From 87c8a6ee7675ecd8447d95a7a7d5ce0aa40f6c3b Mon Sep 17 00:00:00 2001 From: "asiva@google.com" Date: Tue, 31 Mar 2015 18:46:19 +0000 Subject: [PATCH] First step towards splitting a full snapshot into a vm isolate snapshot and a regular isolate snapsot. - change gen_snapshot to split a full snapshot into a vm isolate snapshot and an isolate snapshot - change the build process and scripts to account for splitting the full snapshot R=hausner@google.com Review URL: https://codereview.chromium.org//1023753006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44814 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/bin/bin.gypi | 17 ++++--- runtime/bin/gen_snapshot.cc | 68 +++++++++++++++++++-------- runtime/bin/main.cc | 19 +++++--- runtime/bin/run_vm_tests.cc | 3 +- runtime/bin/snapshot_empty.cc | 3 +- runtime/bin/snapshot_in.cc | 19 ++++++-- runtime/include/dart_api.h | 21 ++++++--- runtime/tools/create_snapshot_bin.py | 16 +++++-- runtime/tools/create_snapshot_file.py | 17 +++++-- runtime/vm/benchmark_test.cc | 18 ++++--- runtime/vm/benchmark_test.h | 12 +++-- runtime/vm/dart.cc | 7 ++- runtime/vm/dart.h | 1 + runtime/vm/dart_api_impl.cc | 32 +++++++++---- runtime/vm/dart_api_impl_test.cc | 8 ++-- runtime/vm/snapshot.h | 16 +++++-- runtime/vm/snapshot_test.cc | 61 +++++++++++++++++------- runtime/vm/unit_test.h | 12 +++-- 18 files changed, 250 insertions(+), 100 deletions(-) diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi index c626805a5ed..d9c43587538 100644 --- a/runtime/bin/bin.gypi +++ b/runtime/bin/bin.gypi @@ -11,7 +11,8 @@ 'builtin_in_cc_file': 'builtin_in.cc', 'builtin_cc_file': '<(gen_source_dir)/builtin_gen.cc', 'snapshot_in_cc_file': 'snapshot_in.cc', - 'snapshot_bin_file': '<(gen_source_dir)/snapshot_gen.bin', + 'vm_isolate_snapshot_bin_file': '<(gen_source_dir)/vm_isolate_snapshot_gen.bin', + 'isolate_snapshot_bin_file': '<(gen_source_dir)/isolate_snapshot_gen.bin', 'resources_cc_file': '<(gen_source_dir)/resources_gen.cc', 'bootstrap_resources_cc_file': '<(gen_source_dir)/bootstrap_resources_gen.cc', @@ -431,17 +432,19 @@ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)', ], 'outputs': [ - '<(snapshot_bin_file)', + '<(vm_isolate_snapshot_bin_file)', + '<(isolate_snapshot_bin_file)', ], 'action': [ 'python', 'tools/create_snapshot_bin.py', '--executable', '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)', - '--output_bin', '<(snapshot_bin_file)', + '--vm_output_bin', '<(vm_isolate_snapshot_bin_file)', + '--output_bin', '<(isolate_snapshot_bin_file)', '--target_os', '<(OS)' ], - 'message': 'Generating ''<(snapshot_bin_file)'' file.' + 'message': 'Generating ''<(vm_isolate_snapshot_bin_file)'' ''<(isolate_snapshot_bin_file)'' files.' }, ], }, @@ -459,7 +462,8 @@ 'inputs': [ '../tools/create_snapshot_file.py', '<(snapshot_in_cc_file)', - '<(snapshot_bin_file)' + '<(vm_isolate_snapshot_bin_file)', + '<(isolate_snapshot_bin_file)', ], 'outputs': [ '<(snapshot_cc_file)', @@ -467,7 +471,8 @@ 'action': [ 'python', 'tools/create_snapshot_file.py', - '--input_bin', '<(snapshot_bin_file)', + '--vm_input_bin', '<(vm_isolate_snapshot_bin_file)', + '--input_bin', '<(isolate_snapshot_bin_file)', '--input_cc', '<(snapshot_in_cc_file)', '--output', '<(snapshot_cc_file)', ], diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc index 719b2b5fd63..76c256b8736 100644 --- a/runtime/bin/gen_snapshot.cc +++ b/runtime/bin/gen_snapshot.cc @@ -25,7 +25,6 @@ namespace bin { #define CHECK_RESULT(result) \ if (Dart_IsError(result)) { \ - free(snapshot_buffer); \ Log::PrintErr("Error: %s", Dart_GetError(result)); \ Dart_ExitScope(); \ Dart_ShutdownIsolate(); \ @@ -35,9 +34,9 @@ namespace bin { // Global state that indicates whether a snapshot is to be created and // if so which file to write the snapshot into. -static const char* snapshot_filename = NULL; +static const char* vm_isolate_snapshot_filename = NULL; +static const char* isolate_snapshot_filename = NULL; static const char* package_root = NULL; -static uint8_t* snapshot_buffer = NULL; // Global state which contains a pointer to the script name for which @@ -67,10 +66,20 @@ static const char* ProcessOption(const char* option, const char* name) { } -static bool ProcessSnapshotOption(const char* option) { - const char* name = ProcessOption(option, "--snapshot="); +static bool ProcessVmIsolateSnapshotOption(const char* option) { + const char* name = ProcessOption(option, "--vm_isolate_snapshot="); if (name != NULL) { - snapshot_filename = name; + vm_isolate_snapshot_filename = name; + return true; + } + return false; +} + + +static bool ProcessIsolateSnapshotOption(const char* option) { + const char* name = ProcessOption(option, "--isolate_snapshot="); + if (name != NULL) { + isolate_snapshot_filename = name; return true; } return false; @@ -114,7 +123,8 @@ static int ParseArguments(int argc, // Parse out the vm options. while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { - if (ProcessSnapshotOption(argv[i]) || + if (ProcessVmIsolateSnapshotOption(argv[i]) || + ProcessIsolateSnapshotOption(argv[i]) || ProcessURLmappingOption(argv[i]) || ProcessPackageRootOption(argv[i])) { i += 1; @@ -132,8 +142,13 @@ static int ParseArguments(int argc, *script_name = NULL; } - if (snapshot_filename == NULL) { - Log::PrintErr("No snapshot output file specified.\n\n"); + if (vm_isolate_snapshot_filename == NULL) { + Log::PrintErr("No vm isolate snapshot output file specified.\n\n"); + return -1; + } + + if (isolate_snapshot_filename == NULL) { + Log::PrintErr("No isolate snapshot output file specified.\n\n"); return -1; } @@ -141,11 +156,13 @@ static int ParseArguments(int argc, } -static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) { - File* file = File::Open(snapshot_filename, File::kWriteTruncate); +static void WriteSnapshotFile(const char* filename, + const uint8_t* buffer, + const intptr_t size) { + File* file = File::Open(filename, File::kWriteTruncate); ASSERT(file != NULL); if (!file->WriteFully(buffer, size)) { - Log::PrintErr("Error: Failed to write full snapshot.\n\n"); + Log::PrintErr("Error: Failed to write snapshot file.\n\n"); } delete file; } @@ -438,15 +455,26 @@ static void VerifyLoaded(Dart_Handle library) { static void CreateAndWriteSnapshot() { Dart_Handle result; - uint8_t* buffer = NULL; - intptr_t size = 0; + uint8_t* vm_isolate_buffer = NULL; + intptr_t vm_isolate_size = 0; + uint8_t* isolate_buffer = NULL; + intptr_t isolate_size = 0; // First create a snapshot. - result = Dart_CreateSnapshot(&buffer, &size); + result = Dart_CreateSnapshot(&vm_isolate_buffer, + &vm_isolate_size, + &isolate_buffer, + &isolate_size); CHECK_RESULT(result); - // Now write the snapshot out to specified file and exit. - WriteSnapshotFile(buffer, size); + // Now write the vm isolate and isolate snapshots out to the + // specified file and exit. + WriteSnapshotFile(vm_isolate_snapshot_filename, + vm_isolate_buffer, + vm_isolate_size); + WriteSnapshotFile(isolate_snapshot_filename, + isolate_buffer, + isolate_size); Dart_ExitScope(); // Shutdown the isolate. @@ -510,7 +538,8 @@ int main(int argc, char** argv) { // Initialize the Dart VM. // Note: We don't expect isolates to be created from dart code during // snapshot generation. - if (!Dart_Initialize(NULL, NULL, NULL, NULL, + if (!Dart_Initialize(NULL, + NULL, NULL, NULL, NULL, DartUtils::OpenFile, DartUtils::ReadFile, DartUtils::WriteFile, @@ -532,7 +561,8 @@ int main(int argc, char** argv) { Dart_Handle library; Dart_EnterScope(); - ASSERT(snapshot_filename != NULL); + ASSERT(vm_isolate_snapshot_filename != NULL); + ASSERT(isolate_snapshot_filename != NULL); // Load up the script before a snapshot is created. if (app_script_name != NULL) { // This is the case of a custom embedder (e.g: dartium) trying to diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index a94631c70d3..9fa8de91a1d 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -28,9 +28,13 @@ namespace dart { namespace bin { -// snapshot_buffer points to a snapshot if we link in a snapshot otherwise -// it is initialized to NULL. -extern const uint8_t* snapshot_buffer; +// vm_isolate_snapshot_buffer points to a snapshot for the vm isolate if we +// link in a snapshot otherwise it is initialized to NULL. +extern const uint8_t* vm_isolate_snapshot_buffer; + +// isolate_snapshot_buffer points to a snapshot for an isolate if we link in a +// snapshot otherwise it is initialized to NULL. +extern const uint8_t* isolate_snapshot_buffer; // Global state that stores a pointer to the application script snapshot. static bool generate_script_snapshot = false; @@ -293,7 +297,7 @@ static bool ProcessGenScriptSnapshotOption(const char* filename, CommandLineOptions* vm_options) { if (filename != NULL && strlen(filename) != 0) { // Ensure that are already running using a full snapshot. - if (snapshot_buffer == NULL) { + if (isolate_snapshot_buffer == NULL) { Log::PrintErr("Script snapshots cannot be generated in this version of" " dart\n"); return false; @@ -584,7 +588,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri, isolate = Dart_CreateIsolate(script_uri, main, - snapshot_buffer, + isolate_snapshot_buffer, isolate_data, error); @@ -594,7 +598,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri, Dart_EnterScope(); - if (snapshot_buffer != NULL) { + if (isolate_snapshot_buffer != NULL) { // Setup the native resolver as the snapshot does not carry it. Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); Builtin::SetNativeResolver(Builtin::kIOLibrary); @@ -964,7 +968,8 @@ void main(int argc, char** argv) { } // Initialize the Dart VM. - if (!Dart_Initialize(CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate, + if (!Dart_Initialize(vm_isolate_snapshot_buffer, + CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate, DartUtils::OpenFile, DartUtils::ReadFile, DartUtils::WriteFile, diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc index 9688457634e..f6bffe801a6 100644 --- a/runtime/bin/run_vm_tests.cc +++ b/runtime/bin/run_vm_tests.cc @@ -97,7 +97,8 @@ static int Main(int argc, const char** argv) { bool set_vm_flags_success = Flags::ProcessCommandLineFlags(dart_argc, dart_argv); ASSERT(set_vm_flags_success); - const char* err_msg = Dart::InitOnce(NULL, NULL, NULL, NULL, + const char* err_msg = Dart::InitOnce(NULL, + NULL, NULL, NULL, NULL, dart::bin::DartUtils::OpenFile, dart::bin::DartUtils::ReadFile, dart::bin::DartUtils::WriteFile, diff --git a/runtime/bin/snapshot_empty.cc b/runtime/bin/snapshot_empty.cc index f8c3f95ddc1..4fd42b3d045 100644 --- a/runtime/bin/snapshot_empty.cc +++ b/runtime/bin/snapshot_empty.cc @@ -17,7 +17,8 @@ typedef unsigned __int8 uint8_t; namespace dart { namespace bin { -const uint8_t* snapshot_buffer = NULL; +const uint8_t* vm_isolate_snapshot_buffer = NULL; +const uint8_t* isolate_snapshot_buffer = NULL; } // namespace bin } // namespace dart diff --git a/runtime/bin/snapshot_in.cc b/runtime/bin/snapshot_in.cc index 2e2a497f813..e2d67e95558 100644 --- a/runtime/bin/snapshot_in.cc +++ b/runtime/bin/snapshot_in.cc @@ -18,12 +18,23 @@ namespace dart { namespace bin { // The string on the next line will be filled in with the contents of the -// generated snapshot binary file. -// This string forms the content of a snapshot which is loaded in by dart. -static const uint8_t snapshot_buffer_[] = { +// generated snapshot binary file for the vm isolate. +// This string forms the content of a vm isolate snapshot which is loaded +// into the vm isolate. +static const uint8_t vm_isolate_snapshot_buffer_[] = { %s }; -const uint8_t* snapshot_buffer = snapshot_buffer_; +const uint8_t* vm_isolate_snapshot_buffer = vm_isolate_snapshot_buffer_; + + +// The string on the next line will be filled in with the contents of the +// generated snapshot binary file for a regular dart isolate. +// This string forms the content of a regular dart isolate snapshot which is +// loaded into an isolate when it is created. +static const uint8_t isolate_snapshot_buffer_[] = { + %s +}; +const uint8_t* isolate_snapshot_buffer = isolate_snapshot_buffer_; } // namespace bin } // namespace dart diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index 2d2dbc3e314..e940ea3aadb 100755 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -825,6 +825,8 @@ typedef bool (*Dart_EntropySource)(uint8_t* buffer, intptr_t length); /** * Initializes the VM. * + * \param vm_isolate_snapshot A buffer containing a snapshot of the VM isolate + * or NULL if no snapshot is provided. * \param create A function to be called during isolate creation. * See Dart_IsolateCreateCallback. * \param interrupt A function to be called when an isolate is interrupted. @@ -837,6 +839,7 @@ typedef bool (*Dart_EntropySource)(uint8_t* buffer, intptr_t length); * \return True if initialization is successful. */ DART_EXPORT bool Dart_Initialize( + const uint8_t* vm_isolate_snapshot, Dart_IsolateCreateCallback create, Dart_IsolateInterruptCallback interrupt, Dart_IsolateUnhandledExceptionCallback unhandled_exception, @@ -889,8 +892,8 @@ DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name); * Provided only for advisory purposes to improve debugging messages. * \param main The name of the main entry point this isolate will run. * Provided only for advisory purposes to improve debugging messages. - * \param snapshot A buffer containing a VM snapshot or NULL if no - * snapshot is provided. + * \param snapshot A buffer containing a snapshot of the isolate or + * NULL if no snapshot is provided. * \param callback_data Embedder data. This data will be passed to * the Dart_IsolateCreateCallback when new isolates are spawned from * this parent isolate. @@ -992,9 +995,10 @@ DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value); /** * Creates a full snapshot of the current isolate heap. * - * A full snapshot is a compact representation of the dart heap state and - * can be used for fast initialization of an isolate. A Snapshot of the heap - * can only be created before any dart code has executed. + * A full snapshot is a compact representation of the dart vm isolate heap + * and dart isolate heap states. These snapshots are used to initialize + * the vm isolate on startup and fast initialization of an isolate. + * A Snapshot of the heap is created before any dart code has executed. * * Requires there to be a current isolate. * @@ -1005,8 +1009,11 @@ DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value); * * \return A valid handle if no error occurs during the operation. */ -DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** buffer, - intptr_t* size); +DART_EXPORT Dart_Handle Dart_CreateSnapshot( + uint8_t** vm_isolate_snapshot_buffer, + intptr_t* vm_isolate_snapshot_size, + uint8_t** isolate_snapshot_buffer, + intptr_t* isolate_snapshot_size); /** * Creates a snapshot of the application script loaded in the isolate. diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py index 71b72e1e08d..19c29434b77 100755 --- a/runtime/tools/create_snapshot_bin.py +++ b/runtime/tools/create_snapshot_bin.py @@ -24,9 +24,14 @@ def BuildOptions(): result.add_option("--executable", action="store", type="string", help="path to snapshot generator executable") + result.add_option("--vm_output_bin", + action="store", type="string", + help="output file name into which vm isolate snapshot in binary form " + + "is generated") result.add_option("--output_bin", action="store", type="string", - help="output file name into which snapshot in binary form is generated") + help="output file name into which isolate snapshot in binary form " + + "is generated") result.add_option("--script", action="store", type="string", help="Dart script for which snapshot is to be generated") @@ -54,6 +59,9 @@ def ProcessOptions(options): if not options.executable: sys.stderr.write('--executable not specified\n') return False + if not options.vm_output_bin: + sys.stderr.write('--vm_output_bin not specified\n') + return False if not options.output_bin: sys.stderr.write('--output_bin not specified\n') return False @@ -83,8 +91,10 @@ def Main(): if options.package_root: script_args.append(''.join([ "--package_root=", options.package_root])) - # First setup the snapshot output filename. - script_args.append(''.join([ "--snapshot=", options.output_bin ])) + # First setup the vm isolate and regular isolate snapshot output filename. + script_args.append(''.join([ "--vm_isolate_snapshot=", + options.vm_output_bin ])) + script_args.append(''.join([ "--isolate_snapshot=", options.output_bin ])) # Next setup all url mapping options specified. for url_arg in options.url_mapping: diff --git a/runtime/tools/create_snapshot_file.py b/runtime/tools/create_snapshot_file.py index 98b3f82d1e1..d31cc067f1c 100755 --- a/runtime/tools/create_snapshot_file.py +++ b/runtime/tools/create_snapshot_file.py @@ -20,9 +20,12 @@ HOST_CPUS = utils.GuessCpus() def BuildOptions(): result = optparse.OptionParser() + result.add_option("--vm_input_bin", + action="store", type="string", + help="input file name of the vm isolate snapshot in binary form") result.add_option("--input_bin", action="store", type="string", - help="input file name of the snapshot in binary form") + help="input file name of the isolate snapshot in binary form") result.add_option("--input_cc", action="store", type="string", help="input file name which contains the C buffer template") @@ -36,6 +39,9 @@ def BuildOptions(): def ProcessOptions(options): + if not options.vm_input_bin: + sys.stderr.write('--vm_input_bin not specified\n') + return False if not options.input_bin: sys.stderr.write('--input_bin not specified\n') return False @@ -63,9 +69,11 @@ def makeString(input_file): return result -def makeFile(output_file, input_cc_file, input_file): +def makeFile(output_file, input_cc_file, + vm_isolate_input_file, isolate_input_file): snapshot_cc_text = open(input_cc_file).read() - snapshot_cc_text = snapshot_cc_text % makeString(input_file) + snapshot_cc_text = snapshot_cc_text % (makeString(vm_isolate_input_file), + makeString(isolate_input_file)) open(output_file, 'w').write(snapshot_cc_text) return True @@ -83,7 +91,8 @@ def Main(): parser.print_help() return 1 - if not makeFile(options.output, options.input_cc, options.input_bin): + if not makeFile(options.output, options.input_cc, + options.vm_input_bin, options.input_bin): print "Unable to generate snapshot in C buffer form" return -1 diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index 7527d48d97f..5d86284aae3 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -428,16 +428,19 @@ BENCHMARK_SIZE(CoreSnapshotSize) { "\n"; // Start an Isolate, load a script and create a full snapshot. - uint8_t* buffer; + uint8_t* vm_isolate_snapshot_buffer; + uint8_t* isolate_snapshot_buffer; // Need to load the script into the dart: core library due to // the import of dart:_internal. TestCase::LoadCoreTestScript(kScriptChars, NULL); Api::CheckAndFinalizePendingClasses(Isolate::Current()); // Write snapshot with object content. - FullSnapshotWriter writer(&buffer, &malloc_allocator); + FullSnapshotWriter writer(&vm_isolate_snapshot_buffer, + &isolate_snapshot_buffer, + &malloc_allocator); writer.WriteFullSnapshot(); - const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer); + const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer); ASSERT(snapshot->kind() == Snapshot::kFull); benchmark->set_score(snapshot->length()); } @@ -459,16 +462,19 @@ BENCHMARK_SIZE(StandaloneSnapshotSize) { "\n"; // Start an Isolate, load a script and create a full snapshot. - uint8_t* buffer; + uint8_t* vm_isolate_snapshot_buffer; + uint8_t* isolate_snapshot_buffer; // Need to load the script into the dart: core library due to // the import of dart:_internal. TestCase::LoadCoreTestScript(kScriptChars, NULL); Api::CheckAndFinalizePendingClasses(Isolate::Current()); // Write snapshot with object content. - FullSnapshotWriter writer(&buffer, &malloc_allocator); + FullSnapshotWriter writer(&vm_isolate_snapshot_buffer, + &isolate_snapshot_buffer, + &malloc_allocator); writer.WriteFullSnapshot(); - const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer); + const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer); ASSERT(snapshot->kind() == Snapshot::kFull); benchmark->set_score(snapshot->length()); } diff --git a/runtime/vm/benchmark_test.h b/runtime/vm/benchmark_test.h index 18ea0a5bc92..b26a13985aa 100644 --- a/runtime/vm/benchmark_test.h +++ b/runtime/vm/benchmark_test.h @@ -19,10 +19,14 @@ namespace dart { DECLARE_FLAG(int, code_heap_size); DECLARE_FLAG(int, old_gen_growth_space_ratio); -// snapshot_buffer points to a snapshot if we link in a snapshot otherwise -// it is initialized to NULL. namespace bin { -extern const uint8_t* snapshot_buffer; +// vm_isolate_snapshot_buffer points to a snapshot for the vm isolate if we +// link in a snapshot otherwise it is initialized to NULL. +extern const uint8_t* vm_isolate_snapshot_buffer; + +// isolate_snapshot_buffer points to a snapshot for an isolate if we link in a +// snapshot otherwise it is initialized to NULL. +extern const uint8_t* isolate_snapshot_buffer; } // The BENCHMARK macros are used for benchmarking a specific functionality @@ -109,7 +113,7 @@ class Benchmark { class BenchmarkIsolateScope { public: explicit BenchmarkIsolateScope(Benchmark* benchmark) : benchmark_(benchmark) { - benchmark_->CreateIsolate(bin::snapshot_buffer); + benchmark_->CreateIsolate(bin::isolate_snapshot_buffer); Dart_EnterScope(); // Create a Dart API scope for unit benchmarks. } ~BenchmarkIsolateScope() { diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index ffae666f23f..ef0b7f051a8 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -75,7 +75,8 @@ class ReadOnlyHandles { }; -const char* Dart::InitOnce(Dart_IsolateCreateCallback create, +const char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot, + Dart_IsolateCreateCallback create, Dart_IsolateInterruptCallback interrupt, Dart_IsolateUnhandledExceptionCallback unhandled, Dart_IsolateShutdownCallback shutdown, @@ -138,6 +139,10 @@ const char* Dart::InitOnce(Dart_IsolateCreateCallback create, return "SSE2 is required."; } #endif + if (vm_isolate_snapshot != NULL) { + // Initializing the VM isolate from a snapshot is not implemented yet. + USE(vm_isolate_snapshot); + } Object::FinalizeVMIsolate(vm_isolate_); } // There is a planned and known asymmetry here: We enter one scope for the VM diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h index 135c6b0a6cf..470b3ffd28b 100644 --- a/runtime/vm/dart.h +++ b/runtime/vm/dart.h @@ -20,6 +20,7 @@ class ThreadPool; class Dart : public AllStatic { public: static const char* InitOnce( + const uint8_t* vm_isolate_snapshot, Dart_IsolateCreateCallback create, Dart_IsolateInterruptCallback interrupt, Dart_IsolateUnhandledExceptionCallback unhandled, diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 6dd2be2c25f..eadd711704b 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -1200,6 +1200,7 @@ DART_EXPORT const char* Dart_VersionString() { } DART_EXPORT bool Dart_Initialize( + const uint8_t* vm_isolate_snapshot, Dart_IsolateCreateCallback create, Dart_IsolateInterruptCallback interrupt, Dart_IsolateUnhandledExceptionCallback unhandled, @@ -1209,7 +1210,8 @@ DART_EXPORT bool Dart_Initialize( Dart_FileWriteCallback file_write, Dart_FileCloseCallback file_close, Dart_EntropySource entropy_source) { - const char* err_msg = Dart::InitOnce(create, interrupt, unhandled, shutdown, + const char* err_msg = Dart::InitOnce(vm_isolate_snapshot, + create, interrupt, unhandled, shutdown, file_open, file_read, file_write, file_close, entropy_source); if (err_msg != NULL) { @@ -1408,16 +1410,25 @@ static uint8_t* ApiReallocate(uint8_t* ptr, } -DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** buffer, - intptr_t* size) { +DART_EXPORT Dart_Handle Dart_CreateSnapshot( + uint8_t** vm_isolate_snapshot_buffer, + intptr_t* vm_isolate_snapshot_size, + uint8_t** isolate_snapshot_buffer, + intptr_t* isolate_snapshot_size) { Isolate* isolate = Isolate::Current(); DARTSCOPE(isolate); TIMERSCOPE(isolate, time_creating_snapshot); - if (buffer == NULL) { - RETURN_NULL_ERROR(buffer); + if (vm_isolate_snapshot_buffer == NULL) { + RETURN_NULL_ERROR(vm_isolate_snapshot_buffer); } - if (size == NULL) { - RETURN_NULL_ERROR(size); + 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); } // Finalize all classes if needed. Dart_Handle state = Api::CheckAndFinalizePendingClasses(isolate); @@ -1426,9 +1437,12 @@ DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** buffer, } // Since this is only a snapshot the root library should not be set. isolate->object_store()->set_root_library(Library::Handle(isolate)); - FullSnapshotWriter writer(buffer, ApiReallocate); + FullSnapshotWriter writer(vm_isolate_snapshot_buffer, + isolate_snapshot_buffer, + ApiReallocate); writer.WriteFullSnapshot(); - *size = writer.BytesWritten(); + *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize(); + *isolate_snapshot_size = writer.IsolateSnapshotSize(); return Api::Success(); } diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc index fe7c5ea4f85..b91fb1223ab 100644 --- a/runtime/vm/dart_api_impl_test.cc +++ b/runtime/vm/dart_api_impl_test.cc @@ -3619,7 +3619,7 @@ UNIT_TEST_CASE(CurrentIsolateData) { intptr_t mydata = 12345; char* err; Dart_Isolate isolate = - Dart_CreateIsolate(NULL, NULL, bin::snapshot_buffer, + Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, reinterpret_cast(mydata), &err); EXPECT(isolate != NULL); @@ -7378,7 +7378,7 @@ void BusyLoop_start(uword unused) { MonitorLocker ml(sync); char* error = NULL; shared_isolate = Dart_CreateIsolate(NULL, NULL, - bin::snapshot_buffer, + bin::isolate_snapshot_buffer, NULL, &error); EXPECT(shared_isolate != NULL); Dart_EnterScope(); @@ -7506,7 +7506,7 @@ UNIT_TEST_CASE(IsolateShutdown) { // Create an isolate. char* err; Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, - bin::snapshot_buffer, + bin::isolate_snapshot_buffer, my_data, &err); if (isolate == NULL) { OS::Print("Creation of isolate failed '%s'\n", err); @@ -7556,7 +7556,7 @@ UNIT_TEST_CASE(IsolateShutdownRunDartCode) { // Create an isolate. char* err; Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, - bin::snapshot_buffer, + bin::isolate_snapshot_buffer, NULL, &err); if (isolate == NULL) { OS::Print("Creation of isolate failed '%s'\n", err); diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index 37a6d1ebf5e..95393629d91 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -677,9 +677,16 @@ class SnapshotWriter : public BaseWriter { class FullSnapshotWriter : public SnapshotWriter { public: static const intptr_t kInitialSize = 64 * KB; - FullSnapshotWriter(uint8_t** buffer, ReAlloc alloc) - : SnapshotWriter(Snapshot::kFull, buffer, alloc, kInitialSize, true) { - ASSERT(buffer != NULL); + FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, + uint8_t** isolate_snapshot_buffer, + ReAlloc alloc) + : SnapshotWriter(Snapshot::kFull, + isolate_snapshot_buffer, + alloc, + kInitialSize, + true) { + ASSERT(vm_isolate_snapshot_buffer != NULL); + ASSERT(isolate_snapshot_buffer != NULL); ASSERT(alloc != NULL); } ~FullSnapshotWriter() { } @@ -687,6 +694,9 @@ class FullSnapshotWriter : public SnapshotWriter { // Writes a full snapshot of the Isolate. void WriteFullSnapshot(); + intptr_t VmIsolateSnapshotSize() const { return 0; } + intptr_t IsolateSnapshotSize() const { return BytesWritten(); } + private: DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter); }; diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 94d6d08d3fa..965772a34d0 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -1029,7 +1029,8 @@ UNIT_TEST_CASE(FullSnapshot) { "}\n"; Dart_Handle result; - uint8_t* buffer; + uint8_t* vm_isolate_snapshot_buffer; + uint8_t* isolate_snapshot_buffer; // Start an Isolate, load a script and create a full snapshot. Timer timer1(true, "Snapshot_test"); @@ -1048,7 +1049,9 @@ UNIT_TEST_CASE(FullSnapshot) { OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime()); // Write snapshot with object content. - FullSnapshotWriter writer(&buffer, &malloc_allocator); + FullSnapshotWriter writer(&vm_isolate_snapshot_buffer, + &isolate_snapshot_buffer, + &malloc_allocator); writer.WriteFullSnapshot(); } @@ -1056,7 +1059,7 @@ UNIT_TEST_CASE(FullSnapshot) { // from the script. Timer timer2(true, "Snapshot_test"); timer2.Start(); - TestCase::CreateTestIsolateFromSnapshot(buffer); + TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_buffer); { Dart_EnterScope(); // Start a Dart API scope for invoking API functions. timer2.Stop(); @@ -1070,7 +1073,7 @@ UNIT_TEST_CASE(FullSnapshot) { Dart_ExitScope(); } Dart_ShutdownIsolate(); - free(buffer); + free(isolate_snapshot_buffer); } @@ -1083,7 +1086,8 @@ UNIT_TEST_CASE(FullSnapshot1) { }; const char* kScriptChars = kFullSnapshotScriptChars; - uint8_t* buffer; + uint8_t* vm_isolate_snapshot_buffer; + uint8_t* isolate_snapshot_buffer; // Start an Isolate, load a script and create a full snapshot. Timer timer1(true, "Snapshot_test"); @@ -1102,7 +1106,9 @@ UNIT_TEST_CASE(FullSnapshot1) { OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime()); // Write snapshot with object content. - FullSnapshotWriter writer(&buffer, &malloc_allocator); + FullSnapshotWriter writer(&vm_isolate_snapshot_buffer, + &isolate_snapshot_buffer, + &malloc_allocator); writer.WriteFullSnapshot(); // Invoke a function which returns an object. @@ -1115,7 +1121,7 @@ UNIT_TEST_CASE(FullSnapshot1) { // from the script. Timer timer2(true, "Snapshot_test"); timer2.Start(); - TestCase::CreateTestIsolateFromSnapshot(buffer); + TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_buffer); { Dart_EnterScope(); // Start a Dart API scope for invoking API functions. timer2.Stop(); @@ -1133,7 +1139,7 @@ UNIT_TEST_CASE(FullSnapshot1) { Dart_ExitScope(); } Dart_ShutdownIsolate(); - free(buffer); + free(isolate_snapshot_buffer); } @@ -1183,6 +1189,10 @@ UNIT_TEST_CASE(ScriptSnapshot) { uint8_t* buffer; intptr_t size; + uint8_t* vm_isolate_snapshot = NULL; + intptr_t vm_isolate_snapshot_size; + uint8_t* isolate_snapshot = NULL; + intptr_t isolate_snapshot_size; uint8_t* full_snapshot = NULL; uint8_t* script_snapshot = NULL; intptr_t expected_num_libs; @@ -1194,10 +1204,13 @@ UNIT_TEST_CASE(ScriptSnapshot) { Dart_EnterScope(); // Start a Dart API scope for invoking API functions. // Write out the script snapshot. - result = Dart_CreateSnapshot(&buffer, &size); + result = Dart_CreateSnapshot(&vm_isolate_snapshot, + &vm_isolate_snapshot_size, + &isolate_snapshot, + &isolate_snapshot_size); EXPECT_VALID(result); - full_snapshot = reinterpret_cast(malloc(size)); - memmove(full_snapshot, buffer, size); + full_snapshot = reinterpret_cast(malloc(isolate_snapshot_size)); + memmove(full_snapshot, isolate_snapshot, isolate_snapshot_size); Dart_ExitScope(); } @@ -1275,6 +1288,10 @@ UNIT_TEST_CASE(ScriptSnapshot1) { Dart_Handle result; uint8_t* buffer; intptr_t size; + uint8_t* vm_isolate_snapshot = NULL; + intptr_t vm_isolate_snapshot_size; + uint8_t* isolate_snapshot = NULL; + intptr_t isolate_snapshot_size; uint8_t* full_snapshot = NULL; uint8_t* script_snapshot = NULL; @@ -1284,10 +1301,13 @@ UNIT_TEST_CASE(ScriptSnapshot1) { Dart_EnterScope(); // Start a Dart API scope for invoking API functions. // Write out the script snapshot. - result = Dart_CreateSnapshot(&buffer, &size); + result = Dart_CreateSnapshot(&vm_isolate_snapshot, + &vm_isolate_snapshot_size, + &isolate_snapshot, + &isolate_snapshot_size); EXPECT_VALID(result); - full_snapshot = reinterpret_cast(malloc(size)); - memmove(full_snapshot, buffer, size); + full_snapshot = reinterpret_cast(malloc(isolate_snapshot_size)); + memmove(full_snapshot, isolate_snapshot, isolate_snapshot_size); Dart_ExitScope(); } @@ -1352,6 +1372,10 @@ UNIT_TEST_CASE(ScriptSnapshot2) { uint8_t* buffer; intptr_t size; + uint8_t* vm_isolate_snapshot = NULL; + intptr_t vm_isolate_snapshot_size; + uint8_t* isolate_snapshot = NULL; + intptr_t isolate_snapshot_size; uint8_t* full_snapshot = NULL; uint8_t* script_snapshot = NULL; @@ -1365,10 +1389,13 @@ UNIT_TEST_CASE(ScriptSnapshot2) { Dart_EnterScope(); // Start a Dart API scope for invoking API functions. // Write out the script snapshot. - result = Dart_CreateSnapshot(&buffer, &size); + result = Dart_CreateSnapshot(&vm_isolate_snapshot, + &vm_isolate_snapshot_size, + &isolate_snapshot, + &isolate_snapshot_size); EXPECT_VALID(result); - full_snapshot = reinterpret_cast(malloc(size)); - memmove(full_snapshot, buffer, size); + full_snapshot = reinterpret_cast(malloc(isolate_snapshot_size)); + memmove(full_snapshot, isolate_snapshot, isolate_snapshot_size); Dart_ExitScope(); } diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h index 41695eda70c..e554b5af2e0 100644 --- a/runtime/vm/unit_test.h +++ b/runtime/vm/unit_test.h @@ -217,10 +217,14 @@ class CodeGenerator; class VirtualMemory; -// snapshot_buffer points to a snapshot if we link in a snapshot otherwise -// it is initialized to NULL. namespace bin { -extern const uint8_t* snapshot_buffer; +// vm_isolate_snapshot_buffer points to a snapshot for the vm isolate if we +// link in a snapshot otherwise it is initialized to NULL. +extern const uint8_t* vm_isolate_snapshot_buffer; + +// isolate_snapshot_buffer points to a snapshot for an isolate if we link in a +// snapshot otherwise it is initialized to NULL. +extern const uint8_t* isolate_snapshot_buffer; } @@ -269,7 +273,7 @@ class TestCase : TestCaseBase { return CreateIsolate(buffer, name); } static Dart_Isolate CreateTestIsolate(const char* name = NULL) { - return CreateIsolate(bin::snapshot_buffer, name); + return CreateIsolate(bin::isolate_snapshot_buffer, name); } static Dart_Handle library_handler(Dart_LibraryTag tag, Dart_Handle library,