[symbol-as-weakmap-key] Fix DCHECKs when clearing JS weakrefs

Bug: chromium:1372500, v8:12947
Fixed: chromium:1372500
Change-Id: Id6330de5886e4ea72544b307c358e2190ea47d9c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3942586
Reviewed-by: Anton Bikineev <bikineev@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83632}
This commit is contained in:
Shu-yu Guo 2022-10-10 15:23:42 -07:00 committed by V8 LUCI CQ
parent e9775165b6
commit 1fada6b36f
2 changed files with 17 additions and 2 deletions

View File

@ -3479,7 +3479,7 @@ void MarkCompactCollector::ClearJSWeakRefs() {
};
HeapObject target = HeapObject::cast(weak_cell.target());
if (!non_atomic_marking_state()->IsBlackOrGrey(target)) {
DCHECK(!target.IsUndefined());
DCHECK(target.CanBeHeldWeakly());
// The value of the WeakCell is dead.
JSFinalizationRegistry finalization_registry =
JSFinalizationRegistry::cast(weak_cell.finalization_registry());
@ -3501,6 +3501,7 @@ void MarkCompactCollector::ClearJSWeakRefs() {
HeapObject unregister_token = weak_cell.unregister_token();
if (!non_atomic_marking_state()->IsBlackOrGrey(unregister_token)) {
DCHECK(unregister_token.CanBeHeldWeakly());
// The unregister token is dead. Remove any corresponding entries in the
// key map. Multiple WeakCell with the same token will have all their
// unregister_token field set to undefined when processing the first
@ -3509,7 +3510,7 @@ void MarkCompactCollector::ClearJSWeakRefs() {
JSFinalizationRegistry finalization_registry =
JSFinalizationRegistry::cast(weak_cell.finalization_registry());
finalization_registry.RemoveUnregisterToken(
JSReceiver::cast(unregister_token), isolate(),
unregister_token, isolate(),
JSFinalizationRegistry::kKeepMatchedCellsInRegistry,
gc_notify_updated_slot);
} else {

View File

@ -0,0 +1,14 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-symbol-as-weakmap-key --expose-gc
// Register an object in a FinalizationRegistry with a Symbol as the unregister
// token.
let fr = new FinalizationRegistry(function () {});
(function register() {
fr.register({}, "holdings", Symbol('unregisterToken'));
})();
// The unregister token should be dead, trigger its collection.
gc();