Support spawnUri in app snapshots.

Fixes #28368

R=asiva@google.com

Review-Url: https://codereview.chromium.org/2628283002 .
This commit is contained in:
Ryan Macnak 2017-01-13 10:37:51 -08:00
parent c5b994750e
commit 593d4504b0
17 changed files with 88 additions and 93 deletions

View file

@ -40,7 +40,8 @@ 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;
extern const uint8_t* const core_isolate_snapshot_buffer;
/**
* Global state used to control and store generation of application snapshots
@ -51,7 +52,7 @@ extern const uint8_t* isolate_snapshot_buffer;
* To Run the application snapshot generated above, use :
* dart <app_snapshot_filename> [<script_options>]
*/
static bool run_app_snapshot = false;
static bool vm_run_app_snapshot = false;
static const char* snapshot_filename = NULL;
enum SnapshotKind {
kNone,
@ -108,6 +109,10 @@ extern const char* kPrecompiledDataSymbolName;
static bool trace_loading = false;
static char* app_script_uri = NULL;
static const uint8_t* app_isolate_snapshot_buffer = NULL;
static Dart_Isolate main_isolate = NULL;
@ -723,7 +728,7 @@ static int ParseArguments(int argc,
Log::PrintErr("Generating a snapshot requires a filename (--snapshot).\n");
return -1;
}
if ((gen_snapshot_kind != kNone) && run_app_snapshot) {
if ((gen_snapshot_kind != kNone) && vm_run_app_snapshot) {
Log::PrintErr(
"Specifying an option to generate a snapshot and"
" run using a snapshot is invalid.\n");
@ -807,7 +812,8 @@ static void SnapshotOnExitHook(int64_t exit_code);
// Returns true on success, false on failure.
static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
const char* script_uri,
const char* main,
const char* package_root,
const char* packages_config,
@ -826,12 +832,29 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
}
}
#if defined(DART_PRECOMPILED_RUNTIME)
// AOT: All isolates start from the app snapshot.
bool isolate_run_app_snapshot = true;
const uint8_t* isolate_snapshot_buffer = app_isolate_snapshot_buffer;
#else
// JIT: Main isolate starts from the app snapshot, if any. Other use the
// core libraries snapshot.
bool isolate_run_app_snapshot = false;
const uint8_t* isolate_snapshot_buffer = core_isolate_snapshot_buffer;
if ((app_isolate_snapshot_buffer != NULL) &&
(is_main_isolate || ((app_script_uri != NULL) &&
(strcmp(script_uri, app_script_uri) == 0)))) {
isolate_run_app_snapshot = true;
isolate_snapshot_buffer = app_isolate_snapshot_buffer;
}
#endif
// If the script is a Kernel binary, then we will try to bootstrap from the
// script.
const uint8_t* kernel_file = NULL;
intptr_t kernel_length = -1;
const bool is_kernel =
!run_app_snapshot &&
!isolate_run_app_snapshot &&
TryReadKernel(script_uri, &kernel_file, &kernel_length);
void* kernel_program = NULL;
@ -867,14 +890,14 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
Builtin::SetNativeResolver(Builtin::kIOLibrary);
}
if (run_app_snapshot) {
if (isolate_run_app_snapshot) {
Dart_Handle result = Loader::ReloadNativeExtensions();
CHECK_RESULT(result);
}
if (Dart_IsServiceIsolate(isolate)) {
// If this is the service isolate, load embedder specific bits and return.
bool skip_library_load = run_app_snapshot;
bool skip_library_load = isolate_run_app_snapshot;
if (!VmService::Setup(vm_service_server_ip, vm_service_server_port,
skip_library_load, vm_service_dev_mode)) {
*error = strdup(VmService::GetErrorMessage());
@ -923,10 +946,23 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
}
}
if (run_app_snapshot) {
if (isolate_run_app_snapshot) {
result = DartUtils::SetupIOLibrary(script_uri);
CHECK_RESULT(result);
Loader::InitForSnapshot(script_uri);
#if !defined(DART_PRECOMPILED_RUNTIME)
if (is_main_isolate) {
// Find the canonical uri of the app snapshot. We'll use this to decide if
// other isolates should use the app snapshot or the core snapshot.
const char* resolved_script_uri = NULL;
result = Dart_StringToCString(
DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri)),
&resolved_script_uri);
CHECK_RESULT(result);
ASSERT(app_script_uri == NULL);
app_script_uri = strdup(resolved_script_uri);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
} else {
// Load the specified application script into the newly created isolate.
Dart_Handle uri =
@ -979,9 +1015,11 @@ static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
return NULL;
}
bool is_main_isolate = false;
int exit_code = 0;
return CreateIsolateAndSetupHelper(script_uri, main, package_root,
package_config, flags, error, &exit_code);
return CreateIsolateAndSetupHelper(is_main_isolate, script_uri, main,
package_root, package_config, flags, error,
&exit_code);
}
@ -1572,11 +1610,12 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
// Call CreateIsolateAndSetup which creates an isolate and loads up
// the specified application script.
char* error = NULL;
bool is_main_isolate = true;
int exit_code = 0;
char* isolate_name = BuildIsolateName(script_name, "main");
Dart_Isolate isolate = CreateIsolateAndSetupHelper(
script_name, "main", commandline_package_root, commandline_packages_file,
NULL, &error, &exit_code);
is_main_isolate, script_name, "main", commandline_package_root,
commandline_packages_file, NULL, &error, &exit_code);
if (isolate == NULL) {
delete[] isolate_name;
if (exit_code == kRestartRequestExitCode) {
@ -1902,16 +1941,15 @@ void main(int argc, char** argv) {
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,
&app_isolate_snapshot_buffer, &instructions_snapshot,
&data_snapshot)) {
run_app_snapshot = true;
vm_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) {
if ((gen_snapshot_kind != kNone) || vm_run_app_snapshot) {
vm_options.AddArgument("--load_deferred_eagerly");
}
#endif
@ -1983,6 +2021,8 @@ void main(int argc, char** argv) {
}
EventHandler::Stop();
free(app_script_uri);
// Free copied argument strings if converted.
if (argv_converted) {
for (int i = 0; i < argc; i++) {

View file

@ -17,7 +17,7 @@ namespace dart {
namespace bin {
const uint8_t* vm_isolate_snapshot_buffer = NULL;
const uint8_t* isolate_snapshot_buffer = NULL;
const uint8_t* core_isolate_snapshot_buffer = NULL;
} // namespace bin
} // namespace dart

View file

@ -32,10 +32,10 @@ const uint8_t* vm_isolate_snapshot_buffer = vm_isolate_snapshot_buffer_;
// 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_[] = {
static const uint8_t core_isolate_snapshot_buffer_[] = {
%s
};
const uint8_t* isolate_snapshot_buffer = isolate_snapshot_buffer_;
const uint8_t* core_isolate_snapshot_buffer = core_isolate_snapshot_buffer_;
} // namespace bin
} // namespace dart

View file

@ -340,10 +340,11 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) {
GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
if (Snapshot::IncludesCode(Dart::snapshot_kind())) {
if (Dart::snapshot_kind() == Snapshot::kAppAOT) {
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, String::Handle(String::New(
"Isolate.spawnUri not supported under precompilation")));
args.SetAt(
0, String::Handle(String::New(
"Isolate.spawnUri not supported when using AOT compilation")));
Exceptions::ThrowByType(Exceptions::kUnsupported, args);
UNREACHABLE();
}

View file

@ -56,7 +56,6 @@ developer_extension_test: Pass, Fail # Issue 27225
address_mapper_test: CompileTimeError # Issue 27806
capture_stdio_test: CompileTimeError # Issue 27806
complex_reload_test: RuntimeError # Issue 27806
dev_fs_spawn_test: RuntimeError # Issue 27806
developer_extension_test: RuntimeError # Issue 27806
evaluate_activation_test/instance: RuntimeError # Issue 27806
evaluate_activation_test/scope: RuntimeError # Issue 27806

View file

@ -256,9 +256,9 @@ cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
# StackTraces in precompilation omit inlined frames.
dart/inline_stack_frame_test: Pass, RuntimeError
dart/optimized_stacktrace_test: Pass, RuntimeError
dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
[ $compiler == app_jit || $compiler == precompiler ]
dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
dart/optimized_stacktrace_test: SkipByDesign # Requires line numbers
[ $runtime == vm && $mode == product ]

View file

@ -26,7 +26,7 @@ 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;
extern const uint8_t* const core_isolate_snapshot_buffer;
}
// The BENCHMARK macros are used for benchmarking a specific functionality
@ -110,7 +110,7 @@ class Benchmark {
class BenchmarkIsolateScope {
public:
explicit BenchmarkIsolateScope(Benchmark* benchmark) : benchmark_(benchmark) {
benchmark_->CreateIsolate(bin::isolate_snapshot_buffer);
benchmark_->CreateIsolate(bin::core_isolate_snapshot_buffer);
Dart_EnterScope(); // Create a Dart API scope for unit benchmarks.
}
~BenchmarkIsolateScope() {

View file

@ -3497,7 +3497,7 @@ UNIT_TEST_CASE(CurrentIsolateData) {
intptr_t mydata = 12345;
char* err;
Dart_Isolate isolate =
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL,
reinterpret_cast<void*>(mydata), &err);
EXPECT(isolate != NULL);
EXPECT_EQ(mydata, reinterpret_cast<intptr_t>(Dart_CurrentIsolateData()));
@ -3528,7 +3528,7 @@ UNIT_TEST_CASE(IsolateSetCheckedMode) {
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(
NULL, NULL, bin::isolate_snapshot_buffer, &api_flags, NULL, &err);
NULL, NULL, bin::core_isolate_snapshot_buffer, &api_flags, NULL, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);
free(err);
@ -7573,7 +7573,7 @@ void BusyLoop_start(uword unused) {
MonitorLocker ml(sync);
char* error = NULL;
shared_isolate = Dart_CreateIsolate(
NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, &error);
NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL, &error);
EXPECT(shared_isolate != NULL);
Dart_EnterScope();
Dart_Handle url = NewString(TestCase::url());
@ -7624,7 +7624,7 @@ UNIT_TEST_CASE(IsolateShutdown) {
// Create an isolate.
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(
NULL, NULL, bin::isolate_snapshot_buffer, NULL, my_data, &err);
NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, my_data, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);
free(err);
@ -7673,7 +7673,7 @@ UNIT_TEST_CASE(IsolateShutdownRunDartCode) {
// Create an isolate.
char* err;
Dart_Isolate isolate = Dart_CreateIsolate(
NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, &err);
NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL, &err);
if (isolate == NULL) {
OS::Print("Creation of isolate failed '%s'\n", err);
free(err);

View file

@ -15,7 +15,7 @@ namespace dart {
UNIT_TEST_CASE(IsolateCurrent) {
Dart_Isolate isolate = Dart_CreateIsolate(
NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL);
NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL, NULL);
EXPECT_EQ(isolate, Dart_CurrentIsolate());
Dart_ShutdownIsolate();
EXPECT_EQ(reinterpret_cast<Dart_Isolate>(NULL), Dart_CurrentIsolate());

View file

@ -16,7 +16,7 @@ namespace dart {
#ifndef PRODUCT
UNIT_TEST_CASE(Metric_Simple) {
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
{
Metric metric;
@ -45,7 +45,7 @@ class MyMetric : public Metric {
};
UNIT_TEST_CASE(Metric_OnDemand) {
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
{
Thread* thread = Thread::Current();

View file

@ -15,7 +15,7 @@ namespace dart {
UNIT_TEST_CASE(Mutex) {
// This unit test case needs a running isolate.
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Mutex* mutex = new Mutex();
@ -37,7 +37,7 @@ UNIT_TEST_CASE(Mutex) {
UNIT_TEST_CASE(Monitor) {
// This unit test case needs a running isolate.
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
OSThread* thread = OSThread::Current();
// Thread interrupter interferes with this test, disable interrupts.
@ -389,13 +389,13 @@ TEST_CASE(ThreadRegistry) {
char* orig_str = orig_zone->PrintToString("foo");
Dart_ExitIsolate();
// Create and enter a new isolate.
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Zone* zone0 = Thread::Current()->zone();
EXPECT(zone0 != orig_zone);
Dart_ShutdownIsolate();
// Create and enter yet another isolate.
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
{
// Create a stack resource this time, and exercise it.

View file

@ -247,7 +247,7 @@ 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;
extern const uint8_t* const core_isolate_snapshot_buffer;
}
@ -295,7 +295,7 @@ class TestCase : TestCaseBase {
return CreateIsolate(buffer, name);
}
static Dart_Isolate CreateTestIsolate(const char* name = NULL) {
return CreateIsolate(bin::isolate_snapshot_buffer, name);
return CreateIsolate(bin::core_isolate_snapshot_buffer, name);
}
static Dart_Handle library_handler(Dart_LibraryTag tag,
Dart_Handle library,

View file

@ -14,7 +14,7 @@ UNIT_TEST_CASE(AllocateZone) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Thread* thread = Thread::Current();
EXPECT(thread->zone() == NULL);
@ -76,7 +76,7 @@ UNIT_TEST_CASE(AllocGeneric_Success) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Thread* thread = Thread::Current();
EXPECT(thread->zone() == NULL);
@ -100,7 +100,7 @@ UNIT_TEST_CASE(AllocGeneric_Overflow) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Thread* thread = Thread::Current();
EXPECT(thread->zone() == NULL);
@ -119,7 +119,7 @@ UNIT_TEST_CASE(ZoneAllocated) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Thread* thread = Thread::Current();
EXPECT(thread->zone() == NULL);
@ -175,7 +175,7 @@ UNIT_TEST_CASE(PrintZoneMemoryInfoToJSON) {
#if defined(DEBUG)
FLAG_trace_zones = true;
#endif
Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL,
Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_buffer, NULL, NULL,
NULL);
Thread* thread = Thread::Current();
EXPECT(thread->zone() == NULL);

View file

@ -293,7 +293,7 @@ Language/Libraries_and_Scripts/Imports/deferred_import_t02: Skip # Eager loading
Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: Skip # Eager loading
Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: Skip # Eager loading
[ $runtime == dart_precompiled || $compiler == app_jit ]
[ $runtime == dart_precompiled ]
LibTest/isolate/Isolate/spawnUri*: SkipByDesign # Isolate.spawnUri
[ $compiler == precompiler ]

View file

@ -197,7 +197,7 @@ stacktrace_message_test: SkipByDesign
static_function_test: SkipByDesign
unresolved_ports_test: SkipByDesign
[ $runtime == dart_precompiled || $compiler == app_jit ]
[ $runtime == dart_precompiled ]
count_test: Skip # Isolate.spawnUri
cross_isolate_message_test: Skip # Isolate.spawnUri
deferred_in_isolate2_test: Skip # Isolate.spawnUri

View file

@ -49,48 +49,3 @@ template("application_snapshot") {
] + training_args
}
}
# TODO(28368): Revert to application snapshot after spawnUri issue is fixed.
template("script_snapshot") {
assert(defined(invoker.main_dart), "Must specify 'main_dart'")
assert(defined(invoker.training_args), "Must specify 'training_args'")
main_dart = invoker.main_dart
training_args = invoker.training_args
name = target_name
if (defined(invoker.name)) {
name = invoker.name
}
extra_deps = []
if (defined(invoker.deps)) {
extra_deps += invoker.deps
}
extra_inputs = []
if (defined(invoker.inputs)) {
extra_inputs += invoker.inputs
}
compiled_action(target_name) {
tool = get_path_info("$_dart_root/runtime/bin:dart", "abspath")
deps = extra_deps + [ "$_dart_root/pkg:pkg_files_stamp" ]
inputs = extra_inputs + [
"$_dart_root/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart",
"$root_gen_dir/pkg_files.stamp",
]
output = "$root_gen_dir/$name.dart.snapshot"
outputs = [
output,
]
dot_packages = rebase_path("$_dart_root/.packages")
abs_output = rebase_path(output)
main_file = rebase_path(main_dart)
args = [
"--packages=$dot_packages",
"--snapshot=$abs_output",
"--snapshot-kind=script",
main_file,
] + training_args
}
}

View file

@ -4,7 +4,7 @@
import("../application_snapshot.gni")
script_snapshot("pub") {
application_snapshot("pub") {
main_dart = "../../third_party/pkg/pub/bin/pub.dart"
training_args = [ "--help" ]
deps = [