Skip to content

Commit

Permalink
bootstrap: build code cache from deserialized isolate
Browse files Browse the repository at this point in the history
V8 now requires the code cache to be compiled with a finalized
read-only space, so we need to serialize the snapshot to get
a finalized read-only space first, then deserialize it to compile
the code cache.

PR-URL: #49099
Refs: #47636
Refs: https://bugs.chromium.org/p/v8/issues/detail?id=13789
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
  • Loading branch information
joyeecheung authored and UlisesGascon committed Sep 10, 2023
1 parent ab97523 commit f37444e
Showing 1 changed file with 73 additions and 18 deletions.
91 changes: 73 additions & 18 deletions src/node_snapshotable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data,
const_cast<v8::StartupData*>(&(data->v8_snapshot_blob_data));
}

ExitCode SnapshotBuilder::Generate(
ExitCode BuildSnapshotWithoutCodeCache(
SnapshotData* out,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args,
Expand All @@ -933,8 +933,8 @@ ExitCode SnapshotBuilder::Generate(
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return ExitCode::kBootstrapFailure;
}
Isolate* isolate = setup->isolate();

Isolate* isolate = setup->isolate();
{
HandleScope scope(isolate);
TryCatch bootstrapCatch(isolate);
Expand Down Expand Up @@ -968,7 +968,77 @@ ExitCode SnapshotBuilder::Generate(
}
}

return CreateSnapshot(out, setup.get(), static_cast<uint8_t>(snapshot_type));
return SnapshotBuilder::CreateSnapshot(
out, setup.get(), static_cast<uint8_t>(snapshot_type));
}

ExitCode BuildCodeCacheFromSnapshot(SnapshotData* out,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
std::vector<std::string> errors;
auto data_wrapper = out->AsEmbedderWrapper();
auto setup = CommonEnvironmentSetup::CreateFromSnapshot(
per_process::v8_platform.Platform(),
&errors,
data_wrapper.get(),
args,
exec_args);
if (!setup) {
for (const auto& err : errors)
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return ExitCode::kBootstrapFailure;
}

Isolate* isolate = setup->isolate();
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
TryCatch bootstrapCatch(isolate);

auto print_Exception = OnScopeLeave([&]() {
if (bootstrapCatch.HasCaught()) {
PrintCaughtException(
isolate, isolate->GetCurrentContext(), bootstrapCatch);
}
});

Environment* env = setup->env();
// Regenerate all the code cache.
if (!env->builtin_loader()->CompileAllBuiltins(setup->context())) {
return ExitCode::kGenericUserError;
}
env->builtin_loader()->CopyCodeCache(&(out->code_cache));
if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
for (const auto& item : out->code_cache) {
std::string size_str = FormatSize(item.data.length);
per_process::Debug(DebugCategory::MKSNAPSHOT,
"Generated code cache for %d: %s\n",
item.id.c_str(),
size_str.c_str());
}
}
return ExitCode::kNoFailure;
}

ExitCode SnapshotBuilder::Generate(
SnapshotData* out,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args,
std::optional<std::string_view> main_script) {
ExitCode code =
BuildSnapshotWithoutCodeCache(out, args, exec_args, main_script);
if (code != ExitCode::kNoFailure) {
return code;
}

#ifdef NODE_USE_NODE_CODE_CACHE
// Deserialize the snapshot to recompile code cache. We need to do this in the
// second pass because V8 requires the code cache to be compiled with a
// finalized read-only space.
return BuildCodeCacheFromSnapshot(out, args, exec_args);
#else
return ExitCode::kNoFailure;
#endif
}

ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out,
Expand Down Expand Up @@ -1021,21 +1091,6 @@ ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out,
out->isolate_data_info = setup->isolate_data()->Serialize(creator);
out->env_info = env->Serialize(creator);

#ifdef NODE_USE_NODE_CODE_CACHE
// Regenerate all the code cache.
if (!env->builtin_loader()->CompileAllBuiltins(main_context)) {
return ExitCode::kGenericUserError;
}
env->builtin_loader()->CopyCodeCache(&(out->code_cache));
for (const auto& item : out->code_cache) {
std::string size_str = FormatSize(item.data.length);
per_process::Debug(DebugCategory::MKSNAPSHOT,
"Generated code cache for %d: %s\n",
item.id.c_str(),
size_str.c_str());
}
#endif

ResetContextSettingsBeforeSnapshot(main_context);
}

Expand Down

0 comments on commit f37444e

Please sign in to comment.