Skip to content

Commit 6d50966

Browse files
joyeecheungrichardlau
authored andcommitted
deps: V8: cherry-pick 94e8282325a1
Original commit message: [symbol-as-weakmap-key] Fix DCHECKs and add CanBeHeldWeakly There are a few DCHECKs that weren't updated to allow for Symbols as weak collection keys. This CL updates those DCHECKs and also does the following refactors for clarity: - Add Object::CanBeHeldWeakly - Rename GotoIfCannotBeWeakKey -> GotoIfCannotBeHeldWeakly to align with spec AO name Bug: chromium:1370400, chromium:1370402, v8:12947 Change-Id: I380840c8377497feae97e3fca37555dae0dcc255 Fixed: chromium:1370400, chromium:1370402 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3928150 Auto-Submit: Shu-yu Guo <syg@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/main@{#83507} Refs: v8/v8@94e8282 PR-URL: #51004 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent fafbacd commit 6d50966

13 files changed

+66
-62
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.31',
39+
'v8_embedder_string': '-node.32',
4040

4141
##### V8 defaults for Node.js #####
4242

deps/v8/src/builtins/builtins-collections-gen.cc

+19-19
Original file line numberDiff line numberDiff line change
@@ -399,23 +399,23 @@ TNode<IntPtrT> BaseCollectionsAssembler::EstimatedInitialSize(
399399
[=] { return IntPtrConstant(0); });
400400
}
401401

402-
void BaseCollectionsAssembler::GotoIfCannotBeWeakKey(
403-
const TNode<Object> obj, Label* if_cannot_be_weak_key) {
402+
void BaseCollectionsAssembler::GotoIfCannotBeHeldWeakly(
403+
const TNode<Object> obj, Label* if_cannot_be_held_weakly) {
404404
Label check_symbol_key(this);
405405
Label end(this);
406-
GotoIf(TaggedIsSmi(obj), if_cannot_be_weak_key);
406+
GotoIf(TaggedIsSmi(obj), if_cannot_be_held_weakly);
407407
TNode<Uint16T> instance_type = LoadMapInstanceType(LoadMap(CAST(obj)));
408408
GotoIfNot(IsJSReceiverInstanceType(instance_type), &check_symbol_key);
409409
// TODO(v8:12547) Shared structs should only be able to point to shared values
410410
// in weak collections. For now, disallow them as weak collection keys.
411-
GotoIf(IsJSSharedStructInstanceType(instance_type), if_cannot_be_weak_key);
411+
GotoIf(IsJSSharedStructInstanceType(instance_type), if_cannot_be_held_weakly);
412412
Goto(&end);
413413
Bind(&check_symbol_key);
414-
GotoIfNot(HasHarmonySymbolAsWeakmapKeyFlag(), if_cannot_be_weak_key);
415-
GotoIfNot(IsSymbolInstanceType(instance_type), if_cannot_be_weak_key);
414+
GotoIfNot(HasHarmonySymbolAsWeakmapKeyFlag(), if_cannot_be_held_weakly);
415+
GotoIfNot(IsSymbolInstanceType(instance_type), if_cannot_be_held_weakly);
416416
TNode<Uint32T> flags = LoadSymbolFlags(CAST(obj));
417417
GotoIf(Word32And(flags, Symbol::IsInPublicSymbolTableBit::kMask),
418-
if_cannot_be_weak_key);
418+
if_cannot_be_held_weakly);
419419
Goto(&end);
420420
Bind(&end);
421421
}
@@ -2573,17 +2573,17 @@ TF_BUILTIN(WeakMapLookupHashIndex, WeakCollectionsBuiltinsAssembler) {
25732573
auto table = Parameter<EphemeronHashTable>(Descriptor::kTable);
25742574
auto key = Parameter<Object>(Descriptor::kKey);
25752575

2576-
Label if_cannot_be_weak_key(this);
2576+
Label if_cannot_be_held_weakly(this);
25772577

2578-
GotoIfCannotBeWeakKey(key, &if_cannot_be_weak_key);
2578+
GotoIfCannotBeHeldWeakly(key, &if_cannot_be_held_weakly);
25792579

2580-
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_weak_key);
2580+
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_held_weakly);
25812581
TNode<IntPtrT> capacity = LoadTableCapacity(table);
25822582
TNode<IntPtrT> key_index = FindKeyIndexForKey(
2583-
table, key, hash, EntryMask(capacity), &if_cannot_be_weak_key);
2583+
table, key, hash, EntryMask(capacity), &if_cannot_be_held_weakly);
25842584
Return(SmiTag(ValueIndexFromKeyIndex(key_index)));
25852585

2586-
BIND(&if_cannot_be_weak_key);
2586+
BIND(&if_cannot_be_held_weakly);
25872587
Return(SmiConstant(-1));
25882588
}
25892589

@@ -2638,22 +2638,22 @@ TF_BUILTIN(WeakCollectionDelete, WeakCollectionsBuiltinsAssembler) {
26382638
auto collection = Parameter<JSWeakCollection>(Descriptor::kCollection);
26392639
auto key = Parameter<Object>(Descriptor::kKey);
26402640

2641-
Label call_runtime(this), if_cannot_be_weak_key(this);
2641+
Label call_runtime(this), if_cannot_be_held_weakly(this);
26422642

2643-
GotoIfCannotBeWeakKey(key, &if_cannot_be_weak_key);
2643+
GotoIfCannotBeHeldWeakly(key, &if_cannot_be_held_weakly);
26442644

2645-
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_weak_key);
2645+
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_held_weakly);
26462646
TNode<EphemeronHashTable> table = LoadTable(collection);
26472647
TNode<IntPtrT> capacity = LoadTableCapacity(table);
26482648
TNode<IntPtrT> key_index = FindKeyIndexForKey(
2649-
table, key, hash, EntryMask(capacity), &if_cannot_be_weak_key);
2649+
table, key, hash, EntryMask(capacity), &if_cannot_be_held_weakly);
26502650
TNode<IntPtrT> number_of_elements = LoadNumberOfElements(table, -1);
26512651
GotoIf(ShouldShrink(capacity, number_of_elements), &call_runtime);
26522652

26532653
RemoveEntry(table, key_index, number_of_elements);
26542654
Return(TrueConstant());
26552655

2656-
BIND(&if_cannot_be_weak_key);
2656+
BIND(&if_cannot_be_held_weakly);
26572657
Return(FalseConstant());
26582658

26592659
BIND(&call_runtime);
@@ -2735,7 +2735,7 @@ TF_BUILTIN(WeakMapPrototypeSet, WeakCollectionsBuiltinsAssembler) {
27352735
"WeakMap.prototype.set");
27362736

27372737
Label throw_invalid_key(this);
2738-
GotoIfCannotBeWeakKey(key, &throw_invalid_key);
2738+
GotoIfCannotBeHeldWeakly(key, &throw_invalid_key);
27392739

27402740
Return(
27412741
CallBuiltin(Builtin::kWeakCollectionSet, context, receiver, key, value));
@@ -2753,7 +2753,7 @@ TF_BUILTIN(WeakSetPrototypeAdd, WeakCollectionsBuiltinsAssembler) {
27532753
"WeakSet.prototype.add");
27542754

27552755
Label throw_invalid_value(this);
2756-
GotoIfCannotBeWeakKey(value, &throw_invalid_value);
2756+
GotoIfCannotBeHeldWeakly(value, &throw_invalid_value);
27572757

27582758
Return(CallBuiltin(Builtin::kWeakCollectionSet, context, receiver, value,
27592759
TrueConstant()));

deps/v8/src/builtins/builtins-collections-gen.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
2727

2828
virtual ~BaseCollectionsAssembler() = default;
2929

30-
void GotoIfCannotBeWeakKey(const TNode<Object> obj,
31-
Label* if_cannot_be_weak_key);
30+
void GotoIfCannotBeHeldWeakly(const TNode<Object> obj,
31+
Label* if_cannot_be_held_weakly);
3232

3333
protected:
3434
enum Variant { kMap, kSet, kWeakMap, kWeakSet };

deps/v8/src/builtins/builtins-weak-refs.cc

+4-17
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,10 @@ BUILTIN(FinalizationRegistryUnregister) {
2727

2828
// 4. If CanBeHeldWeakly(unregisterToken) is false, throw a TypeError
2929
// exception.
30-
if (FLAG_harmony_symbol_as_weakmap_key) {
31-
if (!unregister_token->IsJSReceiver() &&
32-
(!unregister_token->IsSymbol() ||
33-
Handle<Symbol>::cast(unregister_token)->is_in_public_symbol_table())) {
34-
THROW_NEW_ERROR_RETURN_FAILURE(
35-
isolate,
36-
NewTypeError(MessageTemplate::kInvalidWeakRefsUnregisterToken,
37-
unregister_token));
38-
}
39-
} else {
40-
// 4. If Type(unregisterToken) is not Object, throw a TypeError exception.
41-
if (!unregister_token->IsJSReceiver()) {
42-
THROW_NEW_ERROR_RETURN_FAILURE(
43-
isolate,
44-
NewTypeError(MessageTemplate::kInvalidWeakRefsUnregisterToken,
45-
unregister_token));
46-
}
30+
if (!unregister_token->CanBeHeldWeakly()) {
31+
THROW_NEW_ERROR_RETURN_FAILURE(
32+
isolate, NewTypeError(MessageTemplate::kInvalidWeakRefsUnregisterToken,
33+
unregister_token));
4734
}
4835

4936
bool success = JSFinalizationRegistry::Unregister(

deps/v8/src/builtins/finalization-registry.tq

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extern transitioning macro
1616
RemoveFinalizationRegistryCellFromUnregisterTokenMap(
1717
JSFinalizationRegistry, WeakCell): void;
1818

19-
extern macro WeakCollectionsBuiltinsAssembler::GotoIfCannotBeWeakKey(JSAny):
19+
extern macro WeakCollectionsBuiltinsAssembler::GotoIfCannotBeHeldWeakly(JSAny):
2020
void labels NotWeakKey;
2121

2222
macro SplitOffTail(weakCell: WeakCell): WeakCell|Undefined {
@@ -140,7 +140,7 @@ FinalizationRegistryRegister(
140140
MessageTemplate::kIncompatibleMethodReceiver,
141141
'FinalizationRegistry.prototype.register', receiver);
142142
// 3. If CanBeHeldWeakly(target) is false, throw a TypeError exception.
143-
GotoIfCannotBeWeakKey(arguments[0])
143+
GotoIfCannotBeHeldWeakly(arguments[0])
144144
otherwise ThrowTypeError(MessageTemplate::kInvalidWeakRefsRegisterTarget);
145145

146146
const target = UnsafeCast<(JSReceiver | Symbol)>(arguments[0]);
@@ -159,7 +159,7 @@ FinalizationRegistryRegister(
159159
if (IsUndefined(unregisterTokenRaw)) {
160160
unregisterToken = Undefined;
161161
} else {
162-
GotoIfCannotBeWeakKey(unregisterTokenRaw)
162+
GotoIfCannotBeHeldWeakly(unregisterTokenRaw)
163163
otherwise ThrowTypeError(
164164
MessageTemplate::kInvalidWeakRefsUnregisterToken, unregisterTokenRaw);
165165
unregisterToken = UnsafeCast<(JSReceiver | Symbol)>(unregisterTokenRaw);

deps/v8/src/builtins/weak-ref.tq

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ WeakRefConstructor(
2424
}
2525

2626
// 2. If CanBeHeldWeakly(weakTarget) is false, throw a TypeError exception.
27-
GotoIfCannotBeWeakKey(weakTarget) otherwise ThrowTypeError(
27+
GotoIfCannotBeHeldWeakly(weakTarget) otherwise ThrowTypeError(
2828
MessageTemplate::kInvalidWeakRefsWeakRefConstructorTarget);
2929

3030
// 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget,

deps/v8/src/diagnostics/objects-debug.cc

+2-6
Original file line numberDiff line numberDiff line change
@@ -1240,9 +1240,7 @@ void JSSharedStruct::JSSharedStructVerify(Isolate* isolate) {
12401240
void WeakCell::WeakCellVerify(Isolate* isolate) {
12411241
CHECK(IsWeakCell());
12421242

1243-
CHECK(target().IsJSReceiver() || target().IsUndefined(isolate) ||
1244-
(target().IsSymbol() &&
1245-
!Symbol::cast(target()).is_in_public_symbol_table()));
1243+
CHECK(target().IsUndefined(isolate) || target().CanBeHeldWeakly());
12461244

12471245
CHECK(prev().IsWeakCell() || prev().IsUndefined(isolate));
12481246
if (prev().IsWeakCell()) {
@@ -1270,9 +1268,7 @@ void WeakCell::WeakCellVerify(Isolate* isolate) {
12701268
void JSWeakRef::JSWeakRefVerify(Isolate* isolate) {
12711269
CHECK(IsJSWeakRef());
12721270
JSObjectVerify(isolate);
1273-
CHECK(target().IsUndefined(isolate) || target().IsJSReceiver() ||
1274-
(target().IsSymbol() &&
1275-
!Symbol::cast(target()).is_in_public_symbol_table()));
1271+
CHECK(target().IsUndefined(isolate) || target().CanBeHeldWeakly());
12761272
}
12771273

12781274
void JSFinalizationRegistry::JSFinalizationRegistryVerify(Isolate* isolate) {

deps/v8/src/objects/js-weak-refs-inl.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,7 @@ void WeakCell::Nullify(Isolate* isolate,
170170
// only called for WeakCells which haven't been unregistered yet, so they will
171171
// be in the active_cells list. (The caller must guard against calling this
172172
// for unregistered WeakCells by checking that the target is not undefined.)
173-
DCHECK(target().IsJSReceiver() ||
174-
(target().IsSymbol() &&
175-
!Symbol::cast(target()).is_in_public_symbol_table()));
173+
DCHECK(target().CanBeHeldWeakly());
176174
set_target(ReadOnlyRoots(isolate).undefined_value());
177175

178176
JSFinalizationRegistry fr =
@@ -218,7 +216,7 @@ void WeakCell::RemoveFromFinalizationRegistryCells(Isolate* isolate) {
218216

219217
// It's important to set_target to undefined here. This guards that we won't
220218
// call Nullify (which assumes that the WeakCell is in active_cells).
221-
DCHECK(target().IsUndefined() || target().IsJSReceiver());
219+
DCHECK(target().IsUndefined() || target().CanBeHeldWeakly());
222220
set_target(ReadOnlyRoots(isolate).undefined_value());
223221

224222
JSFinalizationRegistry fr =

deps/v8/src/objects/objects-inl.h

+17
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,23 @@ MaybeHandle<Object> Object::Share(Isolate* isolate, Handle<Object> value,
12061206
throw_if_cannot_be_shared);
12071207
}
12081208

1209+
// https://tc39.es/proposal-symbols-as-weakmap-keys/#sec-canbeheldweakly-abstract-operation
1210+
bool Object::CanBeHeldWeakly() const {
1211+
if (IsJSReceiver()) {
1212+
// TODO(v8:12547) Shared structs and arrays should only be able to point
1213+
// to shared values in weak collections. For now, disallow them as weak
1214+
// collection keys.
1215+
if (FLAG_harmony_struct) {
1216+
return !IsJSSharedStruct();
1217+
}
1218+
return true;
1219+
}
1220+
if (FLAG_harmony_symbol_as_weakmap_key) {
1221+
return IsSymbol() && !Symbol::cast(*this).is_in_public_symbol_table();
1222+
}
1223+
return false;
1224+
}
1225+
12091226
Handle<Object> ObjectHashTableShape::AsHandle(Handle<Object> key) {
12101227
return key;
12111228
}

deps/v8/src/objects/objects.h

+5
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,11 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
770770
Handle<HeapObject> value,
771771
ShouldThrow throw_if_cannot_be_shared);
772772

773+
// Whether this Object can be held weakly, i.e. whether it can be used as a
774+
// key in WeakMap, as a key in WeakSet, as the target of a WeakRef, or as a
775+
// target or unregister token of a FinalizationRegistry.
776+
inline bool CanBeHeldWeakly() const;
777+
773778
protected:
774779
inline Address field_address(size_t offset) const {
775780
return ptr() + offset - kHeapObjectTag;

deps/v8/src/runtime/runtime-collections.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
8282
int hash = args.smi_value_at(2);
8383

8484
#ifdef DEBUG
85-
DCHECK(key->IsJSReceiver());
85+
DCHECK(key->CanBeHeldWeakly());
8686
DCHECK(EphemeronHashTable::IsKey(ReadOnlyRoots(isolate), *key));
8787
Handle<EphemeronHashTable> table(
8888
EphemeronHashTable::cast(weak_collection->table()), isolate);
@@ -105,7 +105,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
105105
int hash = args.smi_value_at(3);
106106

107107
#ifdef DEBUG
108-
DCHECK(key->IsJSReceiver());
108+
DCHECK(key->CanBeHeldWeakly());
109109
DCHECK(EphemeronHashTable::IsKey(ReadOnlyRoots(isolate), *key));
110110
Handle<EphemeronHashTable> table(
111111
EphemeronHashTable::cast(weak_collection->table()), isolate);

deps/v8/src/runtime/runtime-weak-refs.cc

+1-7
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,7 @@ RUNTIME_FUNCTION(Runtime_JSWeakRefAddToKeptObjects) {
4444
HandleScope scope(isolate);
4545
DCHECK_EQ(1, args.length());
4646
Handle<HeapObject> object = args.at<HeapObject>(0);
47-
if (FLAG_harmony_symbol_as_weakmap_key) {
48-
DCHECK(object->IsJSReceiver() ||
49-
(object->IsSymbol() &&
50-
!(Handle<Symbol>::cast(object))->is_in_public_symbol_table()));
51-
} else {
52-
DCHECK(object->IsJSReceiver());
53-
}
47+
DCHECK(object->CanBeHeldWeakly());
5448

5549
isolate->heap()->KeepDuringJob(object);
5650

deps/v8/test/mjsunit/harmony/symbol-as-weakmap-key.js

+7
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,10 @@
9999
assertFalse(set.delete(key));
100100
assertFalse(set.has(key));
101101
})();
102+
103+
(function TestFinalizationRegistryUnregister() {
104+
const fr = new FinalizationRegistry(function() {});
105+
const key = {};
106+
fr.register(Symbol('foo'), "holdings", key);
107+
fr.unregister(key);
108+
})();

0 commit comments

Comments
 (0)