Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2419)

Unified Diff: runtime/bin/main.cc

Issue 2405393002: Use a single file for app snapshots. (Closed)
Patch Set: . Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/bin/main.cc
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index c5afc0bfe2a70f5205572c409fe555f0bb073c62..9095165ab80b6535388307a1c245720585bd3909 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -97,16 +97,11 @@ static const bool is_noopt = false;
#endif
-extern const char* kPrecompiledLibraryName;
+extern const char* kPrecompiledVMIsolateSymbolName;
+extern const char* kPrecompiledIsolateSymbolName;
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.
@@ -1207,93 +1202,203 @@ static void WriteSnapshotFile(const char* snapshot_directory,
}
-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 {
- qualified_filename = filename;
- }
+static const int64_t kAppSnapshotHeaderSize = 5 * sizeof(int64_t); // NOLINT
+static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc;
+static const int64_t kAppSnapshotPageSize = 4 * KB;
- void* file = DartUtils::OpenFile(qualified_filename, false);
+
+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) {
- fprintf(stderr,
- "Error: Unable to open file %s for reading snapshot\n",
- qualified_filename);
- fflush(stderr);
- Platform::Exit(kErrorExitCode);
+ 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);
+ if (file->Length() < kAppSnapshotHeaderSize) {
+ file->Release();
+ return false;
}
- DartUtils::CloseFile(file);
- if (concat != NULL) {
- delete[] concat;
+ int64_t magic = 0;
+ int64_t vmisolate_size = 0;
+ int64_t isolate_size = 0;
+ int64_t instructions_size = 0;
+ int64_t rodata_size = 0;
+ if (!file->ReadFully(&magic, sizeof(magic))) {
+ file->Release();
+ return false;
}
-}
+ if (magic != kAppSnapshotMagicNumber) {
+ file->Release();
+ return false;
+ }
+ file->ReadFully(&vmisolate_size, sizeof(vmisolate_size));
+ file->ReadFully(&isolate_size, sizeof(isolate_size));
+ file->ReadFully(&instructions_size, sizeof(instructions_size));
+ file->ReadFully(&rodata_size, sizeof(rodata_size));
+ ASSERT(file->Position() == kAppSnapshotHeaderSize);
siva 2016/10/12 20:37:33 Instead of these individual reads of the magic num
rmacnak 2016/10/13 01:08:16 Done.
+ int64_t position = file->Position();
+ position = Utils::RoundUp(position, kAppSnapshotPageSize);
+ *vmisolate_buffer = reinterpret_cast<const uint8_t*>(
+ file->MapReadOnly(position, vmisolate_size));
+ if (*vmisolate_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
+ }
+ position += vmisolate_size;
-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;
+ position = Utils::RoundUp(position, kAppSnapshotPageSize);
+ *isolate_buffer = reinterpret_cast<const uint8_t*>(
+ file->MapReadOnly(position, isolate_size));
+ if (*isolate_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
+ }
+ position += isolate_size;
+
+ if (instructions_size == 0) {
+ *instructions_buffer = NULL;
} else {
- qualified_filename = filename;
+ position = Utils::RoundUp(position, kAppSnapshotPageSize);
+ *instructions_buffer = reinterpret_cast<const uint8_t*>(
+ file->MapReadExecute(position, instructions_size));
+ if (*instructions_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
+ }
+ position += instructions_size;
}
- 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);
+ if (rodata_size == 0) {
+ *rodata_buffer = NULL;
+ } else {
+ position = Utils::RoundUp(position, kAppSnapshotPageSize);
+ *rodata_buffer = reinterpret_cast<const uint8_t*>(
+ file->MapReadOnly(position, rodata_size));
+ if (*rodata_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
+ }
}
- if (concat != NULL) {
- delete[] concat;
+
siva 2016/10/12 20:37:33 Can the order of rodata be swapped with instructio
rmacnak 2016/10/13 01:08:16 Done.
+ return true;
siva 2016/10/12 20:37:33 Missing file->Release() for the success case? On L
rmacnak 2016/10/13 01:08:16 Done.
+}
+
+
+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);
siva 2016/10/12 20:37:33 Can you make sure that this will work for any name
rmacnak 2016/10/13 01:08:16 Done, using the same for both platforms in the tes
+ if (library == NULL) {
+ return false;
+ }
+
+ *vmisolate_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledVMIsolateSymbolName));
+ if (*vmisolate_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledVMIsolateSymbolName);
+ }
+
+ *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);
}
+
+ *rodata_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledDataSymbolName));
+ if (*rodata_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledDataSymbolName);
+ }
+
+ return true;
}
-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;
+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;
}
- void* library = Extensions::LoadExtensionLibrary(qualified_libname);
- 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);
}
- if (library == NULL) {
- return NULL;
+
+ file->WriteFully(&kAppSnapshotMagicNumber, sizeof(kAppSnapshotMagicNumber));
+ WriteInt64(file, vmisolate_size);
+ WriteInt64(file, isolate_size);
+ WriteInt64(file, instructions_size);
+ WriteInt64(file, rodata_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);
+ }
+
+ 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 (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);
+ }
}
- return Extensions::ResolveSymbol(library, symname);
+
+ file->Flush();
+ file->Release();
}
@@ -1334,35 +1439,24 @@ 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) {
- WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
- false,
- instructions_blob_buffer,
- instructions_blob_size);
- WriteSnapshotFile(snapshot_filename, kRODataSuffix,
- false,
- rodata_blob_buffer,
- rodata_blob_size);
+ 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);
} else {
- WriteSnapshotFile(snapshot_filename, kAssemblySuffix,
+ WriteSnapshotFile(NULL, snapshot_filename,
false,
assembly_buffer,
assembly_size);
@@ -1371,10 +1465,6 @@ 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;
@@ -1395,22 +1485,15 @@ static void GeneratePrecompiledJITSnapshot() {
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);
- WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
- false,
- instructions_blob_buffer,
- instructions_blob_size);
- WriteSnapshotFile(snapshot_filename, kRODataSuffix,
- false,
- rodata_blob_buffer,
- rodata_blob_size);
+ 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);
}
@@ -1430,16 +1513,12 @@ static void GenerateFullSnapshot() {
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);
+ WriteAppSnapshot(snapshot_filename,
+ vm_isolate_buffer,
+ vm_isolate_size,
+ isolate_buffer,
+ isolate_size,
+ NULL, 0, NULL, 0);
}
@@ -1778,6 +1857,17 @@ 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) {
@@ -1801,31 +1891,6 @@ 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));

Powered by Google App Engine
This is Rietveld 408576698