Commit 9ebdcced authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[snapshot] Fix clearing of feedback vector in serializer

The serializer clears JSFunctions together with feedback vectors
assuming that there is one to one correspondence between them.

That does not work in the case when there are multiple JSFunctions
sharing the same feedback vector. This patch ensures that all such
JSFunctions are properly cleared.

Bug: v8:7857
Change-Id: Ie441089e12bda5a8be7f9bed90f7be9499938609
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1698383Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62673}
parent 9a9aa71f
......@@ -812,7 +812,7 @@ StartupData SnapshotCreator::CreateBlob(
fun.CompleteInobjectSlackTrackingIfActive();
// Also, clear out feedback vectors, or any optimized code.
if (!fun.raw_feedback_cell().value().IsUndefined()) {
if (fun.IsOptimized() || fun.IsInterpreted()) {
fun.raw_feedback_cell().set_value(
i::ReadOnlyRoots(isolate).undefined_value());
fun.set_code(isolate->builtins()->builtin(i::Builtins::kCompileLazy));
......
......@@ -2938,6 +2938,53 @@ UNINITIALIZED_TEST(SnapshotCreatorArrayJoinWithKeep) {
FreeCurrentEmbeddedBlob();
}
v8::StartupData CreateCustomSnapshotWithDuplicateFunctions() {
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun(
"function f() { return (() => 'a'); }\n"
"let g1 = f();\n"
"let g2 = f();\n");
ExpectString("g1()", "a");
ExpectString("g2()", "a");
creator.SetDefaultContext(context);
}
}
return creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
UNINITIALIZED_TEST(SnapshotCreatorDuplicateFunctions) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateCustomSnapshotWithDuplicateFunctions();
ReadOnlyHeap::ClearSharedHeapForTest();
// Deserialize with an incomplete list of external references.
{
v8::Isolate::CreateParams params;
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
// Test-appropriate equivalent of v8::Isolate::New.
v8::Isolate* isolate = TestSerializer::NewIsolate(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectString("g1()", "a");
ExpectString("g2()", "a");
}
isolate->Dispose();
}
delete[] blob.data;
FreeCurrentEmbeddedBlob();
}
TEST(SnapshotCreatorNoExternalReferencesCustomFail1) {
DisableAlwaysOpt();
v8::StartupData blob = CreateSnapshotWithDefaultAndCustom();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment