| Index: runtime/bin/main.cc
|
| diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
|
| index d8fa7e5cecf4286f33a57352627404fe25b2dd14..b5ef0870b9f687c4d8c31bef1b7420cd8393fb85 100644
|
| --- a/runtime/bin/main.cc
|
| +++ b/runtime/bin/main.cc
|
| @@ -97,11 +97,16 @@ static const bool is_noopt = false;
|
| #endif
|
|
|
|
|
| -extern const char* kPrecompiledVMIsolateSymbolName;
|
| -extern const char* kPrecompiledIsolateSymbolName;
|
| +extern const char* kPrecompiledLibraryName;
|
| extern const char* kPrecompiledInstructionsSymbolName;
|
| extern const char* kPrecompiledDataSymbolName;
|
|
|
| +static const char* kVMIsolateSuffix = "snapshot.vmisolate";
|
| +static const char* kIsolateSuffix = "snapshot.isolate";
|
| +static const char* kAssemblySuffix = "snapshot.S";
|
| +static const char* kInstructionsSuffix = "snapshot.instructions";
|
| +static const char* kRODataSuffix = "snapshot.rodata";
|
| +
|
|
|
| // Global flag that is used to indicate that we want to trace resolution of
|
| // URIs and the loading of libraries, parts and scripts.
|
| @@ -373,6 +378,15 @@ static bool ProcessSnapshotKindOption(const char* kind,
|
| }
|
|
|
|
|
| +static bool ProcessRunAppSnapshotOption(
|
| + const char* filename, CommandLineOptions* vm_options) {
|
| + ASSERT(filename != NULL);
|
| + snapshot_filename = filename;
|
| + run_app_snapshot = true;
|
| + return true;
|
| +}
|
| +
|
| +
|
| static bool ProcessEnableVmServiceOption(const char* option_value,
|
| CommandLineOptions* vm_options) {
|
| ASSERT(option_value != NULL);
|
| @@ -551,6 +565,7 @@ static struct {
|
| { "--observe", ProcessObserveOption },
|
| { "--snapshot=", ProcessSnapshotFilenameOption },
|
| { "--snapshot-kind=", ProcessSnapshotKindOption },
|
| + { "--run-app-snapshot=", ProcessRunAppSnapshotOption },
|
| { "--use-blobs", ProcessUseBlobsOption },
|
| { "--trace-loading", ProcessTraceLoadingOption },
|
| { "--hot-reload-test-mode", ProcessHotReloadTestModeOption },
|
| @@ -1192,193 +1207,93 @@ static void WriteSnapshotFile(const char* snapshot_directory,
|
| }
|
|
|
|
|
| -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** vmisolate_buffer,
|
| - const uint8_t** isolate_buffer,
|
| - const uint8_t** instructions_buffer,
|
| - const uint8_t** rodata_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 vmisolate_position =
|
| - Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
|
| - int64_t isolate_position =
|
| - Utils::RoundUp(vmisolate_position + header[1], kAppSnapshotPageSize);
|
| - int64_t rodata_position =
|
| - Utils::RoundUp(isolate_position + header[2], kAppSnapshotPageSize);
|
| - int64_t instructions_position =
|
| - Utils::RoundUp(rodata_position + header[3], kAppSnapshotPageSize);
|
| -
|
| - void* read_only_buffer =
|
| - file->Map(File::kReadOnly, vmisolate_position,
|
| - instructions_position - vmisolate_position);
|
| - if (read_only_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
|
| - }
|
| -
|
| - *vmisolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
|
| - + (vmisolate_position - vmisolate_position);
|
| - *isolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
|
| - + (isolate_position - vmisolate_position);
|
| - if (header[3] == 0) {
|
| - *rodata_buffer = NULL;
|
| +static void ReadSnapshotFile(const char* snapshot_directory,
|
| + const char* filename,
|
| + const uint8_t** buffer) {
|
| + char* concat = NULL;
|
| + const char* qualified_filename;
|
| + if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
|
| + intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, filename);
|
| + concat = new char[len + 1];
|
| + snprintf(concat, len + 1, "%s/%s", snapshot_directory, filename);
|
| + qualified_filename = concat;
|
| } else {
|
| - *rodata_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
|
| - + (rodata_position - vmisolate_position);
|
| + qualified_filename = filename;
|
| }
|
|
|
| - if (header[4] == 0) {
|
| - *instructions_buffer = NULL;
|
| - } else {
|
| - *instructions_buffer = reinterpret_cast<const uint8_t*>(
|
| - file->Map(File::kReadExecute, instructions_position, header[4]));
|
| - if (*instructions_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to memory map snapshot2\n");
|
| - }
|
| + void* file = DartUtils::OpenFile(qualified_filename, false);
|
| + if (file == NULL) {
|
| + fprintf(stderr,
|
| + "Error: Unable to open file %s for reading snapshot\n",
|
| + qualified_filename);
|
| + fflush(stderr);
|
| + Platform::Exit(kErrorExitCode);
|
| }
|
| -
|
| - file->Release();
|
| - return true;
|
| -}
|
| -
|
| -
|
| -static bool ReadAppSnapshotDynamicLibrary(const char* script_name,
|
| - const uint8_t** vmisolate_buffer,
|
| - const uint8_t** isolate_buffer,
|
| - const uint8_t** instructions_buffer,
|
| - const uint8_t** rodata_buffer) {
|
| - void* library = Extensions::LoadExtensionLibrary(script_name);
|
| - if (library == NULL) {
|
| - return false;
|
| + intptr_t len = -1;
|
| + DartUtils::ReadFile(buffer, &len, file);
|
| + if ((*buffer == NULL) || (len == -1)) {
|
| + fprintf(stderr,
|
| + "Error: Unable to read snapshot file %s\n", qualified_filename);
|
| + fflush(stderr);
|
| + Platform::Exit(kErrorExitCode);
|
| }
|
| -
|
| - *vmisolate_buffer = reinterpret_cast<const uint8_t*>(
|
| - Extensions::ResolveSymbol(library, kPrecompiledVMIsolateSymbolName));
|
| - if (*vmisolate_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
|
| - kPrecompiledVMIsolateSymbolName);
|
| + DartUtils::CloseFile(file);
|
| + if (concat != NULL) {
|
| + delete[] concat;
|
| }
|
| +}
|
|
|
| - *isolate_buffer = reinterpret_cast<const uint8_t*>(
|
| - Extensions::ResolveSymbol(library, kPrecompiledIsolateSymbolName));
|
| - if (*isolate_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
|
| - kPrecompiledIsolateSymbolName);
|
| - }
|
|
|
| - *instructions_buffer = reinterpret_cast<const uint8_t*>(
|
| - Extensions::ResolveSymbol(library, kPrecompiledInstructionsSymbolName));
|
| - if (*instructions_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
|
| - kPrecompiledInstructionsSymbolName);
|
| +static void ReadExecutableSnapshotFile(const char* snapshot_directory,
|
| + const char* filename,
|
| + const uint8_t** buffer) {
|
| + char* concat = NULL;
|
| + const char* qualified_filename;
|
| + if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
|
| + intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, filename);
|
| + concat = new char[len + 1];
|
| + snprintf(concat, len + 1, "%s/%s", snapshot_directory, filename);
|
| + qualified_filename = concat;
|
| + } else {
|
| + qualified_filename = filename;
|
| }
|
|
|
| - *rodata_buffer = reinterpret_cast<const uint8_t*>(
|
| - Extensions::ResolveSymbol(library, kPrecompiledDataSymbolName));
|
| - if (*rodata_buffer == NULL) {
|
| - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
|
| - kPrecompiledDataSymbolName);
|
| + intptr_t len = -1;
|
| + *buffer = reinterpret_cast<uint8_t*>(
|
| + DartUtils::MapExecutable(qualified_filename, &len));
|
| + if ((*buffer == NULL) || (len == -1)) {
|
| + fprintf(stderr,
|
| + "Error: Unable to read snapshot file %s\n", qualified_filename);
|
| + fflush(stderr);
|
| + Platform::Exit(kErrorExitCode);
|
| }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -
|
| -static bool ReadAppSnapshot(const char* script_name,
|
| - const uint8_t** vmisolate_buffer,
|
| - const uint8_t** isolate_buffer,
|
| - const uint8_t** instructions_buffer,
|
| - const uint8_t** rodata_buffer) {
|
| - if (ReadAppSnapshotBlobs(script_name,
|
| - vmisolate_buffer,
|
| - isolate_buffer,
|
| - instructions_buffer,
|
| - rodata_buffer)) {
|
| - return true;
|
| + if (concat != NULL) {
|
| + delete[] concat;
|
| }
|
| - return ReadAppSnapshotDynamicLibrary(script_name,
|
| - vmisolate_buffer,
|
| - isolate_buffer,
|
| - instructions_buffer,
|
| - rodata_buffer);
|
| }
|
|
|
|
|
| -static bool WriteInt64(File* file, int64_t size) {
|
| - return file->WriteFully(&size, sizeof(size));
|
| -}
|
| -
|
| -
|
| -static void WriteAppSnapshot(const char* filename,
|
| - uint8_t* vmisolate_buffer,
|
| - intptr_t vmisolate_size,
|
| - uint8_t* isolate_buffer,
|
| - intptr_t isolate_size,
|
| - uint8_t* instructions_buffer,
|
| - intptr_t instructions_size,
|
| - uint8_t* rodata_buffer,
|
| - intptr_t rodata_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, vmisolate_size);
|
| - WriteInt64(file, isolate_size);
|
| - WriteInt64(file, rodata_size);
|
| - WriteInt64(file, instructions_size);
|
| - ASSERT(file->Position() == kAppSnapshotHeaderSize);
|
| -
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(vmisolate_buffer, vmisolate_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
|
| - }
|
| -
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(isolate_buffer, isolate_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
|
| +static void* LoadLibrarySymbol(const char* snapshot_directory,
|
| + const char* libname,
|
| + const char* symname) {
|
| + char* concat = NULL;
|
| + const char* qualified_libname;
|
| + if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
|
| + intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, libname);
|
| + concat = new char[len + 1];
|
| + snprintf(concat, len + 1, "%s/%s", snapshot_directory, libname);
|
| + qualified_libname = concat;
|
| + } else {
|
| + qualified_libname = libname;
|
| }
|
| -
|
| - if (rodata_size != 0) {
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(rodata_buffer, rodata_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
|
| - filename);
|
| - }
|
| + void* library = Extensions::LoadExtensionLibrary(qualified_libname);
|
| + if (concat != NULL) {
|
| + delete concat;
|
| }
|
| -
|
| - if (instructions_size != 0) {
|
| - file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
| - if (!file->WriteFully(instructions_buffer, instructions_size)) {
|
| - ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
|
| - filename);
|
| - }
|
| + if (library == NULL) {
|
| + return NULL;
|
| }
|
| -
|
| - file->Flush();
|
| - file->Release();
|
| + return Extensions::ResolveSymbol(library, symname);
|
| }
|
|
|
|
|
| @@ -1419,24 +1334,35 @@ static void GeneratePrecompiledSnapshot() {
|
| &rodata_blob_size);
|
| } else {
|
| result = Dart_CreatePrecompiledSnapshotAssembly(
|
| + &vm_isolate_buffer,
|
| + &vm_isolate_size,
|
| + &isolate_buffer,
|
| + &isolate_size,
|
| &assembly_buffer,
|
| &assembly_size);
|
| }
|
| if (Dart_IsError(result)) {
|
| ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| }
|
| + WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
|
| + false,
|
| + vm_isolate_buffer,
|
| + vm_isolate_size);
|
| + WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
|
| + false,
|
| + isolate_buffer,
|
| + isolate_size);
|
| if (use_blobs) {
|
| - WriteAppSnapshot(snapshot_filename,
|
| - vm_isolate_buffer,
|
| - vm_isolate_size,
|
| - isolate_buffer,
|
| - isolate_size,
|
| - instructions_blob_buffer,
|
| - instructions_blob_size,
|
| - rodata_blob_buffer,
|
| - rodata_blob_size);
|
| + WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
|
| + false,
|
| + instructions_blob_buffer,
|
| + instructions_blob_size);
|
| + WriteSnapshotFile(snapshot_filename, kRODataSuffix,
|
| + false,
|
| + rodata_blob_buffer,
|
| + rodata_blob_size);
|
| } else {
|
| - WriteSnapshotFile(NULL, snapshot_filename,
|
| + WriteSnapshotFile(snapshot_filename, kAssemblySuffix,
|
| false,
|
| assembly_buffer,
|
| assembly_size);
|
| @@ -1445,6 +1371,10 @@ static void GeneratePrecompiledSnapshot() {
|
|
|
|
|
| static void GeneratePrecompiledJITSnapshot() {
|
| + if (!use_blobs) {
|
| + ErrorExit(kErrorExitCode,
|
| + "Generating app JIT snapshots as assembly unimplemented\n");
|
| + }
|
| uint8_t* vm_isolate_buffer = NULL;
|
| intptr_t vm_isolate_size = 0;
|
| uint8_t* isolate_buffer = NULL;
|
| @@ -1465,15 +1395,22 @@ static void GeneratePrecompiledJITSnapshot() {
|
| if (Dart_IsError(result)) {
|
| ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| }
|
| - WriteAppSnapshot(snapshot_filename,
|
| - vm_isolate_buffer,
|
| - vm_isolate_size,
|
| - isolate_buffer,
|
| - isolate_size,
|
| - instructions_blob_buffer,
|
| - instructions_blob_size,
|
| - rodata_blob_buffer,
|
| - rodata_blob_size);
|
| + WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
|
| + false,
|
| + vm_isolate_buffer,
|
| + vm_isolate_size);
|
| + WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
|
| + false,
|
| + isolate_buffer,
|
| + isolate_size);
|
| + WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
|
| + false,
|
| + instructions_blob_buffer,
|
| + instructions_blob_size);
|
| + WriteSnapshotFile(snapshot_filename, kRODataSuffix,
|
| + false,
|
| + rodata_blob_buffer,
|
| + rodata_blob_size);
|
| }
|
|
|
|
|
| @@ -1493,12 +1430,16 @@ static void GenerateFullSnapshot() {
|
| ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
|
| }
|
|
|
| - WriteAppSnapshot(snapshot_filename,
|
| - vm_isolate_buffer,
|
| - vm_isolate_size,
|
| - isolate_buffer,
|
| - isolate_size,
|
| - NULL, 0, NULL, 0);
|
| + WriteSnapshotFile(snapshot_filename,
|
| + kVMIsolateSuffix,
|
| + false,
|
| + vm_isolate_buffer,
|
| + vm_isolate_size);
|
| + WriteSnapshotFile(snapshot_filename,
|
| + kIsolateSuffix,
|
| + false,
|
| + isolate_buffer,
|
| + isolate_size);
|
| }
|
|
|
|
|
| @@ -1842,17 +1783,6 @@ void main(int argc, char** argv) {
|
| Platform::Exit(kErrorExitCode);
|
| }
|
|
|
| - const uint8_t* instructions_snapshot = NULL;
|
| - const uint8_t* data_snapshot = NULL;
|
| -
|
| - if (ReadAppSnapshot(script_name,
|
| - &vm_isolate_snapshot_buffer,
|
| - &isolate_snapshot_buffer,
|
| - &instructions_snapshot,
|
| - &data_snapshot)) {
|
| - run_app_snapshot = true;
|
| - }
|
| -
|
| #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
| // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME.
|
| if ((gen_snapshot_kind != kNone) || run_app_snapshot) {
|
| @@ -1876,6 +1806,31 @@ void main(int argc, char** argv) {
|
| TimerUtils::InitOnce();
|
| EventHandler::Start();
|
|
|
| + const uint8_t* instructions_snapshot = NULL;
|
| + const uint8_t* data_snapshot = NULL;
|
| + if (run_app_snapshot) {
|
| + ReadSnapshotFile(snapshot_filename, kVMIsolateSuffix,
|
| + &vm_isolate_snapshot_buffer);
|
| + ReadSnapshotFile(snapshot_filename, kIsolateSuffix,
|
| + &isolate_snapshot_buffer);
|
| + if (use_blobs) {
|
| + ReadExecutableSnapshotFile(snapshot_filename,
|
| + kInstructionsSuffix,
|
| + &instructions_snapshot);
|
| + ReadSnapshotFile(snapshot_filename, kRODataSuffix,
|
| + &data_snapshot);
|
| + } else {
|
| + instructions_snapshot = reinterpret_cast<const uint8_t*>(
|
| + LoadLibrarySymbol(snapshot_filename,
|
| + kPrecompiledLibraryName,
|
| + kPrecompiledInstructionsSymbolName));
|
| + data_snapshot = reinterpret_cast<const uint8_t*>(
|
| + LoadLibrarySymbol(snapshot_filename,
|
| + kPrecompiledLibraryName,
|
| + kPrecompiledDataSymbolName));
|
| + }
|
| + }
|
| +
|
| // Initialize the Dart VM.
|
| Dart_InitializeParams init_params;
|
| memset(&init_params, 0, sizeof(init_params));
|
|
|