| Index: runtime/bin/main.cc
|
| diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
|
| index 863609b99ddd8e8f2f4eb3197bdb3bfd2202410c..4fb75a6b6a781b292fe4bad118d7ae7731ba12e3 100644
|
| --- a/runtime/bin/main.cc
|
| +++ b/runtime/bin/main.cc
|
| @@ -14,6 +14,7 @@
|
| #include "bin/directory.h"
|
| #include "bin/embedded_dart_io.h"
|
| #include "bin/eventhandler.h"
|
| +#include "bin/exit.h"
|
| #include "bin/extensions.h"
|
| #include "bin/file.h"
|
| #include "bin/isolate_data.h"
|
| @@ -21,6 +22,7 @@
|
| #include "bin/log.h"
|
| #include "bin/platform.h"
|
| #include "bin/process.h"
|
| +#include "bin/snapshot.h"
|
| #include "bin/thread.h"
|
| #include "bin/utils.h"
|
| #include "bin/vmservice_impl.h"
|
| @@ -95,12 +97,6 @@ static bool parse_all = false;
|
| static bool use_blobs = false;
|
|
|
|
|
| -extern const char* kVmSnapshotDataSymbolName;
|
| -extern const char* kVmSnapshotInstructionsSymbolName;
|
| -extern const char* kIsolateSnapshotDataSymbolName;
|
| -extern const char* kIsolateSnapshotInstructionsSymbolName;
|
| -
|
| -
|
| // Global flag that is used to indicate that we want to trace resolution of
|
| // URIs and the loading of libraries, parts and scripts.
|
| static bool trace_loading = false;
|
| @@ -125,39 +121,6 @@ static int vm_service_server_port = -1;
|
| // checks are disabled.
|
| static bool vm_service_dev_mode = false;
|
|
|
| -// Exit code indicating an internal Dart Frontend error.
|
| -static const int kDartFrontendErrorExitCode = 252;
|
| -// Exit code indicating an API error.
|
| -static const int kApiErrorExitCode = 253;
|
| -// Exit code indicating a compilation error.
|
| -static const int kCompilationErrorExitCode = 254;
|
| -// Exit code indicating an unhandled error that is not a compilation error.
|
| -static const int kErrorExitCode = 255;
|
| -// Exit code indicating a vm restart request. Never returned to the user.
|
| -static const int kRestartRequestExitCode = 1000;
|
| -
|
| -static void ErrorExit(int exit_code, const char* format, ...) {
|
| - va_list arguments;
|
| - va_start(arguments, format);
|
| - Log::VPrintErr(format, arguments);
|
| - va_end(arguments);
|
| -
|
| - Dart_ExitScope();
|
| - Dart_ShutdownIsolate();
|
| -
|
| - // Terminate process exit-code handler.
|
| - Process::TerminateExitCodeHandler();
|
| -
|
| - char* error = Dart_Cleanup();
|
| - if (error != NULL) {
|
| - Log::PrintErr("VM cleanup failed: %s\n", error);
|
| - free(error);
|
| - }
|
| -
|
| - EventHandler::Stop();
|
| - Platform::Exit(exit_code);
|
| -}
|
| -
|
|
|
| // The environment provided through the command line using -D options.
|
| static dart::HashMap* environment = NULL;
|
| @@ -808,173 +771,17 @@ 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);
|
| +static void SnapshotOnExitHook(int64_t exit_code) {
|
| + if (Dart_CurrentIsolate() != main_isolate) {
|
| + Log::PrintErr(
|
| + "A snapshot was requested, but a secondary isolate "
|
| + "performed a hard exit (%" Pd64 ").\n",
|
| + exit_code);
|
| 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 (exit_code == 0) {
|
| + Snapshot::GenerateAppJIT(snapshot_filename);
|
| }
|
| -#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)
|
| }
|
|
|
|
|
| @@ -1027,7 +834,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
| 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(
|
| + if (Snapshot::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.
|
| @@ -1462,175 +1269,12 @@ static bool FileModifiedCallback(const char* url, int64_t since) {
|
| }
|
|
|
|
|
| -static void WriteSnapshotFile(const char* filename,
|
| - bool write_magic_number,
|
| - const uint8_t* buffer,
|
| - const intptr_t size) {
|
| - char* concat = NULL;
|
| - File* file = File::Open(filename, File::kWriteTruncate);
|
| - if (file == NULL) {
|
| - ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n",
|
| - filename);
|
| - }
|
| -
|
| - if (write_magic_number) {
|
| - // Write the magic number to indicate file is a script snapshot.
|
| - DartUtils::WriteMagicNumber(file);
|
| - }
|
| -
|
| - if (!file->WriteFully(buffer, size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write file %s for writing snapshot\n",
|
| - filename);
|
| - }
|
| - file->Release();
|
| - if (concat != NULL) {
|
| - delete concat;
|
| - }
|
| -}
|
| -
|
| -
|
| -static bool WriteInt64(File* file, int64_t size) {
|
| - return file->WriteFully(&size, sizeof(size));
|
| -}
|
| -
|
| -
|
| -static void WriteAppSnapshot(const char* filename,
|
| - uint8_t* vm_data_buffer,
|
| - intptr_t vm_data_size,
|
| - uint8_t* vm_instructions_buffer,
|
| - intptr_t vm_instructions_size,
|
| - uint8_t* isolate_data_buffer,
|
| - intptr_t isolate_data_size,
|
| - uint8_t* isolate_instructions_buffer,
|
| - intptr_t isolate_instructions_size) {
|
| - File* file = File::Open(filename, File::kWriteTruncate);
|
| - if (file == NULL) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
|
| - }
|
| -
|
| - file->WriteFully(&kAppSnapshotMagicNumber, sizeof(kAppSnapshotMagicNumber));
|
| - WriteInt64(file, vm_data_size);
|
| - WriteInt64(file, vm_instructions_size);
|
| - WriteInt64(file, isolate_data_size);
|
| - WriteInt64(file, isolate_instructions_size);
|
| - ASSERT(file->Position() == kAppSnapshotHeaderSize);
|
| -
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(vm_data_buffer, vm_data_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
|
| - }
|
| -
|
| - if (vm_instructions_size != 0) {
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(vm_instructions_buffer, vm_instructions_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
|
| - filename);
|
| - }
|
| - }
|
| -
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(isolate_data_buffer, isolate_data_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
|
| - }
|
| -
|
| - if (isolate_instructions_size != 0) {
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(isolate_instructions_buffer,
|
| - isolate_instructions_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
|
| - filename);
|
| - }
|
| - }
|
| -
|
| - file->Flush();
|
| - file->Release();
|
| -}
|
| -
|
| -
|
| -static void GenerateScriptSnapshot() {
|
| - // First create a snapshot.
|
| - uint8_t* buffer = NULL;
|
| - intptr_t size = 0;
|
| - Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
|
| - if (Dart_IsError(result)) {
|
| - ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| - }
|
| -
|
| - WriteSnapshotFile(snapshot_filename, true, buffer, size);
|
| -}
|
| -
|
| -
|
| -static void GenerateAppAOTSnapshotAsBlobs() {
|
| - uint8_t* vm_data_buffer = NULL;
|
| - intptr_t vm_data_size = 0;
|
| - uint8_t* vm_instructions_buffer = NULL;
|
| - intptr_t vm_instructions_size = 0;
|
| - uint8_t* isolate_data_buffer = NULL;
|
| - intptr_t isolate_data_size = 0;
|
| - uint8_t* isolate_instructions_buffer = NULL;
|
| - intptr_t isolate_instructions_size = 0;
|
| - Dart_Handle result = Dart_CreateAppAOTSnapshotAsBlobs(
|
| - &vm_data_buffer, &vm_data_size, &vm_instructions_buffer,
|
| - &vm_instructions_size, &isolate_data_buffer, &isolate_data_size,
|
| - &isolate_instructions_buffer, &isolate_instructions_size);
|
| - if (Dart_IsError(result)) {
|
| - ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| - }
|
| - WriteAppSnapshot(snapshot_filename, vm_data_buffer, vm_data_size,
|
| - vm_instructions_buffer, vm_instructions_size,
|
| - isolate_data_buffer, isolate_data_size,
|
| - isolate_instructions_buffer, isolate_instructions_size);
|
| -}
|
| -
|
| -static void GenerateAppAOTSnapshotAsAssembly() {
|
| - uint8_t* assembly_buffer = NULL;
|
| - intptr_t assembly_size = 0;
|
| - Dart_Handle result =
|
| - Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size);
|
| - if (Dart_IsError(result)) {
|
| - ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| - }
|
| - WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size);
|
| -}
|
| -
|
| -
|
| static void GenerateAppAOTSnapshot() {
|
| if (use_blobs) {
|
| - GenerateAppAOTSnapshotAsBlobs();
|
| + Snapshot::GenerateAppAOTAsBlobs(snapshot_filename);
|
| } else {
|
| - GenerateAppAOTSnapshotAsAssembly();
|
| - }
|
| -}
|
| -
|
| -
|
| -static void GenerateAppJITSnapshot() {
|
| -#if defined(TARGET_ARCH_X64)
|
| - uint8_t* isolate_data_buffer = NULL;
|
| - intptr_t isolate_data_size = 0;
|
| - uint8_t* isolate_instructions_buffer = NULL;
|
| - intptr_t isolate_instructions_size = 0;
|
| - Dart_Handle result = Dart_CreateAppJITSnapshotAsBlobs(
|
| - &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer,
|
| - &isolate_instructions_size);
|
| - if (Dart_IsError(result)) {
|
| - ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| - }
|
| - WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_data_buffer,
|
| - isolate_data_size, isolate_instructions_buffer,
|
| - isolate_instructions_size);
|
| -#else
|
| - uint8_t* isolate_buffer = NULL;
|
| - intptr_t isolate_size = 0;
|
| -
|
| - Dart_Handle result =
|
| - Dart_CreateSnapshot(NULL, NULL, &isolate_buffer, &isolate_size);
|
| - if (Dart_IsError(result)) {
|
| - ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| + Snapshot::GenerateAppAOTAsAssembly(snapshot_filename);
|
| }
|
| -
|
| - WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_buffer,
|
| - isolate_size, NULL, 0);
|
| -#endif // defined(TARGET_ARCH_X64)
|
| }
|
|
|
|
|
| @@ -1648,17 +1292,17 @@ static void GenerateAppJITSnapshot() {
|
| }
|
|
|
|
|
| -static void SnapshotOnExitHook(int64_t exit_code) {
|
| - if (Dart_CurrentIsolate() != main_isolate) {
|
| - Log::PrintErr(
|
| - "A snapshot was requested, but a secondary isolate "
|
| - "performed a hard exit (%" Pd64 ").\n",
|
| - exit_code);
|
| - Platform::Exit(kErrorExitCode);
|
| +static void WriteFile(const char* filename,
|
| + const uint8_t* buffer,
|
| + const intptr_t size) {
|
| + File* file = File::Open(filename, File::kWriteTruncate);
|
| + if (file == NULL) {
|
| + ErrorExit(kErrorExitCode, "Unable to open file %s\n", filename);
|
| }
|
| - if (exit_code == 0) {
|
| - GenerateAppJITSnapshot();
|
| + if (!file->WriteFully(buffer, size)) {
|
| + ErrorExit(kErrorExitCode, "Unable to write file %s\n", filename);
|
| }
|
| + file->Release();
|
| }
|
|
|
|
|
| @@ -1701,7 +1345,7 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
|
| Dart_EnterScope();
|
|
|
| if (gen_snapshot_kind == kScript) {
|
| - GenerateScriptSnapshot();
|
| + Snapshot::GenerateScript(snapshot_filename);
|
| } else {
|
| // Lookup the library of the root script.
|
| Dart_Handle root_lib = Dart_RootLibrary();
|
| @@ -1832,7 +1476,7 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
|
| if (gen_snapshot_kind == kAppJIT) {
|
| if (!Dart_IsCompilationError(result) &&
|
| !Dart_IsVMRestartRequest(result)) {
|
| - GenerateAppJITSnapshot();
|
| + Snapshot::GenerateAppJIT(snapshot_filename);
|
| }
|
| }
|
| CHECK_RESULT(result);
|
| @@ -1844,7 +1488,7 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
|
| if (Dart_IsError(result)) {
|
| ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| }
|
| - WriteSnapshotFile(save_feedback_filename, false, buffer, size);
|
| + WriteFile(save_feedback_filename, buffer, size);
|
| }
|
| }
|
| }
|
| @@ -1995,9 +1639,9 @@ void main(int argc, char** argv) {
|
| Platform::Exit(kErrorExitCode);
|
| }
|
|
|
| - if (ReadAppSnapshot(script_name, &vm_snapshot_data, &vm_snapshot_instructions,
|
| - &app_isolate_snapshot_data,
|
| - &app_isolate_snapshot_instructions)) {
|
| + if (Snapshot::ReadAppSnapshot(
|
| + script_name, &vm_snapshot_data, &vm_snapshot_instructions,
|
| + &app_isolate_snapshot_data, &app_isolate_snapshot_instructions)) {
|
| vm_run_app_snapshot = true;
|
| }
|
|
|
|
|