From c614b99ae1934390b511414a2fb46e38ee740607 Mon Sep 17 00:00:00 2001 From: Liam Appelbe Date: Fri, 22 Mar 2019 16:14:16 +0000 Subject: [PATCH] [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 Reviewed-by: Siva Annamalai --- runtime/bin/BUILD.gn | 5 +- runtime/bin/dfe.cc | 151 +++++++++++++++++++++++++++++-------------- runtime/bin/dfe.h | 9 ++- runtime/bin/main.cc | 2 +- 4 files changed, 116 insertions(+), 51 deletions(-) diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index a3ad29e5ac7..55e9d2e3966 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn @@ -136,7 +136,7 @@ template("build_gen_snapshot") { 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 @@ template("build_gen_snapshot") { "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 @@ executable("run_vm_tests") { ":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 @@ executable("run_vm_tests") { 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 517df575258..0ef24e706af 100644 --- a/runtime/bin/dfe.cc +++ b/runtime/bin/dfe.cc @@ -4,6 +4,9 @@ #include "bin/dfe.h" +#include + +#include "bin/abi_version.h" #include "bin/dartutils.h" #include "bin/directory.h" #include "bin/error_exit.h" @@ -31,18 +34,6 @@ intptr_t kPlatformStrongDillSize = 0; 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 @@ DFE::DFE() 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 @@ DFE::~DFE() { } 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( + 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(&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(&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 @@ Dart_KernelCompilationResult DFE::CompileScript(const char* script_uri, 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 af5206586ab..932936f9c2e 100644 --- a/runtime/bin/dfe.h +++ b/runtime/bin/dfe.h @@ -21,6 +21,7 @@ class DFE { // 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 @@ class DFE { 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 @@ class DFE { 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 f572e20250d..b86cd437ca3 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -1125,7 +1125,7 @@ void main(int argc, char** argv) { // 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,