diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc index 1415cb1750f..7a6e869769a 100644 --- a/runtime/bin/dartutils.cc +++ b/runtime/bin/dartutils.cc @@ -192,17 +192,6 @@ const char* DartUtils::RemoveScheme(const char* url) { } -void* DartUtils::MapExecutable(const char* name, intptr_t* len) { - File* file = File::Open(name, File::kRead); - if (file == NULL) { - return NULL; - } - void* addr = file->MapExecutable(len); - file->Release(); - return addr; -} - - void* DartUtils::OpenFile(const char* name, bool write) { File* file = File::Open(name, write ? File::kWriteTruncate : File::kRead); return reinterpret_cast(file); diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc index c34902c680f..44df41027c1 100644 --- a/runtime/bin/extensions_android.cc +++ b/runtime/bin/extensions_android.cc @@ -11,7 +11,8 @@ namespace dart { namespace bin { -const char* kPrecompiledLibraryName = "libprecompiled.so"; +const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot"; +const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot"; const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot"; const char* kPrecompiledDataSymbolName = "_kDataSnapshot"; diff --git a/runtime/bin/extensions_fuchsia.cc b/runtime/bin/extensions_fuchsia.cc index d4746725cce..691cac38dd3 100644 --- a/runtime/bin/extensions_fuchsia.cc +++ b/runtime/bin/extensions_fuchsia.cc @@ -11,7 +11,8 @@ namespace dart { namespace bin { -const char* kPrecompiledLibraryName = "libprecompiled.so"; +const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot"; +const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot"; const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot"; const char* kPrecompiledDataSymbolName = "_kDataSnapshot"; diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc index 8a25cba44da..264c4ee2fe7 100644 --- a/runtime/bin/extensions_linux.cc +++ b/runtime/bin/extensions_linux.cc @@ -11,7 +11,8 @@ namespace dart { namespace bin { -const char* kPrecompiledLibraryName = "libprecompiled.so"; +const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot"; +const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot"; const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot"; const char* kPrecompiledDataSymbolName = "_kDataSnapshot"; diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc index 9910f108607..69d712d1835 100644 --- a/runtime/bin/extensions_macos.cc +++ b/runtime/bin/extensions_macos.cc @@ -11,7 +11,8 @@ namespace dart { namespace bin { -const char* kPrecompiledLibraryName = "libprecompiled.dylib"; +const char* kPrecompiledVMIsolateSymbolName = "kVmIsolateSnapshot"; +const char* kPrecompiledIsolateSymbolName = "kIsolateSnapshot"; const char* kPrecompiledInstructionsSymbolName = "kInstructionsSnapshot"; const char* kPrecompiledDataSymbolName = "kDataSnapshot"; diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc index 493acad450e..da626f15e06 100644 --- a/runtime/bin/extensions_win.cc +++ b/runtime/bin/extensions_win.cc @@ -12,7 +12,8 @@ namespace dart { namespace bin { -const char* kPrecompiledLibraryName = "precompiled.dll"; +const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot"; +const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot"; const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot"; const char* kPrecompiledDataSymbolName = "_kDataSnapshot"; diff --git a/runtime/bin/file.h b/runtime/bin/file.h index 6b22793ec5a..c30c02d8bf2 100644 --- a/runtime/bin/file.h +++ b/runtime/bin/file.h @@ -88,7 +88,11 @@ class File : public ReferenceCounted { intptr_t GetFD(); - void* MapExecutable(intptr_t* num_bytes); + enum MapType { + kReadOnly = 0, + kReadExecute = 1, + }; + void* Map(MapType type, int64_t position, int64_t length); // Read/Write attempt to transfer num_bytes to/from buffer. It returns // the number of bytes read/written. diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc index 9bcf44c8334..a139876bdb3 100644 --- a/runtime/bin/file_android.cc +++ b/runtime/bin/file_android.cc @@ -78,17 +78,23 @@ bool File::IsClosed() { } -void* File::MapExecutable(intptr_t* len) { +void* File::Map(MapType type, int64_t position, int64_t length) { ASSERT(handle_->fd() >= 0); - - intptr_t length = Length(); - void* addr = mmap(0, length, - PROT_READ | PROT_EXEC, MAP_PRIVATE, - handle_->fd(), 0); + int prot = PROT_NONE; + switch (type) { + case kReadOnly: + prot = PROT_READ; + break; + case kReadExecute: + prot = PROT_READ | PROT_EXEC; + break; + default: + return NULL; + } + void* addr = mmap(NULL, length, prot, MAP_PRIVATE, + handle_->fd(), position); if (addr == MAP_FAILED) { - *len = -1; - } else { - *len = length; + return NULL; } return addr; } diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc index fdc26238821..cdc587625c9 100644 --- a/runtime/bin/file_fuchsia.cc +++ b/runtime/bin/file_fuchsia.cc @@ -75,7 +75,13 @@ bool File::IsClosed() { } -void* File::MapExecutable(intptr_t* len) { +void* File::Map(MapType type, int64_t position, int64_t length) { + UNIMPLEMENTED(); + return NULL; +} + + +void* File::MapReadExecute(int64_t position, int64_t length) { UNIMPLEMENTED(); return NULL; } diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc index 4f61db1d306..e6b27f8ace5 100644 --- a/runtime/bin/file_linux.cc +++ b/runtime/bin/file_linux.cc @@ -77,16 +77,23 @@ bool File::IsClosed() { } -void* File::MapExecutable(intptr_t* len) { +void* File::Map(MapType type, int64_t position, int64_t length) { ASSERT(handle_->fd() >= 0); - intptr_t length = Length(); - void* addr = mmap(0, length, - PROT_READ | PROT_EXEC, MAP_PRIVATE, - handle_->fd(), 0); + int prot = PROT_NONE; + switch (type) { + case kReadOnly: + prot = PROT_READ; + break; + case kReadExecute: + prot = PROT_READ | PROT_EXEC; + break; + default: + return NULL; + } + void* addr = mmap(NULL, length, prot, MAP_PRIVATE, + handle_->fd(), position); if (addr == MAP_FAILED) { - *len = -1; - } else { - *len = length; + return NULL; } return addr; } diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc index 38699cd6d06..0720b6f3437 100644 --- a/runtime/bin/file_macos.cc +++ b/runtime/bin/file_macos.cc @@ -80,16 +80,23 @@ bool File::IsClosed() { } -void* File::MapExecutable(intptr_t* len) { +void* File::Map(MapType type, int64_t position, int64_t length) { ASSERT(handle_->fd() >= 0); - intptr_t length = Length(); - void* addr = mmap(0, length, - PROT_READ | PROT_EXEC, MAP_PRIVATE, - handle_->fd(), 0); + int prot = PROT_NONE; + switch (type) { + case kReadOnly: + prot = PROT_READ; + break; + case kReadExecute: + prot = PROT_READ | PROT_EXEC; + break; + default: + return NULL; + } + void* addr = mmap(NULL, length, prot, MAP_PRIVATE, + handle_->fd(), position); if (addr == MAP_FAILED) { - *len = -1; - } else { - *len = length; + return NULL; } return addr; } diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc index f487a889b88..a9cfda9d5a6 100644 --- a/runtime/bin/file_win.cc +++ b/runtime/bin/file_win.cc @@ -74,7 +74,13 @@ bool File::IsClosed() { } -void* File::MapExecutable(intptr_t* len) { +void* File::Map(MapType type, int64_t position, int64_t length) { + UNIMPLEMENTED(); + return NULL; +} + + +void* File::MapReadExecute(int64_t position, int64_t length) { UNIMPLEMENTED(); return NULL; } diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc index 319a322d4d1..5f7f9b0e959 100644 --- a/runtime/bin/gen_snapshot.cc +++ b/runtime/bin/gen_snapshot.cc @@ -1036,16 +1036,6 @@ static void CreateAndWritePrecompiledSnapshot( Dart_QualifiedFunctionName* standalone_entry_points) { ASSERT(IsSnapshottingForPrecompilation()); Dart_Handle result; - uint8_t* vm_isolate_buffer = NULL; - intptr_t vm_isolate_size = 0; - uint8_t* isolate_buffer = NULL; - intptr_t isolate_size = 0; - uint8_t* assembly_buffer = NULL; - intptr_t assembly_size = 0; - uint8_t* instructions_blob_buffer = NULL; - intptr_t instructions_blob_size = 0; - uint8_t* rodata_blob_buffer = NULL; - intptr_t rodata_blob_size = 0; // Precompile with specified embedder entry points result = Dart_Precompile(standalone_entry_points, true); @@ -1054,14 +1044,23 @@ static void CreateAndWritePrecompiledSnapshot( // Create a precompiled snapshot. bool as_assembly = assembly_filename != NULL; if (as_assembly) { - result = Dart_CreatePrecompiledSnapshotAssembly(&vm_isolate_buffer, - &vm_isolate_size, - &isolate_buffer, - &isolate_size, - &assembly_buffer, + uint8_t* assembly_buffer = NULL; + intptr_t assembly_size = 0; + result = Dart_CreatePrecompiledSnapshotAssembly(&assembly_buffer, &assembly_size); CHECK_RESULT(result); + WriteSnapshotFile(assembly_filename, + assembly_buffer, + assembly_size); } else { + uint8_t* vm_isolate_buffer = NULL; + intptr_t vm_isolate_size = 0; + uint8_t* isolate_buffer = NULL; + intptr_t isolate_size = 0; + uint8_t* instructions_blob_buffer = NULL; + intptr_t instructions_blob_size = 0; + uint8_t* rodata_blob_buffer = NULL; + intptr_t rodata_blob_size = 0; result = Dart_CreatePrecompiledSnapshotBlob(&vm_isolate_buffer, &vm_isolate_size, &isolate_buffer, @@ -1071,20 +1070,12 @@ static void CreateAndWritePrecompiledSnapshot( &rodata_blob_buffer, &rodata_blob_size); CHECK_RESULT(result); - } - - // Now write the snapshot pieces out to the specified files and exit. - WriteSnapshotFile(vm_isolate_snapshot_filename, - vm_isolate_buffer, - vm_isolate_size); - WriteSnapshotFile(isolate_snapshot_filename, - isolate_buffer, - isolate_size); - if (as_assembly) { - WriteSnapshotFile(assembly_filename, - assembly_buffer, - assembly_size); - } else { + WriteSnapshotFile(vm_isolate_snapshot_filename, + vm_isolate_buffer, + vm_isolate_size); + WriteSnapshotFile(isolate_snapshot_filename, + isolate_buffer, + isolate_size); WriteSnapshotFile(instructions_blob_filename, instructions_blob_buffer, instructions_blob_size); @@ -1092,6 +1083,7 @@ static void CreateAndWritePrecompiledSnapshot( rodata_blob_buffer, rodata_blob_size); } + Dart_ExitScope(); // Shutdown the isolate. diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index b5ef0870b9f..d8fa7e5cecf 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. @@ -378,15 +373,6 @@ 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); @@ -565,7 +551,6 @@ static struct { { "--observe", ProcessObserveOption }, { "--snapshot=", ProcessSnapshotFilenameOption }, { "--snapshot-kind=", ProcessSnapshotKindOption }, - { "--run-app-snapshot=", ProcessRunAppSnapshotOption }, { "--use-blobs", ProcessUseBlobsOption }, { "--trace-loading", ProcessTraceLoadingOption }, { "--hot-reload-test-mode", ProcessHotReloadTestModeOption }, @@ -1207,93 +1192,193 @@ 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 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(read_only_buffer) + + (vmisolate_position - vmisolate_position); + *isolate_buffer = reinterpret_cast(read_only_buffer) + + (isolate_position - vmisolate_position); + if (header[3] == 0) { + *rodata_buffer = NULL; + } else { + *rodata_buffer = reinterpret_cast(read_only_buffer) + + (rodata_position - vmisolate_position); + } + + if (header[4] == 0) { + *instructions_buffer = NULL; + } else { + *instructions_buffer = reinterpret_cast( + file->Map(File::kReadExecute, instructions_position, header[4])); + if (*instructions_buffer == NULL) { + ErrorExit(kErrorExitCode, "Failed to memory map snapshot2\n"); + } + } + + file->Release(); + return true; } -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; - } - - intptr_t len = -1; - *buffer = reinterpret_cast( - 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 (concat != NULL) { - delete[] concat; - } -} - - -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; - } - void* library = Extensions::LoadExtensionLibrary(qualified_libname); - if (concat != NULL) { - delete concat; - } +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 NULL; + return false; } - return Extensions::ResolveSymbol(library, symname); + + *vmisolate_buffer = reinterpret_cast( + Extensions::ResolveSymbol(library, kPrecompiledVMIsolateSymbolName)); + if (*vmisolate_buffer == NULL) { + ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", + kPrecompiledVMIsolateSymbolName); + } + + *isolate_buffer = reinterpret_cast( + Extensions::ResolveSymbol(library, kPrecompiledIsolateSymbolName)); + if (*isolate_buffer == NULL) { + ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", + kPrecompiledIsolateSymbolName); + } + + *instructions_buffer = reinterpret_cast( + Extensions::ResolveSymbol(library, kPrecompiledInstructionsSymbolName)); + if (*instructions_buffer == NULL) { + ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", + kPrecompiledInstructionsSymbolName); + } + + *rodata_buffer = reinterpret_cast( + Extensions::ResolveSymbol(library, kPrecompiledDataSymbolName)); + if (*rodata_buffer == NULL) { + ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", + kPrecompiledDataSymbolName); + } + + 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; + } + 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); + } + + 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); + } + } + + 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); + } + } + + file->Flush(); + file->Release(); } @@ -1334,35 +1419,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 +1445,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 +1465,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 +1493,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); } @@ -1783,6 +1842,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) { @@ -1806,31 +1876,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( - LoadLibrarySymbol(snapshot_filename, - kPrecompiledLibraryName, - kPrecompiledInstructionsSymbolName)); - data_snapshot = reinterpret_cast( - LoadLibrarySymbol(snapshot_filename, - kPrecompiledLibraryName, - kPrecompiledDataSymbolName)); - } - } - // Initialize the Dart VM. Dart_InitializeParams init_params; memset(&init_params, 0, sizeof(init_params)); diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index c9c0d1a926e..45a84008b97 100755 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -3115,10 +3115,6 @@ DART_EXPORT Dart_Handle Dart_Precompile( * \return A valid handle if no error occurs during the operation. */ DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly( - uint8_t** vm_isolate_snapshot_buffer, - intptr_t* vm_isolate_snapshot_size, - uint8_t** isolate_snapshot_buffer, - intptr_t* isolate_snapshot_size, uint8_t** assembly_buffer, intptr_t* assembly_size); diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index d9e65ad4796..1799db88ae9 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -5287,7 +5287,10 @@ void FullSnapshotWriter::WriteFullSnapshot() { WriteIsolateFullSnapshot(num_base_objects); if (Snapshot::IncludesCode(kind_)) { - instructions_writer_->Write(); + instructions_writer_->Write(*vm_isolate_snapshot_buffer_, + vm_isolate_snapshot_size_, + *isolate_snapshot_buffer_, + isolate_snapshot_size_); OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize()); OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize()); diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index f6f3ab841fb..8fbeea1411f 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -6323,10 +6323,6 @@ DART_EXPORT Dart_Handle Dart_Precompile( DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly( - uint8_t** vm_isolate_snapshot_buffer, - intptr_t* vm_isolate_snapshot_size, - uint8_t** isolate_snapshot_buffer, - intptr_t* isolate_snapshot_size, uint8_t** assembly_buffer, intptr_t* assembly_size) { UNREACHABLE(); @@ -6378,10 +6374,6 @@ DART_EXPORT Dart_Handle Dart_Precompile( DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly( - uint8_t** vm_isolate_snapshot_buffer, - intptr_t* vm_isolate_snapshot_size, - uint8_t** isolate_snapshot_buffer, - intptr_t* isolate_snapshot_size, uint8_t** assembly_buffer, intptr_t* assembly_size) { #if defined(TARGET_ARCH_IA32) @@ -6397,18 +6389,6 @@ DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly( "Did you forget to call Dart_Precompile?"); } ASSERT(FLAG_load_deferred_eagerly); - if (vm_isolate_snapshot_buffer == NULL) { - RETURN_NULL_ERROR(vm_isolate_snapshot_buffer); - } - if (vm_isolate_snapshot_size == NULL) { - RETURN_NULL_ERROR(vm_isolate_snapshot_size); - } - if (isolate_snapshot_buffer == NULL) { - RETURN_NULL_ERROR(isolate_snapshot_buffer); - } - if (isolate_snapshot_size == NULL) { - RETURN_NULL_ERROR(isolate_snapshot_size); - } if (assembly_buffer == NULL) { RETURN_NULL_ERROR(assembly_buffer); } @@ -6421,15 +6401,15 @@ DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly( AssemblyInstructionsWriter instructions_writer(assembly_buffer, ApiReallocate, 2 * MB /* initial_size */); + uint8_t* vm_isolate_snapshot_buffer = NULL; + uint8_t* isolate_snapshot_buffer = NULL; FullSnapshotWriter writer(Snapshot::kAppNoJIT, - vm_isolate_snapshot_buffer, - isolate_snapshot_buffer, + &vm_isolate_snapshot_buffer, + &isolate_snapshot_buffer, ApiReallocate, &instructions_writer); writer.WriteFullSnapshot(); - *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize(); - *isolate_snapshot_size = writer.IsolateSnapshotSize(); *assembly_size = instructions_writer.AssemblySize(); return Api::Success(); diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc index 0062dacd544..08cf77ce3a9 100644 --- a/runtime/vm/snapshot.cc +++ b/runtime/vm/snapshot.cc @@ -704,7 +704,10 @@ static void EnsureIdentifier(char* label) { } -void AssemblyInstructionsWriter::Write() { +void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer, + intptr_t vmisolate_length, + uint8_t* isolate_buffer, + intptr_t isolate_length) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); NOT_IN_PRODUCT(TimelineDurationScope tds(thread, @@ -849,10 +852,28 @@ void AssemblyInstructionsWriter::Write() { WriteWordLiteralData(*cursor); } } + + + assembly_stream_.Print(".globl _kVmIsolateSnapshot\n"); + assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); + assembly_stream_.Print("_kVmIsolateSnapshot:\n"); + for (intptr_t i = 0; i < vmisolate_length; i++) { + assembly_stream_.Print(".byte %" Pd "\n", vmisolate_buffer[i]); + } + + assembly_stream_.Print(".globl _kIsolateSnapshot\n"); + assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); + assembly_stream_.Print("_kIsolateSnapshot:\n"); + for (intptr_t i = 0; i < isolate_length; i++) { + assembly_stream_.Print(".byte %" Pd "\n", isolate_buffer[i]); + } } -void BlobInstructionsWriter::Write() { +void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer, + intptr_t vmisolate_len, + uint8_t* isolate_buffer, + intptr_t isolate_length) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); NOT_IN_PRODUCT(TimelineDurationScope tds(thread, diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index 3f767b8eb25..020f4485a96 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -750,7 +750,10 @@ class InstructionsWriter : public ZoneAllocated { int32_t GetObjectOffsetFor(RawObject* raw_object); - virtual void Write() = 0; + virtual void Write(uint8_t* vmisolate_buffer, + intptr_t vmisolate_length, + uint8_t* isolate_buffer, + intptr_t isolate_length) = 0; virtual intptr_t text_size() = 0; virtual intptr_t data_size() = 0; @@ -803,7 +806,10 @@ class AssemblyInstructionsWriter : public InstructionsWriter { data_size_(0) { } - virtual void Write(); + virtual void Write(uint8_t* vmisolate_buffer, + intptr_t vmisolate_length, + uint8_t* isolate_buffer, + intptr_t isolate_length); virtual intptr_t text_size() { return text_size_; } virtual intptr_t data_size() { return data_size_; } @@ -849,7 +855,10 @@ class BlobInstructionsWriter : public InstructionsWriter { rodata_blob_stream_(rodata_blob_buffer, alloc, initial_size) { } - virtual void Write(); + virtual void Write(uint8_t* vmisolate_buffer, + intptr_t vmisolate_length, + uint8_t* isolate_buffer, + intptr_t isolate_length); virtual intptr_t text_size() { return InstructionsBlobSize(); } virtual intptr_t data_size() { return RodataBlobSize(); } diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart index d0e6f5f444a..6cada5b21c9 100644 --- a/tools/testing/dart/compiler_configuration.dart +++ b/tools/testing/dart/compiler_configuration.dart @@ -369,10 +369,12 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration { Map environmentOverrides) { var exec = "$buildDir/dart_bootstrap"; var args = new List(); - args.add("--snapshot=$tempDir"); args.add("--snapshot-kind=app-aot"); if (useBlobs) { + args.add("--snapshot=$tempDir/out.aotsnapshot"); args.add("--use-blobs"); + } else { + args.add("--snapshot=$tempDir/out.S"); } if (isAndroid && arch == 'arm') { args.add('--no-sim-use-hardfp'); @@ -390,15 +392,13 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration { List arguments, Map environmentOverrides) { - var cc, shared, libname; + var cc, shared; if (Platform.isLinux) { cc = 'gcc'; shared = '-shared'; - libname = 'libprecompiled.so'; } else if (Platform.isMacOS) { cc = 'clang'; shared = '-dynamiclib'; - libname = 'libprecompiled.dylib'; } else { throw "Platform not supported: ${Platform.operatingSystem}"; } @@ -430,8 +430,8 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration { var args = (cc_flags != null) ? [ shared, cc_flags ] : [ shared ]; args.addAll([ '-o', - '$tempDir/$libname', - '$tempDir/snapshot.S' + '$tempDir/out.aotsnapshot', + '$tempDir/out.S' ]); return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk, @@ -447,7 +447,7 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration { List arguments, Map environmentOverrides) { var exec = 'rm'; - var args = ['$tempDir/snapshot.S']; + var args = ['$tempDir/out.S']; return commandBuilder.getCompilationCommand( 'remove_assembly', @@ -532,7 +532,7 @@ class Dart2AppSnapshotCompilerConfiguration extends CompilerConfiguration { Map environmentOverrides) { var exec = "$buildDir/dart_bootstrap"; var args = new List(); - args.add("--snapshot=$tempDir"); + args.add("--snapshot=$tempDir/out.jitsnapshot"); args.add("--snapshot-kind=app-after-run"); args.addAll(arguments); @@ -592,7 +592,7 @@ class Dart2AppJitSnapshotCompilerConfiguration extends Dart2AppSnapshotCompilerC Map environmentOverrides) { var exec = "$buildDir/dart"; var args = new List(); - args.add("--snapshot=$tempDir"); + args.add("--snapshot=$tempDir/out.jitsnapshot"); args.add("--snapshot-kind=app-jit-after-run"); if (useBlobs) { args.add("--use-blobs"); diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart index 8983cc5949d..a56614864c1 100644 --- a/tools/testing/dart/runtime_configuration.dart +++ b/tools/testing/dart/runtime_configuration.dart @@ -4,6 +4,8 @@ library runtime_configuration; +import 'dart:io' show Platform; + import 'compiler_configuration.dart' show CommandArtifact; // TODO(ahe): Remove this import, we can precompute all the values required @@ -244,16 +246,14 @@ class DartAppRuntimeConfiguration extends DartVmRuntimeConfiguration { throw "dart_app cannot run files of type '$type'."; } - var augmentedArgs = new List(); - augmentedArgs.add("--run-app-snapshot=${artifact.filename}"); - if (useBlobs) { - augmentedArgs.add("--use-blobs"); - } - augmentedArgs.addAll(arguments); + var args = new List(); + args.addAll(arguments); + args.removeLast(); + args.add("${artifact.filename}/out.jitsnapshot"); return [ commandBuilder.getVmCommand(suite.dartVmBinaryFileName, - augmentedArgs, environmentOverrides) + args, environmentOverrides) ]; } } @@ -274,16 +274,14 @@ class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration { throw "dart_precompiled cannot run files of type '$type'."; } - var augmentedArgs = new List(); - augmentedArgs.add("--run-app-snapshot=${artifact.filename}"); - if (useBlobs) { - augmentedArgs.add("--use-blobs"); - } - augmentedArgs.addAll(arguments); + var args = new List(); + args.addAll(arguments); + args.removeLast(); + args.add("${artifact.filename}/out.aotsnapshot"); return [ commandBuilder.getVmCommand(suite.dartPrecompiledBinaryFileName, - augmentedArgs, environmentOverrides) + args, environmentOverrides) ]; } }