[ VM / CLI ] Run DartDev isolate from snapshot when possible
This change tries to run from dartdev.dart.snapshot and falls back to running from dartdev.dill if incompatible VM flags are provided. Fixes https://github.com/dart-lang/sdk/issues/43969 Performance results: dart test.dart (no CLI isolate): 0.167s dart run test (from snapshot): 0.208s dart run test (from kernel): 0.326s TEST=pkg/dartdev/test/load_from_dill_test.dart Change-Id: I3195886b86676580ef2a0221f0284328964ef061 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178300 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
9d1a307954
commit
c42c76f590
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
void main() {
|
||||
TestProject p;
|
||||
|
||||
tearDown(() => p?.dispose());
|
||||
|
||||
test("Fallback to dartdev.dill from dartdev.dart.snapshot for 'Hello World'",
|
||||
() {
|
||||
p = project(mainSrc: "void main() { print('Hello World'); }");
|
||||
// The DartDev snapshot includes the --use-bare-instructions flag. If
|
||||
// --no-use-bare-instructions is passed, the VM will fail to load the
|
||||
// snapshot and should fall back to using the DartDev dill file.
|
||||
ProcessResult result =
|
||||
p.runSync(['--no-use-bare-instructions', 'run', p.relativeFilePath]);
|
||||
|
||||
expect(result.stdout, contains('Hello World'));
|
||||
expect(result.stderr, isEmpty);
|
||||
expect(result.exitCode, 0);
|
||||
});
|
||||
}
|
||||
@@ -57,13 +57,14 @@ bool DartDevIsolate::ShouldParseCommand(const char* script_uri) {
|
||||
(strncmp(script_uri, "google3://", 10) != 0));
|
||||
}
|
||||
|
||||
Utils::CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
|
||||
Utils::CStringUniquePtr DartDevIsolate::TryResolveArtifactPath(
|
||||
const char* filename) {
|
||||
// |dir_prefix| includes the last path seperator.
|
||||
auto dir_prefix = EXEUtils::GetDirectoryPrefixFromExeName();
|
||||
|
||||
// First assume we're in dart-sdk/bin.
|
||||
char* snapshot_path =
|
||||
Utils::SCreate("%ssnapshots/dartdev.dill", dir_prefix.get());
|
||||
Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
|
||||
if (File::Exists(nullptr, snapshot_path)) {
|
||||
return Utils::CreateCStringUniquePtr(snapshot_path);
|
||||
}
|
||||
@@ -71,7 +72,7 @@ Utils::CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
|
||||
|
||||
// If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
|
||||
// directories. Try to use a snapshot from a previously built SDK.
|
||||
snapshot_path = Utils::SCreate("%sdartdev.dill", dir_prefix.get());
|
||||
snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
|
||||
if (File::Exists(nullptr, snapshot_path)) {
|
||||
return Utils::CreateCStringUniquePtr(snapshot_path);
|
||||
}
|
||||
@@ -79,6 +80,14 @@ Utils::CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
|
||||
return Utils::CreateCStringUniquePtr(nullptr);
|
||||
}
|
||||
|
||||
Utils::CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
|
||||
return TryResolveArtifactPath("dartdev.dart.snapshot");
|
||||
}
|
||||
|
||||
Utils::CStringUniquePtr DartDevIsolate::TryResolveDartDevKernelPath() {
|
||||
return TryResolveArtifactPath("dartdev.dill");
|
||||
}
|
||||
|
||||
void DartDevIsolate::DartDevRunner::Run(
|
||||
Dart_IsolateGroupCreateCallback create_isolate,
|
||||
char** packages_file,
|
||||
|
||||
@@ -41,8 +41,10 @@ class DartDevIsolate {
|
||||
|
||||
static bool should_run_dart_dev() { return should_run_dart_dev_; }
|
||||
|
||||
// Attempts to find the DartDev snapshot. If the snapshot cannot be found,
|
||||
// the VM will shutdown.
|
||||
// Attempts to find the path of the DartDev kernel file.
|
||||
static Utils::CStringUniquePtr TryResolveDartDevKernelPath();
|
||||
|
||||
// Attempts to find the path of the DartDev snapshot.
|
||||
static Utils::CStringUniquePtr TryResolveDartDevSnapshotPath();
|
||||
|
||||
// Starts a DartDev instance in a new isolate and runs it to completion.
|
||||
@@ -89,6 +91,8 @@ class DartDevIsolate {
|
||||
};
|
||||
|
||||
private:
|
||||
static Utils::CStringUniquePtr TryResolveArtifactPath(const char* filename);
|
||||
|
||||
static DartDevRunner runner_;
|
||||
static bool should_run_dart_dev_;
|
||||
|
||||
|
||||
+56
-20
@@ -584,40 +584,76 @@ static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
|
||||
int64_t start = Dart_TimelineGetMicros();
|
||||
|
||||
auto dartdev_path = DartDevIsolate::TryResolveDartDevSnapshotPath();
|
||||
if (dartdev_path == nullptr) {
|
||||
*error = Utils::StrDup("Unable to find DartDev snapshot");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Dart_Isolate isolate = nullptr;
|
||||
const uint8_t* isolate_snapshot_data = core_isolate_snapshot_data;
|
||||
const uint8_t* isolate_snapshot_instructions =
|
||||
core_isolate_snapshot_instructions;
|
||||
IsolateGroupData* isolate_group_data = nullptr;
|
||||
IsolateData* isolate_data = nullptr;
|
||||
|
||||
auto isolate_group_data =
|
||||
new IsolateGroupData(DART_DEV_ISOLATE_NAME, packages_config, nullptr,
|
||||
/*isolate_run_app_snapshot*/ false);
|
||||
uint8_t* application_kernel_buffer = NULL;
|
||||
intptr_t application_kernel_buffer_size = 0;
|
||||
dfe.ReadScript(dartdev_path.get(), &application_kernel_buffer,
|
||||
&application_kernel_buffer_size);
|
||||
isolate_group_data->SetKernelBufferNewlyOwned(application_kernel_buffer,
|
||||
application_kernel_buffer_size);
|
||||
AppSnapshot* app_snapshot;
|
||||
bool isolate_run_app_snapshot = true;
|
||||
if (dartdev_path.get() != nullptr &&
|
||||
(app_snapshot = Snapshot::TryReadAppSnapshot(dartdev_path.get())) !=
|
||||
nullptr) {
|
||||
const uint8_t* isolate_snapshot_data = NULL;
|
||||
const uint8_t* isolate_snapshot_instructions = NULL;
|
||||
const uint8_t* ignore_vm_snapshot_data;
|
||||
const uint8_t* ignore_vm_snapshot_instructions;
|
||||
app_snapshot->SetBuffers(
|
||||
&ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
|
||||
&isolate_snapshot_data, &isolate_snapshot_instructions);
|
||||
isolate_group_data =
|
||||
new IsolateGroupData(dartdev_path.get(), packages_config, app_snapshot,
|
||||
isolate_run_app_snapshot);
|
||||
isolate_data = new IsolateData(isolate_group_data);
|
||||
isolate = Dart_CreateIsolateGroup(
|
||||
DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
|
||||
isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
|
||||
error);
|
||||
}
|
||||
|
||||
auto isolate_data = new IsolateData(isolate_group_data);
|
||||
Dart_Isolate isolate = nullptr;
|
||||
isolate = Dart_CreateIsolateGroup(
|
||||
DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
|
||||
isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
|
||||
error);
|
||||
if (isolate == nullptr) {
|
||||
isolate_run_app_snapshot = false;
|
||||
dartdev_path = DartDevIsolate::TryResolveDartDevKernelPath();
|
||||
// Clear error from app snapshot and retry from kernel.
|
||||
free(*error);
|
||||
*error = nullptr;
|
||||
|
||||
if (app_snapshot != nullptr) {
|
||||
delete app_snapshot;
|
||||
}
|
||||
|
||||
if (dartdev_path.get() != nullptr) {
|
||||
isolate_group_data =
|
||||
new IsolateGroupData(DART_DEV_ISOLATE_NAME, packages_config, nullptr,
|
||||
isolate_run_app_snapshot);
|
||||
uint8_t* application_kernel_buffer = NULL;
|
||||
intptr_t application_kernel_buffer_size = 0;
|
||||
dfe.ReadScript(dartdev_path.get(), &application_kernel_buffer,
|
||||
&application_kernel_buffer_size);
|
||||
isolate_group_data->SetKernelBufferNewlyOwned(
|
||||
application_kernel_buffer, application_kernel_buffer_size);
|
||||
|
||||
isolate_data = new IsolateData(isolate_group_data);
|
||||
isolate = Dart_CreateIsolateGroup(
|
||||
DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
|
||||
isolate_snapshot_instructions, flags, isolate_group_data,
|
||||
isolate_data, error);
|
||||
}
|
||||
}
|
||||
|
||||
Dart_Isolate created_isolate = nullptr;
|
||||
if (isolate == nullptr) {
|
||||
Syslog::PrintErr("Failed to start the Dart CLI isolate\n");
|
||||
delete isolate_data;
|
||||
delete isolate_group_data;
|
||||
return nullptr;
|
||||
} else {
|
||||
created_isolate = IsolateSetupHelper(
|
||||
isolate, false, DART_DEV_ISOLATE_NAME, packages_config,
|
||||
/*isolate_run_app_snapshot*/ false, flags, error, exit_code);
|
||||
isolate_run_app_snapshot, flags, error, exit_code);
|
||||
}
|
||||
int64_t end = Dart_TimelineGetMicros();
|
||||
Dart_TimelineEvent("CreateAndSetupDartDevIsolate", start, end,
|
||||
|
||||
@@ -48,6 +48,7 @@ declare_args() {
|
||||
# ........dart2js.dart.snapshot
|
||||
# ........dart2native.dart.snapshot (if not on ia32)
|
||||
# ........dartanalyzer.dart.snapshot
|
||||
# ........dartdev.dart.snapshot
|
||||
# ........dartdev.dill
|
||||
# ........dartdevc.dart.snapshot
|
||||
# ........dartdoc.dart.snapshot
|
||||
@@ -117,6 +118,10 @@ _platform_sdk_snapshots = [
|
||||
"dartanalyzer",
|
||||
"../utils/dartanalyzer:generate_dartanalyzer_snapshot",
|
||||
],
|
||||
[
|
||||
"dartdev",
|
||||
"../utils/dartdev:dartdev",
|
||||
],
|
||||
[
|
||||
"dartdoc",
|
||||
"../utils/dartdoc",
|
||||
@@ -162,6 +167,10 @@ _full_sdk_snapshots = [
|
||||
"dartanalyzer",
|
||||
"../utils/dartanalyzer:generate_dartanalyzer_snapshot",
|
||||
],
|
||||
[
|
||||
"dartdev",
|
||||
"../utils/dartdev:generate_dartdev_snapshot",
|
||||
],
|
||||
[
|
||||
"dartdevc",
|
||||
"../utils/dartdevc",
|
||||
|
||||
+19
-1
@@ -12,7 +12,10 @@ dartdev_files = exec_script("../../tools/list_dart_files.py",
|
||||
"list lines")
|
||||
|
||||
group("dartdev") {
|
||||
public_deps = [ ":copy_dartdev_kernel" ]
|
||||
public_deps = [
|
||||
":copy_dartdev_kernel",
|
||||
":copy_dartdev_snapshot",
|
||||
]
|
||||
}
|
||||
|
||||
copy("copy_dartdev_kernel") {
|
||||
@@ -30,3 +33,18 @@ application_snapshot("generate_dartdev_kernel") {
|
||||
inputs = dartdev_files
|
||||
output = "$root_gen_dir/dartdev.dill"
|
||||
}
|
||||
|
||||
copy("copy_dartdev_snapshot") {
|
||||
visibility = [ ":dartdev" ]
|
||||
public_deps = [ ":generate_dartdev_snapshot" ]
|
||||
sources = [ "$root_gen_dir/dartdev.dart.snapshot" ]
|
||||
outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
|
||||
}
|
||||
|
||||
application_snapshot("generate_dartdev_snapshot") {
|
||||
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
|
||||
training_args = [ "--help" ]
|
||||
deps = [ "../dds:dds" ]
|
||||
inputs = dartdev_files
|
||||
output = "$root_gen_dir/dartdev.dart.snapshot"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user