Support running sound null safe kernels from dart_runner (flutter/engine#49598)

Before starting an isolate, `dart[_test]_component_controller` detects
sound null safety status for all given kernels and fails if they aren't
the same, and uses the result to set `null_safety` in isolate flags.

Also switch to `core` snapshots from `core-jit` snapshots, based on
https://github.com/flutter/engine/pull/30744, as it looks like
`core-jit` snapshots are not null safety agnostic.

See b/315776399


## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [X] All existing and new tests are passing.
This commit is contained in:
Ivan Inozemtsev 2024-01-16 16:58:01 +01:00 committed by GitHub
parent 6aced2dd87
commit 445a8fb328
7 changed files with 88 additions and 79 deletions

View File

@ -248,21 +248,11 @@ template("jit_runner_package") {
rebase_path("$target_gen_dir/kernel/vm_data${product_suffix}.bin")
dest = "vm_snapshot_data.bin"
},
{
path = rebase_path(
"$target_gen_dir/kernel/vm_instructions${product_suffix}.bin")
dest = "vm_snapshot_instructions.bin"
},
{
path = rebase_path(
"$target_gen_dir/kernel/isolate_data${product_suffix}.bin")
dest = "isolate_core_snapshot_data.bin"
},
{
path = rebase_path(
"$target_gen_dir/kernel/isolate_instructions${product_suffix}.bin")
dest = "isolate_core_snapshot_instructions.bin"
},
]
if (!invoker.product) {

View File

@ -304,22 +304,13 @@ bool DartComponentController::SetUpFromKernel() {
isolate_snapshot_data_)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
nullptr, "/pkg/data/isolate_core_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
if (!CreateIsolate(isolate_snapshot_data_.address(),
isolate_snapshot_instructions_.address())) {
return false;
}
Dart_EnterScope();
std::string str(reinterpret_cast<const char*>(manifest.address()),
manifest.size());
Dart_Handle library = Dart_Null();
bool first_library = true;
bool result_sound_null_safety = false;
for (size_t start = 0; start < manifest.size();) {
size_t end = str.find("\n", start);
if (end == std::string::npos) {
@ -339,6 +330,37 @@ bool DartComponentController::SetUpFromKernel() {
Dart_ExitScope();
return false;
}
bool sound_null_safety = Dart_DetectNullSafety(
/*script_uri=*/nullptr, /*package_config=*/nullptr,
/*original_working_directory=*/nullptr,
isolate_snapshot_data_.address(),
/*isolate_snapshot_instructions=*/nullptr, kernel.address(),
kernel.size());
if (first_library) {
result_sound_null_safety = sound_null_safety;
first_library = false;
} else if (sound_null_safety != result_sound_null_safety) {
FX_LOG(ERROR, LOG_TAG, "Inconsistent sound null safety");
return false;
}
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_IsolateFlags isolate_flags;
Dart_IsolateFlagsInitialize(&isolate_flags);
isolate_flags.null_safety = result_sound_null_safety;
if (!CreateIsolate(isolate_snapshot_data_.address(),
/*isolate_snapshot_instructions=*/nullptr,
&isolate_flags)) {
return false;
}
Dart_EnterScope();
for (const auto& kernel : kernel_peices_) {
library = Dart_LoadLibraryFromKernel(kernel.address(), kernel.size());
if (Dart_IsError(library)) {
FX_LOGF(ERROR, LOG_TAG, "Cannot load library from kernel: %s",
@ -346,9 +368,8 @@ bool DartComponentController::SetUpFromKernel() {
Dart_ExitScope();
return false;
}
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_SetRootLibrary(library);
Dart_Handle result = Dart_FinalizeLoading(false);
@ -381,19 +402,18 @@ bool DartComponentController::SetUpFromAppSnapshot() {
isolate_snapshot_data_)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/isolate_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
isolate_data = isolate_snapshot_data_.address();
isolate_instructions = nullptr;
}
return CreateIsolate(isolate_data, isolate_instructions);
return CreateIsolate(isolate_data, isolate_instructions,
/*isolate_flags=*/nullptr);
#endif // defined(AOT_RUNTIME)
}
bool DartComponentController::CreateIsolate(
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions) {
const uint8_t* isolate_snapshot_instructions,
Dart_IsolateFlags* isolate_flags) {
// Create the isolate from the snapshot.
char* error = nullptr;
@ -406,7 +426,7 @@ bool DartComponentController::CreateIsolate(
isolate_ = Dart_CreateIsolateGroup(
url_.c_str(), label_.c_str(), isolate_snapshot_data,
isolate_snapshot_instructions, nullptr /* flags */, state, state, &error);
isolate_snapshot_instructions, isolate_flags, state, state, &error);
if (!isolate_) {
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
return false;

View File

@ -61,7 +61,8 @@ class DartComponentController
bool SetUpFromAppSnapshot();
bool CreateIsolate(const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions);
const uint8_t* isolate_snapshot_instructions,
Dart_IsolateFlags* isolate_flags);
// |Echo|
void EchoString(fidl::StringPtr value, EchoStringCallback callback) override;

View File

@ -56,10 +56,6 @@ const char* kDartVMArgs[] = {
#if !defined(DART_PRODUCT) && (!defined(FLUTTER_PROFILE) || !defined(NDEBUG))
"--enable_asserts",
#endif
// Run in unsound null safety mode as some packages used in Integration
// testing have not been migrated yet.
"--no-sound-null-safety",
// clang-format on
};
Dart_Isolate IsolateGroupCreateCallback(const char* uri,
@ -226,13 +222,7 @@ DartRunner::DartRunner(sys::ComponentContext* context) : context_(context) {
nullptr, "/pkg/data/vm_snapshot_data.bin", vm_snapshot_data_)) {
FX_LOG(FATAL, LOG_TAG, "Failed to load vm snapshot data");
}
if (!dart_utils::MappedResource::LoadFromNamespace(
nullptr, "/pkg/data/vm_snapshot_instructions.bin",
vm_snapshot_instructions_, true /* executable */)) {
FX_LOG(FATAL, LOG_TAG, "Failed to load vm snapshot instructions");
}
params.vm_snapshot_data = vm_snapshot_data_.address();
params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
#endif
params.create_group = IsolateGroupCreateCallback;
params.shutdown_isolate = IsolateShutdownCallback;

View File

@ -241,27 +241,17 @@ bool DartTestComponentController::SetUpFromKernel() {
isolate_snapshot_data_)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
nullptr, "/pkg/data/isolate_core_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
if (!CreateIsolate(isolate_snapshot_data_.address(),
isolate_snapshot_instructions_.address())) {
return false;
}
Dart_EnterScope();
std::string str(reinterpret_cast<const char*>(manifest.address()),
manifest.size());
Dart_Handle library = Dart_Null();
bool first_library = true;
bool result_sound_null_safety = false;
for (size_t start = 0; start < manifest.size();) {
size_t end = str.find("\n", start);
if (end == std::string::npos) {
FX_LOG(ERROR, LOG_TAG, "Malformed manifest");
Dart_ExitScope();
return false;
}
@ -273,9 +263,39 @@ bool DartTestComponentController::SetUpFromKernel() {
kernel)) {
FX_LOGF(ERROR, LOG_TAG, "Cannot load kernel from namespace: %s",
path.c_str());
Dart_ExitScope();
return false;
}
bool sound_null_safety = Dart_DetectNullSafety(
/*script_uri=*/nullptr, /*package_config=*/nullptr,
/*original_working_directory=*/nullptr,
isolate_snapshot_data_.address(),
/*isolate_snapshot_instructions=*/nullptr, kernel.address(),
kernel.size());
if (first_library) {
result_sound_null_safety = sound_null_safety;
first_library = false;
} else if (sound_null_safety != result_sound_null_safety) {
FX_LOG(ERROR, LOG_TAG, "Inconsistent sound null safety");
return false;
}
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_IsolateFlags isolate_flags;
Dart_IsolateFlagsInitialize(&isolate_flags);
isolate_flags.null_safety = result_sound_null_safety;
if (!CreateIsolate(isolate_snapshot_data_.address(),
/*isolate_snapshot_instructions=*/nullptr,
&isolate_flags)) {
return false;
}
Dart_EnterScope();
for (const auto& kernel : kernel_peices_) {
library = Dart_LoadLibraryFromKernel(kernel.address(), kernel.size());
if (Dart_IsError(library)) {
FX_LOGF(ERROR, LOG_TAG, "Cannot load library from kernel: %s",
@ -283,8 +303,6 @@ bool DartTestComponentController::SetUpFromKernel() {
Dart_ExitScope();
return false;
}
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_SetRootLibrary(library);
@ -318,19 +336,18 @@ bool DartTestComponentController::SetUpFromAppSnapshot() {
isolate_snapshot_data_)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/isolate_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
isolate_data = isolate_snapshot_data_.address();
isolate_instructions = nullptr;
}
return CreateIsolate(isolate_data, isolate_instructions);
return CreateIsolate(isolate_data, isolate_instructions,
/*isolate_flags=*/nullptr);
#endif // defined(AOT_RUNTIME)
}
bool DartTestComponentController::CreateIsolate(
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions) {
const uint8_t* isolate_snapshot_instructions,
Dart_IsolateFlags* isolate_flags) {
// Create the isolate from the snapshot.
char* error = nullptr;
@ -343,7 +360,7 @@ bool DartTestComponentController::CreateIsolate(
isolate_ = Dart_CreateIsolateGroup(
url_.c_str(), label_.c_str(), isolate_snapshot_data,
isolate_snapshot_instructions, nullptr /* flags */, state, state, &error);
isolate_snapshot_instructions, isolate_flags, state, state, &error);
if (!isolate_) {
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
return false;

View File

@ -77,7 +77,8 @@ class DartTestComponentController
bool SetUpFromAppSnapshot();
bool CreateIsolate(const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions);
const uint8_t* isolate_snapshot_instructions,
Dart_IsolateFlags* isolate_flags);
// |ComponentController|
void Kill() override;

View File

@ -40,17 +40,11 @@ template("create_kernel_core_snapshot") {
inputs = [ platform_dill ]
vm_snapshot_data = "$target_gen_dir/vm_data${product_suffix}.bin"
vm_snapshot_instructions =
"$target_gen_dir/vm_instructions${product_suffix}.bin"
isolate_snapshot_data = "$target_gen_dir/isolate_data${product_suffix}.bin"
isolate_snapshot_instructions =
"$target_gen_dir/isolate_instructions${product_suffix}.bin"
snapshot_profile = "$target_gen_dir/snapshot_profile${product_suffix}.json"
outputs = [
vm_snapshot_data,
vm_snapshot_instructions,
isolate_snapshot_data,
isolate_snapshot_instructions,
snapshot_profile,
]
@ -64,14 +58,10 @@ template("create_kernel_core_snapshot") {
args = [
"--enable_mirrors=false",
"--deterministic",
"--snapshot_kind=core-jit",
"--snapshot_kind=core",
"--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),
"--vm_snapshot_instructions=" +
rebase_path(vm_snapshot_instructions, root_build_dir),
"--isolate_snapshot_data=" +
rebase_path(isolate_snapshot_data, root_build_dir),
"--isolate_snapshot_instructions=" +
rebase_path(isolate_snapshot_instructions, root_build_dir),
"--write_v8_snapshot_profile_to=" +
rebase_path(snapshot_profile, root_build_dir),
]