Commit 360c7afc authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

[weakrefs] Clear unregister token-related fields when clearing weak cells

Bug: chromium:1213770
Change-Id: Ic063e79bfa8f3dabdd29d1cc9ed74c7af44d0c31
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2923294Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74890}
parent 3d24b3ab
...@@ -2578,11 +2578,6 @@ void MarkCompactCollector::ClearJSWeakRefs() { ...@@ -2578,11 +2578,6 @@ void MarkCompactCollector::ClearJSWeakRefs() {
matched_cell.set_unregister_token(undefined); matched_cell.set_unregister_token(undefined);
}, },
gc_notify_updated_slot); gc_notify_updated_slot);
// The following is necessary because in the case that weak_cell has
// already been popped and removed from the FinalizationRegistry, the call
// to JSFinalizationRegistry::RemoveUnregisterToken above will not find
// weak_cell itself to clear its unregister token.
weak_cell.set_unregister_token(undefined);
} else { } else {
// The unregister_token is alive. // The unregister_token is alive.
ObjectSlot slot = weak_cell.RawField(WeakCell::kUnregisterTokenOffset); ObjectSlot slot = weak_cell.RawField(WeakCell::kUnregisterTokenOffset);
......
...@@ -6844,6 +6844,7 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap( ...@@ -6844,6 +6844,7 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap(
JSFinalizationRegistry::cast(Object(raw_finalization_registry)); JSFinalizationRegistry::cast(Object(raw_finalization_registry));
WeakCell weak_cell = WeakCell::cast(Object(raw_weak_cell)); WeakCell weak_cell = WeakCell::cast(Object(raw_weak_cell));
DCHECK(!weak_cell.unregister_token().IsUndefined(isolate)); DCHECK(!weak_cell.unregister_token().IsUndefined(isolate));
HeapObject undefined = ReadOnlyRoots(isolate).undefined_value();
// Remove weak_cell from the linked list of other WeakCells with the same // Remove weak_cell from the linked list of other WeakCells with the same
// unregister token and remove its unregister token from key_map if necessary // unregister token and remove its unregister token from key_map if necessary
...@@ -6867,8 +6868,7 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap( ...@@ -6867,8 +6868,7 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap(
// of the key in the hash table. // of the key in the hash table.
WeakCell next = WeakCell::cast(weak_cell.key_list_next()); WeakCell next = WeakCell::cast(weak_cell.key_list_next());
DCHECK_EQ(next.key_list_prev(), weak_cell); DCHECK_EQ(next.key_list_prev(), weak_cell);
next.set_key_list_prev(ReadOnlyRoots(isolate).undefined_value()); next.set_key_list_prev(undefined);
weak_cell.set_key_list_next(ReadOnlyRoots(isolate).undefined_value());
key_map.ValueAtPut(entry, next); key_map.ValueAtPut(entry, next);
} }
} else { } else {
...@@ -6880,6 +6880,12 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap( ...@@ -6880,6 +6880,12 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap(
next.set_key_list_prev(weak_cell.key_list_prev()); next.set_key_list_prev(weak_cell.key_list_prev());
} }
} }
// weak_cell is now removed from the unregister token map, so clear its
// unregister token-related fields for heap verification.
weak_cell.set_unregister_token(undefined);
weak_cell.set_key_list_prev(undefined);
weak_cell.set_key_list_next(undefined);
} }
} // namespace internal } // namespace internal
......
...@@ -979,15 +979,17 @@ TEST(UnregisterTokenHeapVerifier) { ...@@ -979,15 +979,17 @@ TEST(UnregisterTokenHeapVerifier) {
v8::HandleScope outer_scope(isolate); v8::HandleScope outer_scope(isolate);
{ {
// Make a new FinalizationRegistry and register an object with an unregister // Make a new FinalizationRegistry and register two objects with the same
// token that's unreachable after the IIFE returns. // unregister token that's unreachable after the IIFE returns.
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
CompileRun( CompileRun(
"var token = {}; " "var token = {}; "
"var registry = new FinalizationRegistry(function () {}); " "var registry = new FinalizationRegistry(function () {}); "
"(function () { " "(function () { "
" let o = {}; " " let o1 = {}; "
" registry.register(o, {}, token); " " let o2 = {}; "
" registry.register(o1, {}, token); "
" registry.register(o2, {}, token); "
"})();"); "})();");
} }
......
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