Chromium Code Reviews| Index: runtime/bin/main.cc |
| diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc |
| index b5f958d30c0ce749125811e4f223fbb4e77f0505..c31c2748f897054ca7084b671320ac390c95b7b5 100644 |
| --- a/runtime/bin/main.cc |
| +++ b/runtime/bin/main.cc |
| @@ -809,6 +809,173 @@ static Dart_Handle EnvironmentCallback(Dart_Handle name) { |
| static void SnapshotOnExitHook(int64_t exit_code); |
| +static const int64_t kAppSnapshotHeaderSize = 5 * sizeof(int64_t); // NOLINT |
|
zra
2017/01/26 20:55:00
is sizeof(int64_t) not already a constant in platf
rmacnak
2017/01/26 23:48:45
Didn't know about these. Added and used kInt64Size
|
| +static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc; |
| +static const int64_t kAppSnapshotPageSize = 4 * KB; |
| + |
| + |
| +static bool ReadAppSnapshotBlobs(const char* script_name, |
|
zra
2017/01/26 20:55:00
Should these snapshot reading functions be pulled
rmacnak
2017/01/26 23:48:45
Good point, I'll factor this out in a future CL.
|
| + 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 true on success, false on failure. |
| static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
| const char* script_uri, |
| @@ -823,10 +990,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; |
| } |
| } |
| @@ -849,6 +1016,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. |
|
siva
2017/01/26 17:07:08
When you say leaked do you mean it is not unmapped
rmacnak
2017/01/26 18:07:13
Right, it is not unmapped. If a second spawnURI is
|
| + isolate_run_app_snapshot = true; |
| + isolate_snapshot_data = file_isolate_snapshot_data; |
| + isolate_snapshot_instructions = file_isolate_snapshot_instructions; |
| + } |
| } |
| #endif |
| @@ -929,10 +1109,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); |
| @@ -1288,173 +1464,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)); |
| } |