[vm] Load kernel service from ABI versioned dill file
Bug: https://github.com/dart-lang/sdk/issues/36047
Change-Id: I7122e8f0c8841be462e0fa0b28a75ef693d85d20
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97260
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index a3ad29e..55e9d2e 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -136,7 +136,7 @@
if (is_fuchsia) {
configs -= [ "//build/config:symbol_visibility_hidden" ]
}
- deps = extra_deps
+ deps = [ ":generate_abi_version_cc_file" ] + extra_deps
sources = [
"address_sanitizer.cc",
@@ -152,6 +152,7 @@
"snapshot_utils.h",
# Very limited native resolver provided.
+ "$target_gen_dir/abi_version.cc",
"builtin_common.cc",
"builtin_gen_snapshot.cc",
"dfe.cc",
@@ -933,6 +934,7 @@
":dart_kernel_platform_cc",
":dart_snapshot_cc",
":gen_kernel_bytecode_dill",
+ ":generate_abi_version_cc_file",
":generate_snapshot_test_dat_file",
":libdart_builtin",
":standalone_dart_io",
@@ -961,6 +963,7 @@
heap_tests = rebase_path(heap_sources_tests, ".", "../vm/heap")
sources = [
+ "$target_gen_dir/abi_version.cc",
"builtin.cc",
"dfe.cc",
"dfe.h",
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 517df57..0ef24e7 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -4,6 +4,9 @@
#include "bin/dfe.h"
+#include <memory>
+
+#include "bin/abi_version.h"
#include "bin/dartutils.h"
#include "bin/directory.h"
#include "bin/error_exit.h"
@@ -31,18 +34,6 @@
namespace dart {
namespace bin {
-#if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER)
-const uint8_t* kernel_service_dill = NULL;
-const intptr_t kernel_service_dill_size = 0;
-const uint8_t* platform_strong_dill = NULL;
-const intptr_t platform_strong_dill_size = 0;
-#else
-const uint8_t* kernel_service_dill = kKernelServiceDill;
-const intptr_t kernel_service_dill_size = kKernelServiceDillSize;
-const uint8_t* platform_strong_dill = kPlatformStrongDill;
-const intptr_t platform_strong_dill_size = kPlatformStrongDillSize;
-#endif
-
#if !defined(DART_PRECOMPILED_RUNTIME)
DFE dfe;
#endif
@@ -76,7 +67,19 @@
use_incremental_compiler_(false),
frontend_filename_(NULL),
application_kernel_buffer_(NULL),
- application_kernel_buffer_size_(0) {}
+ application_kernel_buffer_size_(0) {
+#if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER)
+ kernel_service_dill_ = NULL;
+ kernel_service_dill_size_ = 0;
+ platform_strong_dill_ = NULL;
+ platform_strong_dill_size_ = 0;
+#else
+ kernel_service_dill_ = kKernelServiceDill;
+ kernel_service_dill_size_ = kKernelServiceDillSize;
+ platform_strong_dill_ = kPlatformStrongDill;
+ platform_strong_dill_size_ = kPlatformStrongDillSize;
+#endif
+}
DFE::~DFE() {
if (frontend_filename_ != NULL) {
@@ -90,56 +93,108 @@
}
void DFE::Init() {
- if (platform_strong_dill == NULL) {
+ Init(AbiVersion::GetCurrent());
+}
+
+void DFE::Init(int target_abi_version) {
+ if (platform_strong_dill_ == NULL) {
return;
}
- Dart_SetDartLibrarySourcesKernel(platform_strong_dill,
- platform_strong_dill_size);
-
- if (frontend_filename_ == NULL) {
- // Look for the frontend snapshot next to the executable.
- char* dir_prefix = GetDirectoryPrefixFromExeName();
- // |dir_prefix| includes the last path seperator.
- frontend_filename_ =
- OS::SCreate(NULL, "%s%s", dir_prefix, kKernelServiceSnapshot);
-
- if (!File::Exists(NULL, frontend_filename_)) {
- // If the frontend snapshot is not found next to the executable,
- // then look for it in the "snapshots" directory.
- free(frontend_filename_);
- // |dir_prefix| includes the last path seperator.
- frontend_filename_ =
- OS::SCreate(NULL, "%s%s%s%s", dir_prefix, kSnapshotsDirectory,
- File::PathSeparator(), kKernelServiceSnapshot);
- }
-
- free(dir_prefix);
- if (!File::Exists(NULL, frontend_filename_)) {
- free(frontend_filename_);
- frontend_filename_ = NULL;
- }
+ if (!InitKernelServiceAndPlatformDills(target_abi_version)) {
+ return;
}
+
+ Dart_SetDartLibrarySourcesKernel(platform_strong_dill_,
+ platform_strong_dill_size_);
}
-bool DFE::KernelServiceDillAvailable() {
- return kernel_service_dill != NULL;
+bool DFE::InitKernelServiceAndPlatformDills(int target_abi_version) {
+ const char kAbiVersionsDir[] = "dart-sdk/lib/_internal/abiversions";
+ const char kKernelServiceDillFile[] = "kernel_service.dill";
+ const char kPlatformStrongDillFile[] = "vm_platform_strong.dill";
+
+ if (frontend_filename_ != NULL) {
+ return true;
+ }
+
+ // |dir_prefix| includes the last path seperator.
+ auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
+ GetDirectoryPrefixFromExeName(), free);
+
+ if (target_abi_version != AbiVersion::GetCurrent()) {
+ kernel_service_dill_ = NULL;
+ kernel_service_dill_size_ = 0;
+ platform_strong_dill_ = NULL;
+ platform_strong_dill_size_ = 0;
+
+ // Look in the old abi version directory.
+ char* script_uri =
+ OS::SCreate(NULL, "%s%s/%d/%s", dir_prefix.get(), kAbiVersionsDir,
+ target_abi_version, kPlatformStrongDillFile);
+ if (!TryReadKernelFile(script_uri,
+ const_cast<uint8_t**>(&platform_strong_dill_),
+ &platform_strong_dill_size_)) {
+ Log::PrintErr("Can't find old ABI dill file: %s\n", script_uri);
+ free(script_uri);
+ return false;
+ }
+ free(script_uri);
+ script_uri =
+ OS::SCreate(NULL, "%s%s/%d/%s", dir_prefix.get(), kAbiVersionsDir,
+ target_abi_version, kKernelServiceDillFile);
+ if (!TryReadKernelFile(script_uri,
+ const_cast<uint8_t**>(&kernel_service_dill_),
+ &kernel_service_dill_size_)) {
+ Log::PrintErr("Can't find old ABI dill file: %s\n", script_uri);
+ free(script_uri);
+ return false;
+ } else {
+ frontend_filename_ = script_uri;
+ return true;
+ }
+ }
+
+ // Look for the frontend snapshot next to the executable.
+ frontend_filename_ =
+ OS::SCreate(NULL, "%s%s", dir_prefix.get(), kKernelServiceSnapshot);
+ if (File::Exists(NULL, frontend_filename_)) {
+ return true;
+ }
+ free(frontend_filename_);
+ frontend_filename_ = NULL;
+
+ // If the frontend snapshot is not found next to the executable, then look for
+ // it in the "snapshots" directory.
+ frontend_filename_ =
+ OS::SCreate(NULL, "%s%s%s%s", dir_prefix.get(), kSnapshotsDirectory,
+ File::PathSeparator(), kKernelServiceSnapshot);
+ if (File::Exists(NULL, frontend_filename_)) {
+ return true;
+ }
+ free(frontend_filename_);
+ frontend_filename_ = NULL;
+ return true;
+}
+
+bool DFE::KernelServiceDillAvailable() const {
+ return kernel_service_dill_ != NULL;
}
void DFE::LoadKernelService(const uint8_t** kernel_service_buffer,
intptr_t* kernel_service_buffer_size) {
- *kernel_service_buffer = kernel_service_dill;
- *kernel_service_buffer_size = kernel_service_dill_size;
+ *kernel_service_buffer = kernel_service_dill_;
+ *kernel_service_buffer_size = kernel_service_dill_size_;
}
void DFE::LoadPlatform(const uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size) {
- *kernel_buffer = platform_strong_dill;
- *kernel_buffer_size = platform_strong_dill_size;
+ *kernel_buffer = platform_strong_dill_;
+ *kernel_buffer_size = platform_strong_dill_size_;
}
bool DFE::CanUseDartFrontend() const {
- return (platform_strong_dill != NULL) &&
+ return (platform_strong_dill_ != NULL) &&
(KernelServiceDillAvailable() || (frontend_filename() != NULL));
}
@@ -191,8 +246,8 @@
const char* sanitized_uri = script_uri;
#endif
- return Dart_CompileToKernel(sanitized_uri, platform_strong_dill,
- platform_strong_dill_size, incremental,
+ return Dart_CompileToKernel(sanitized_uri, platform_strong_dill_,
+ platform_strong_dill_size_, incremental,
package_config);
}
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index af520658..932936f 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -21,6 +21,7 @@
// Call Init before Dart_Initialize to prevent races between the
// different isolates.
void Init();
+ void Init(int target_abi_version);
char* frontend_filename() const { return frontend_filename_; }
@@ -78,7 +79,7 @@
uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size) const;
- static bool KernelServiceDillAvailable();
+ bool KernelServiceDillAvailable() const;
// Tries to read [script_uri] as a Kernel IR file.
// Returns `true` if successful and sets [kernel_file] and [kernel_length]
@@ -104,11 +105,17 @@
bool use_dfe_;
bool use_incremental_compiler_;
char* frontend_filename_;
+ const uint8_t* kernel_service_dill_;
+ intptr_t kernel_service_dill_size_;
+ const uint8_t* platform_strong_dill_;
+ intptr_t platform_strong_dill_size_;
// Kernel binary specified on the cmd line.
uint8_t* application_kernel_buffer_;
intptr_t application_kernel_buffer_size_;
+ bool InitKernelServiceAndPlatformDills(int target_abi_version);
+
DISALLOW_COPY_AND_ASSIGN(DFE);
};
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index f572e20..b86cd43 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1125,7 +1125,7 @@
// Note: must read platform only *after* VM flags are parsed because
// they might affect how the platform is loaded.
#if !defined(DART_PRECOMPILED_RUNTIME)
- dfe.Init();
+ dfe.Init(Options::target_abi_version());
uint8_t* application_kernel_buffer = NULL;
intptr_t application_kernel_buffer_size = 0;
dfe.ReadScript(script_name, &application_kernel_buffer,