Index: runtime/bin/main.cc |
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc |
index f910f34d001a9baabd96bb6900d7f3c1ceab37c4..663379c88052c9add8707647f7bda10facb57867 100644 |
--- a/runtime/bin/main.cc |
+++ b/runtime/bin/main.cc |
@@ -811,6 +811,173 @@ static Dart_Handle EnvironmentCallback(Dart_Handle name) { |
static void SnapshotOnExitHook(int64_t exit_code); |
+static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size; |
+static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc; |
+static const int64_t kAppSnapshotPageSize = 4 * KB; |
+ |
+ |
+static bool ReadAppSnapshotBlobs(const char* script_name, |
+ const uint8_t** vm_data_buffer, |
+ const uint8_t** vm_instructions_buffer, |
+ const uint8_t** isolate_data_buffer, |
+ const uint8_t** isolate_instructions_buffer) { |
+ File* file = File::Open(script_name, File::kRead); |
+ if (file == NULL) { |
+ return false; |
+ } |
+ if (file->Length() < kAppSnapshotHeaderSize) { |
+ file->Release(); |
+ return false; |
+ } |
+ int64_t header[5]; |
+ ASSERT(sizeof(header) == kAppSnapshotHeaderSize); |
+ if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) { |
+ file->Release(); |
+ return false; |
+ } |
+ if (header[0] != kAppSnapshotMagicNumber) { |
+ file->Release(); |
+ return false; |
+ } |
+ |
+ int64_t vm_data_size = header[1]; |
+ int64_t vm_data_position = |
+ Utils::RoundUp(file->Position(), kAppSnapshotPageSize); |
+ int64_t vm_instructions_size = header[2]; |
+ int64_t vm_instructions_position = vm_data_position + vm_data_size; |
+ if (vm_instructions_size != 0) { |
+ vm_instructions_position = |
+ Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize); |
+ } |
+ int64_t isolate_data_size = header[3]; |
+ int64_t isolate_data_position = Utils::RoundUp( |
+ vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize); |
+ int64_t isolate_instructions_size = header[4]; |
+ int64_t isolate_instructions_position = |
+ isolate_data_position + isolate_data_size; |
+ if (isolate_instructions_size != 0) { |
+ isolate_instructions_position = |
+ Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize); |
+ } |
+ |
+ if (vm_data_size != 0) { |
+ *vm_data_buffer = reinterpret_cast<const uint8_t*>( |
+ file->Map(File::kReadOnly, vm_data_position, vm_data_size)); |
+ if (vm_data_buffer == NULL) { |
+ Log::PrintErr("Failed to memory map snapshot\n"); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ } |
+ |
+ if (vm_instructions_size != 0) { |
+ *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map( |
+ File::kReadExecute, vm_instructions_position, vm_instructions_size)); |
+ if (*vm_instructions_buffer == NULL) { |
+ Log::PrintErr("Failed to memory map snapshot\n"); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ } |
+ |
+ *isolate_data_buffer = reinterpret_cast<const uint8_t*>( |
+ file->Map(File::kReadOnly, isolate_data_position, isolate_data_size)); |
+ if (isolate_data_buffer == NULL) { |
+ Log::PrintErr("Failed to memory map snapshot\n"); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ |
+ if (isolate_instructions_size == 0) { |
+ *isolate_instructions_buffer = NULL; |
+ } else { |
+ *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>( |
+ file->Map(File::kReadExecute, isolate_instructions_position, |
+ isolate_instructions_size)); |
+ if (*isolate_instructions_buffer == NULL) { |
+ Log::PrintErr("Failed to memory map snapshot\n"); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ } |
+ |
+ file->Release(); |
+ return true; |
+} |
+ |
+ |
+#if defined(DART_PRECOMPILED_RUNTIME) |
+static bool ReadAppSnapshotDynamicLibrary( |
+ const char* script_name, |
+ const uint8_t** vm_data_buffer, |
+ const uint8_t** vm_instructions_buffer, |
+ const uint8_t** isolate_data_buffer, |
+ const uint8_t** isolate_instructions_buffer) { |
+ void* library = Extensions::LoadExtensionLibrary(script_name); |
+ if (library == NULL) { |
+ return false; |
+ } |
+ |
+ *vm_data_buffer = reinterpret_cast<const uint8_t*>( |
+ Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName)); |
+ if (*vm_data_buffer == NULL) { |
+ Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ |
+ *vm_instructions_buffer = reinterpret_cast<const uint8_t*>( |
+ Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName)); |
+ if (*vm_instructions_buffer == NULL) { |
+ Log::PrintErr("Failed to resolve symbol '%s'\n", |
+ kVmSnapshotInstructionsSymbolName); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ |
+ *isolate_data_buffer = reinterpret_cast<const uint8_t*>( |
+ Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName)); |
+ if (*isolate_data_buffer == NULL) { |
+ Log::PrintErr("Failed to resolve symbol '%s'\n", |
+ kIsolateSnapshotDataSymbolName); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ |
+ *isolate_instructions_buffer = |
+ reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol( |
+ library, kIsolateSnapshotInstructionsSymbolName)); |
+ if (*isolate_instructions_buffer == NULL) { |
+ Log::PrintErr("Failed to resolve symbol '%s'\n", |
+ kIsolateSnapshotInstructionsSymbolName); |
+ Platform::Exit(kErrorExitCode); |
+ } |
+ |
+ return true; |
+} |
+#endif // defined(DART_PRECOMPILED_RUNTIME) |
+ |
+ |
+static bool ReadAppSnapshot(const char* script_name, |
+ const uint8_t** vm_data_buffer, |
+ const uint8_t** vm_instructions_buffer, |
+ const uint8_t** isolate_data_buffer, |
+ const uint8_t** isolate_instructions_buffer) { |
+ if (File::GetType(script_name, true) != File::kIsFile) { |
+ // If 'script_name' refers to a pipe, don't read to check for an app |
+ // snapshot since we cannot rewind if it isn't (and couldn't mmap it in |
+ // anyway if it was). |
+ return false; |
+ } |
+ if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer, |
+ isolate_data_buffer, isolate_instructions_buffer)) { |
+ return true; |
+ } |
+#if defined(DART_PRECOMPILED_RUNTIME) |
+ // For testing AOT with the standalone embedder, we also support loading |
+ // from a dynamic library to simulate what happens on iOS. |
+ return ReadAppSnapshotDynamicLibrary( |
+ script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer, |
+ isolate_instructions_buffer); |
+#else |
+ return false; |
+#endif // defined(DART_PRECOMPILED_RUNTIME) |
+} |
+ |
+ |
// Returns newly created Isolate on success, NULL on failure. |
static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
const char* script_uri, |
@@ -829,10 +996,10 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
if (!use_dart_frontend) { |
*error = strdup("Kernel isolate not supported."); |
return NULL; |
- } else { |
- if (packages_config == NULL) { |
- packages_config = commandline_packages_file; |
- } |
+ } |
+ script_uri = frontend_filename; |
+ if (packages_config == NULL) { |
+ packages_config = commandline_packages_file; |
} |
} |
@@ -855,6 +1022,19 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
isolate_run_app_snapshot = true; |
isolate_snapshot_data = app_isolate_snapshot_data; |
isolate_snapshot_instructions = app_isolate_snapshot_instructions; |
+ } else if (!is_main_isolate) { |
+ const uint8_t* file_vm_snapshot_data = NULL; |
+ const uint8_t* file_vm_snapshot_instructions = NULL; |
+ const uint8_t* file_isolate_snapshot_data = NULL; |
+ const uint8_t* file_isolate_snapshot_instructions = NULL; |
+ if (ReadAppSnapshot( |
+ script_uri, &file_vm_snapshot_data, &file_vm_snapshot_instructions, |
+ &file_isolate_snapshot_data, &file_isolate_snapshot_instructions)) { |
+ // TODO(rmacnak): We are leaking the snapshot when the isolate shuts down. |
+ isolate_run_app_snapshot = true; |
+ isolate_snapshot_data = file_isolate_snapshot_data; |
+ isolate_snapshot_instructions = file_isolate_snapshot_instructions; |
+ } |
} |
#endif |
@@ -958,10 +1138,6 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
result = DartUtils::SetupServiceLoadPort(); |
CHECK_RESULT(result); |
- if (Dart_IsKernelIsolate(isolate)) { |
- script_uri = frontend_filename; |
- } |
- |
// Setup package root if specified. |
result = DartUtils::SetupPackageRoot(package_root, packages_config); |
CHECK_RESULT(result); |
@@ -1313,173 +1489,6 @@ static void WriteSnapshotFile(const char* filename, |
} |
-static const int64_t kAppSnapshotHeaderSize = 5 * sizeof(int64_t); // NOLINT |
-static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc; |
-static const int64_t kAppSnapshotPageSize = 4 * KB; |
- |
- |
-static bool ReadAppSnapshotBlobs(const char* script_name, |
- const uint8_t** vm_data_buffer, |
- const uint8_t** vm_instructions_buffer, |
- const uint8_t** isolate_data_buffer, |
- const uint8_t** isolate_instructions_buffer) { |
- File* file = File::Open(script_name, File::kRead); |
- if (file == NULL) { |
- return false; |
- } |
- if (file->Length() < kAppSnapshotHeaderSize) { |
- file->Release(); |
- return false; |
- } |
- int64_t header[5]; |
- ASSERT(sizeof(header) == kAppSnapshotHeaderSize); |
- if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) { |
- file->Release(); |
- return false; |
- } |
- if (header[0] != kAppSnapshotMagicNumber) { |
- file->Release(); |
- return false; |
- } |
- |
- int64_t vm_data_size = header[1]; |
- int64_t vm_data_position = |
- Utils::RoundUp(file->Position(), kAppSnapshotPageSize); |
- int64_t vm_instructions_size = header[2]; |
- int64_t vm_instructions_position = vm_data_position + vm_data_size; |
- if (vm_instructions_size != 0) { |
- vm_instructions_position = |
- Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize); |
- } |
- int64_t isolate_data_size = header[3]; |
- int64_t isolate_data_position = Utils::RoundUp( |
- vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize); |
- int64_t isolate_instructions_size = header[4]; |
- int64_t isolate_instructions_position = |
- isolate_data_position + isolate_data_size; |
- if (isolate_instructions_size != 0) { |
- isolate_instructions_position = |
- Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize); |
- } |
- |
- if (vm_data_size != 0) { |
- *vm_data_buffer = reinterpret_cast<const uint8_t*>( |
- file->Map(File::kReadOnly, vm_data_position, vm_data_size)); |
- if (vm_data_buffer == NULL) { |
- Log::PrintErr("Failed to memory map snapshot\n"); |
- Platform::Exit(kErrorExitCode); |
- } |
- } |
- |
- if (vm_instructions_size != 0) { |
- *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map( |
- File::kReadExecute, vm_instructions_position, vm_instructions_size)); |
- if (*vm_instructions_buffer == NULL) { |
- Log::PrintErr("Failed to memory map snapshot\n"); |
- Platform::Exit(kErrorExitCode); |
- } |
- } |
- |
- *isolate_data_buffer = reinterpret_cast<const uint8_t*>( |
- file->Map(File::kReadOnly, isolate_data_position, isolate_data_size)); |
- if (isolate_data_buffer == NULL) { |
- Log::PrintErr("Failed to memory map snapshot\n"); |
- Platform::Exit(kErrorExitCode); |
- } |
- |
- if (isolate_instructions_size == 0) { |
- *isolate_instructions_buffer = NULL; |
- } else { |
- *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>( |
- file->Map(File::kReadExecute, isolate_instructions_position, |
- isolate_instructions_size)); |
- if (*isolate_instructions_buffer == NULL) { |
- Log::PrintErr("Failed to memory map snapshot\n"); |
- Platform::Exit(kErrorExitCode); |
- } |
- } |
- |
- file->Release(); |
- return true; |
-} |
- |
- |
-#if defined(DART_PRECOMPILED_RUNTIME) |
-static bool ReadAppSnapshotDynamicLibrary( |
- const char* script_name, |
- const uint8_t** vm_data_buffer, |
- const uint8_t** vm_instructions_buffer, |
- const uint8_t** isolate_data_buffer, |
- const uint8_t** isolate_instructions_buffer) { |
- void* library = Extensions::LoadExtensionLibrary(script_name); |
- if (library == NULL) { |
- return false; |
- } |
- |
- *vm_data_buffer = reinterpret_cast<const uint8_t*>( |
- Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName)); |
- if (*vm_data_buffer == NULL) { |
- Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName); |
- Platform::Exit(kErrorExitCode); |
- } |
- |
- *vm_instructions_buffer = reinterpret_cast<const uint8_t*>( |
- Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName)); |
- if (*vm_instructions_buffer == NULL) { |
- Log::PrintErr("Failed to resolve symbol '%s'\n", |
- kVmSnapshotInstructionsSymbolName); |
- Platform::Exit(kErrorExitCode); |
- } |
- |
- *isolate_data_buffer = reinterpret_cast<const uint8_t*>( |
- Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName)); |
- if (*isolate_data_buffer == NULL) { |
- Log::PrintErr("Failed to resolve symbol '%s'\n", |
- kIsolateSnapshotDataSymbolName); |
- Platform::Exit(kErrorExitCode); |
- } |
- |
- *isolate_instructions_buffer = |
- reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol( |
- library, kIsolateSnapshotInstructionsSymbolName)); |
- if (*isolate_instructions_buffer == NULL) { |
- Log::PrintErr("Failed to resolve symbol '%s'\n", |
- kIsolateSnapshotInstructionsSymbolName); |
- Platform::Exit(kErrorExitCode); |
- } |
- |
- return true; |
-} |
-#endif // defined(DART_PRECOMPILED_RUNTIME) |
- |
- |
-static bool ReadAppSnapshot(const char* script_name, |
- const uint8_t** vm_data_buffer, |
- const uint8_t** vm_instructions_buffer, |
- const uint8_t** isolate_data_buffer, |
- const uint8_t** isolate_instructions_buffer) { |
- if (File::GetType(script_name, true) != File::kIsFile) { |
- // If 'script_name' refers to a pipe, don't read to check for an app |
- // snapshot since we cannot rewind if it isn't (and couldn't mmap it in |
- // anyway if it was). |
- return false; |
- } |
- if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer, |
- isolate_data_buffer, isolate_instructions_buffer)) { |
- return true; |
- } |
-#if defined(DART_PRECOMPILED_RUNTIME) |
- // For testing AOT with the standalone embedder, we also support loading |
- // from a dynamic library to simulate what happens on iOS. |
- return ReadAppSnapshotDynamicLibrary( |
- script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer, |
- isolate_instructions_buffer); |
-#else |
- return false; |
-#endif // defined(DART_PRECOMPILED_RUNTIME) |
-} |
- |
- |
static bool WriteInt64(File* file, int64_t size) { |
return file->WriteFully(&size, sizeof(size)); |
} |