[vm] Adds a benchmark for Dart_LoadLibraryFromKernel

Change-Id: I71c9d6a1cd9d07f554bbeb02c682de2c771ddb3e
Reviewed-on: https://dart-review.googlesource.com/75787
Commit-Queue: Zach Anderson <zra@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index c6fe258..c6bb522 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -1121,6 +1121,43 @@
   ]
 }
 
+prebuilt_dart_action("gen_kernel_bytecode_dill") {
+  if (target_os == "fuchsia") {
+    testonly = true
+  }
+
+  deps = [
+    "../vm:vm_platform",
+  ]
+  platform_dill = "$root_out_dir/vm_platform_strong.dill"
+
+  output = "$root_out_dir/gen_kernel_bytecode.dill"
+  outputs = [
+    output,
+  ]
+
+  script = "../../pkg/vm/bin/gen_kernel.dart"
+
+  depfile = "$target_gen_dir/gen_kernel_bytecode.dill.d"
+  abs_depfile = rebase_path(depfile)
+  rebased_output = rebase_path(output, root_out_dir)
+  vm_args = [
+    "--depfile=$abs_depfile",
+    "--depfile_output_filename=$rebased_output",
+  ]
+
+  args = [
+    "--gen-bytecode",
+    "--no-embed-sources",
+    "--drop-ast",
+    "--platform",
+    rebase_path(platform_dill),
+    "--output",
+    rebase_path(output),
+    rebase_path(script),
+  ]
+}
+
 executable("run_vm_tests") {
   if (target_os == "fuchsia") {
     testonly = true
@@ -1139,6 +1176,7 @@
   deps = [
     ":dart_kernel_platform_cc",
     ":dart_snapshot_cc",
+    ":gen_kernel_bytecode_dill",
     ":generate_snapshot_test_dat_file",
     ":libdart_builtin",
     ":standalone_dart_io",
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 3d5bf6f..5e4dc79 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -8,6 +8,7 @@
 #include "bin/file.h"
 #include "bin/isolate_data.h"
 #include "bin/process.h"
+#include "bin/reference_counting.h"
 
 #include "platform/assert.h"
 #include "platform/globals.h"
@@ -177,6 +178,60 @@
   free(script);
 }
 
+// This file is created by the target //runtime/bin:gen_kernel_bytecode_dill
+// which is depended on by run_vm_tests.
+static char* ComputeGenKernelKernelPath(const char* arg) {
+  char buffer[2048];
+  char* gen_kernel_path = strdup(File::GetCanonicalPath(NULL, arg));
+  EXPECT(gen_kernel_path != NULL);
+  const char* compiler_path = "%s%sgen_kernel_bytecode.dill";
+  const char* path_separator = File::PathSeparator();
+  ASSERT(path_separator != NULL && strlen(path_separator) == 1);
+  char* ptr = strrchr(gen_kernel_path, *path_separator);
+  while (ptr != NULL) {
+    *ptr = '\0';
+    Utils::SNPrint(buffer, ARRAY_SIZE(buffer), compiler_path, gen_kernel_path,
+                   path_separator);
+    if (File::Exists(NULL, buffer)) {
+      break;
+    }
+    ptr = strrchr(gen_kernel_path, *path_separator);
+  }
+  free(gen_kernel_path);
+  if (ptr == NULL) {
+    return NULL;
+  }
+  return strdup(buffer);
+}
+
+BENCHMARK(GenKernelKernelLoadKernel) {
+  char* dill_path = ComputeGenKernelKernelPath(Benchmark::Executable());
+  fprintf(stderr, "dill_path = '%s'\n", dill_path);
+  File* file = File::Open(NULL, dill_path, File::kRead);
+  EXPECT(file != NULL);
+  bin::RefCntReleaseScope<File> rs(file);
+  intptr_t kernel_buffer_size = file->Length();
+  uint8_t* kernel_buffer =
+      reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
+  EXPECT(kernel_buffer != NULL);
+  bool read_fully = file->ReadFully(kernel_buffer, kernel_buffer_size);
+  EXPECT(read_fully);
+
+  Timer timer(true, "GenKernelKernelLoadKernel benchmark");
+  timer.Start();
+
+  Dart_Handle result =
+      Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
+  EXPECT_VALID(result);
+
+  result = Dart_FinalizeLoading(false);
+  EXPECT_VALID(result);
+
+  timer.Stop();
+  int64_t elapsed_time = timer.TotalElapsedTime();
+  benchmark->set_score(elapsed_time);
+}
+
 #endif  // !PRODUCT
 
 //