Skip to content

Commit 1ce901b

Browse files
joyeecheungrichardlau
authored andcommitted
deps: V8: cherry-pick c400af48b5ef
Original commit message: [symbol-as-weakmap-key] Implement Symbol as WeakMap Keys Allow non-registered symbols as keys in weakmap and weakset. Allow non-registered symbols as target and unregisterToken in WeakRef and FinalizationRegistry. Bug: v8:12947 Change-Id: Ieb63bda66e3cc378879ac651e23300b71caed627 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3865056 Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Jakob Linke <jgruber@chromium.org> Cr-Commit-Position: refs/heads/main@{#83313} Refs: v8/v8@c400af4 PR-URL: #51004 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 902d8b3 commit 1ce901b

27 files changed

+534
-261
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
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.28',
39+
'v8_embedder_string': '-node.29',
4040

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

deps/v8/src/builtins/base.tq

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ extern enum MessageTemplate {
438438
kWasmTrapArrayOutOfBounds,
439439
kWasmTrapArrayTooLarge,
440440
kWeakRefsRegisterTargetAndHoldingsMustNotBeSame,
441-
kWeakRefsRegisterTargetMustBeObject,
442-
kWeakRefsUnregisterTokenMustBeObject,
443-
kWeakRefsWeakRefConstructorTargetMustBeObject,
441+
kInvalidWeakRefsRegisterTarget,
442+
kInvalidWeakRefsUnregisterToken,
443+
kInvalidWeakRefsWeakRefConstructorTarget,
444444
...
445445
}
446446

@@ -906,10 +906,10 @@ macro Float64IsNaN(n: float64): bool {
906906
// The type of all tagged values that can safely be compared with TaggedEqual.
907907
@if(V8_ENABLE_WEBASSEMBLY)
908908
type TaggedWithIdentity = JSReceiver | FixedArrayBase | Oddball | Map |
909-
WeakCell | Context | EmptyString | WasmInternalFunction;
909+
WeakCell | Context | EmptyString | Symbol | WasmInternalFunction;
910910
@ifnot(V8_ENABLE_WEBASSEMBLY)
911911
type TaggedWithIdentity = JSReceiver | FixedArrayBase | Oddball | Map |
912-
WeakCell | Context | EmptyString;
912+
WeakCell | Context | EmptyString | Symbol;
913913

914914
extern operator '==' macro TaggedEqual(TaggedWithIdentity, Object): bool;
915915
extern operator '==' macro TaggedEqual(Object, TaggedWithIdentity): bool;

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

Lines changed: 37 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -22,130 +22,6 @@ namespace internal {
2222
template <class T>
2323
using TVariable = compiler::TypedCodeAssemblerVariable<T>;
2424

25-
class BaseCollectionsAssembler : public CodeStubAssembler {
26-
public:
27-
explicit BaseCollectionsAssembler(compiler::CodeAssemblerState* state)
28-
: CodeStubAssembler(state) {}
29-
30-
virtual ~BaseCollectionsAssembler() = default;
31-
32-
protected:
33-
enum Variant { kMap, kSet, kWeakMap, kWeakSet };
34-
35-
// Adds an entry to a collection. For Maps, properly handles extracting the
36-
// key and value from the entry (see LoadKeyValue()).
37-
void AddConstructorEntry(Variant variant, TNode<Context> context,
38-
TNode<Object> collection, TNode<Object> add_function,
39-
TNode<Object> key_value,
40-
Label* if_may_have_side_effects = nullptr,
41-
Label* if_exception = nullptr,
42-
TVariable<Object>* var_exception = nullptr);
43-
44-
// Adds constructor entries to a collection. Choosing a fast path when
45-
// possible.
46-
void AddConstructorEntries(Variant variant, TNode<Context> context,
47-
TNode<Context> native_context,
48-
TNode<HeapObject> collection,
49-
TNode<Object> initial_entries);
50-
51-
// Fast path for adding constructor entries. Assumes the entries are a fast
52-
// JS array (see CodeStubAssembler::BranchIfFastJSArray()).
53-
void AddConstructorEntriesFromFastJSArray(Variant variant,
54-
TNode<Context> context,
55-
TNode<Context> native_context,
56-
TNode<Object> collection,
57-
TNode<JSArray> fast_jsarray,
58-
Label* if_may_have_side_effects);
59-
60-
// Adds constructor entries to a collection using the iterator protocol.
61-
void AddConstructorEntriesFromIterable(Variant variant,
62-
TNode<Context> context,
63-
TNode<Context> native_context,
64-
TNode<Object> collection,
65-
TNode<Object> iterable);
66-
67-
// Constructs a collection instance. Choosing a fast path when possible.
68-
TNode<JSObject> AllocateJSCollection(TNode<Context> context,
69-
TNode<JSFunction> constructor,
70-
TNode<JSReceiver> new_target);
71-
72-
// Fast path for constructing a collection instance if the constructor
73-
// function has not been modified.
74-
TNode<JSObject> AllocateJSCollectionFast(TNode<JSFunction> constructor);
75-
76-
// Fallback for constructing a collection instance if the constructor function
77-
// has been modified.
78-
TNode<JSObject> AllocateJSCollectionSlow(TNode<Context> context,
79-
TNode<JSFunction> constructor,
80-
TNode<JSReceiver> new_target);
81-
82-
// Allocates the backing store for a collection.
83-
virtual TNode<HeapObject> AllocateTable(
84-
Variant variant, TNode<IntPtrT> at_least_space_for) = 0;
85-
86-
// Main entry point for a collection constructor builtin.
87-
void GenerateConstructor(Variant variant,
88-
Handle<String> constructor_function_name,
89-
TNode<Object> new_target, TNode<IntPtrT> argc,
90-
TNode<Context> context);
91-
92-
// Retrieves the collection function that adds an entry. `set` for Maps and
93-
// `add` for Sets.
94-
TNode<Object> GetAddFunction(Variant variant, TNode<Context> context,
95-
TNode<Object> collection);
96-
97-
// Retrieves the collection constructor function.
98-
TNode<JSFunction> GetConstructor(Variant variant,
99-
TNode<Context> native_context);
100-
101-
// Retrieves the initial collection function that adds an entry. Should only
102-
// be called when it is certain that a collection prototype's map hasn't been
103-
// changed.
104-
TNode<JSFunction> GetInitialAddFunction(Variant variant,
105-
TNode<Context> native_context);
106-
107-
// Checks whether {collection}'s initial add/set function has been modified
108-
// (depending on {variant}, loaded from {native_context}).
109-
void GotoIfInitialAddFunctionModified(Variant variant,
110-
TNode<NativeContext> native_context,
111-
TNode<HeapObject> collection,
112-
Label* if_modified);
113-
114-
// Gets root index for the name of the add/set function.
115-
RootIndex GetAddFunctionNameIndex(Variant variant);
116-
117-
// Retrieves the offset to access the backing table from the collection.
118-
int GetTableOffset(Variant variant);
119-
120-
// Estimates the number of entries the collection will have after adding the
121-
// entries passed in the constructor. AllocateTable() can use this to avoid
122-
// the time of growing/rehashing when adding the constructor entries.
123-
TNode<IntPtrT> EstimatedInitialSize(TNode<Object> initial_entries,
124-
TNode<BoolT> is_fast_jsarray);
125-
126-
void GotoIfCannotBeWeakKey(const TNode<Object> obj,
127-
Label* if_cannot_be_weak_key);
128-
129-
// Determines whether the collection's prototype has been modified.
130-
TNode<BoolT> HasInitialCollectionPrototype(Variant variant,
131-
TNode<Context> native_context,
132-
TNode<Object> collection);
133-
134-
// Gets the initial prototype map for given collection {variant}.
135-
TNode<Map> GetInitialCollectionPrototype(Variant variant,
136-
TNode<Context> native_context);
137-
138-
// Loads an element from a fixed array. If the element is the hole, returns
139-
// `undefined`.
140-
TNode<Object> LoadAndNormalizeFixedArrayElement(TNode<FixedArray> elements,
141-
TNode<IntPtrT> index);
142-
143-
// Loads an element from a fixed double array. If the element is the hole,
144-
// returns `undefined`.
145-
TNode<Object> LoadAndNormalizeFixedDoubleArrayElement(
146-
TNode<HeapObject> elements, TNode<IntPtrT> index);
147-
};
148-
14925
void BaseCollectionsAssembler::AddConstructorEntry(
15026
Variant variant, TNode<Context> context, TNode<Object> collection,
15127
TNode<Object> add_function, TNode<Object> key_value,
@@ -525,12 +401,23 @@ TNode<IntPtrT> BaseCollectionsAssembler::EstimatedInitialSize(
525401

526402
void BaseCollectionsAssembler::GotoIfCannotBeWeakKey(
527403
const TNode<Object> obj, Label* if_cannot_be_weak_key) {
404+
Label check_symbol_key(this);
405+
Label end(this);
528406
GotoIf(TaggedIsSmi(obj), if_cannot_be_weak_key);
529407
TNode<Uint16T> instance_type = LoadMapInstanceType(LoadMap(CAST(obj)));
530-
GotoIfNot(IsJSReceiverInstanceType(instance_type), if_cannot_be_weak_key);
408+
GotoIfNot(IsJSReceiverInstanceType(instance_type), &check_symbol_key);
531409
// TODO(v8:12547) Shared structs should only be able to point to shared values
532410
// in weak collections. For now, disallow them as weak collection keys.
533411
GotoIf(IsJSSharedStructInstanceType(instance_type), if_cannot_be_weak_key);
412+
Goto(&end);
413+
Bind(&check_symbol_key);
414+
GotoIfNot(HasHarmonySymbolAsWeakmapKeyFlag(), if_cannot_be_weak_key);
415+
GotoIfNot(IsSymbolInstanceType(instance_type), if_cannot_be_weak_key);
416+
TNode<Uint32T> flags = LoadSymbolFlags(CAST(obj));
417+
GotoIf(Word32And(flags, Symbol::IsInPublicSymbolTableBit::kMask),
418+
if_cannot_be_weak_key);
419+
Goto(&end);
420+
Bind(&end);
534421
}
535422

536423
TNode<Map> BaseCollectionsAssembler::GetInitialCollectionPrototype(
@@ -2427,67 +2314,6 @@ TF_BUILTIN(FindOrderedHashMapEntry, CollectionsBuiltinsAssembler) {
24272314
Return(SmiConstant(-1));
24282315
}
24292316

2430-
class WeakCollectionsBuiltinsAssembler : public BaseCollectionsAssembler {
2431-
public:
2432-
explicit WeakCollectionsBuiltinsAssembler(compiler::CodeAssemblerState* state)
2433-
: BaseCollectionsAssembler(state) {}
2434-
2435-
protected:
2436-
void AddEntry(TNode<EphemeronHashTable> table, TNode<IntPtrT> key_index,
2437-
TNode<Object> key, TNode<Object> value,
2438-
TNode<IntPtrT> number_of_elements);
2439-
2440-
TNode<HeapObject> AllocateTable(Variant variant,
2441-
TNode<IntPtrT> at_least_space_for) override;
2442-
2443-
// Generates and sets the identity for a JSRececiver.
2444-
TNode<Smi> CreateIdentityHash(TNode<Object> receiver);
2445-
TNode<IntPtrT> EntryMask(TNode<IntPtrT> capacity);
2446-
2447-
// Builds code that finds the EphemeronHashTable entry for a {key} using the
2448-
// comparison code generated by {key_compare}. The key index is returned if
2449-
// the {key} is found.
2450-
using KeyComparator =
2451-
std::function<void(TNode<Object> entry_key, Label* if_same)>;
2452-
TNode<IntPtrT> FindKeyIndex(TNode<HeapObject> table, TNode<IntPtrT> key_hash,
2453-
TNode<IntPtrT> entry_mask,
2454-
const KeyComparator& key_compare);
2455-
2456-
// Builds code that finds an EphemeronHashTable entry available for a new
2457-
// entry.
2458-
TNode<IntPtrT> FindKeyIndexForInsertion(TNode<HeapObject> table,
2459-
TNode<IntPtrT> key_hash,
2460-
TNode<IntPtrT> entry_mask);
2461-
2462-
// Builds code that finds the EphemeronHashTable entry with key that matches
2463-
// {key} and returns the entry's key index. If {key} cannot be found, jumps to
2464-
// {if_not_found}.
2465-
TNode<IntPtrT> FindKeyIndexForKey(TNode<HeapObject> table, TNode<Object> key,
2466-
TNode<IntPtrT> hash,
2467-
TNode<IntPtrT> entry_mask,
2468-
Label* if_not_found);
2469-
2470-
TNode<Word32T> InsufficientCapacityToAdd(TNode<IntPtrT> capacity,
2471-
TNode<IntPtrT> number_of_elements,
2472-
TNode<IntPtrT> number_of_deleted);
2473-
TNode<IntPtrT> KeyIndexFromEntry(TNode<IntPtrT> entry);
2474-
2475-
TNode<IntPtrT> LoadNumberOfElements(TNode<EphemeronHashTable> table,
2476-
int offset);
2477-
TNode<IntPtrT> LoadNumberOfDeleted(TNode<EphemeronHashTable> table,
2478-
int offset = 0);
2479-
TNode<EphemeronHashTable> LoadTable(TNode<JSWeakCollection> collection);
2480-
TNode<IntPtrT> LoadTableCapacity(TNode<EphemeronHashTable> table);
2481-
2482-
void RemoveEntry(TNode<EphemeronHashTable> table, TNode<IntPtrT> key_index,
2483-
TNode<IntPtrT> number_of_elements);
2484-
TNode<BoolT> ShouldRehash(TNode<IntPtrT> number_of_elements,
2485-
TNode<IntPtrT> number_of_deleted);
2486-
TNode<Word32T> ShouldShrink(TNode<IntPtrT> capacity,
2487-
TNode<IntPtrT> number_of_elements);
2488-
TNode<IntPtrT> ValueIndexFromKeyIndex(TNode<IntPtrT> key_index);
2489-
};
2490-
24912317
void WeakCollectionsBuiltinsAssembler::AddEntry(
24922318
TNode<EphemeronHashTable> table, TNode<IntPtrT> key_index,
24932319
TNode<Object> key, TNode<Object> value, TNode<IntPtrT> number_of_elements) {
@@ -2503,6 +2329,25 @@ void WeakCollectionsBuiltinsAssembler::AddEntry(
25032329
SmiFromIntPtr(number_of_elements));
25042330
}
25052331

2332+
TNode<IntPtrT> WeakCollectionsBuiltinsAssembler::GetHash(
2333+
const TNode<HeapObject> key, Label* if_no_hash) {
2334+
TVARIABLE(IntPtrT, var_hash);
2335+
Label if_symbol(this);
2336+
Label return_result(this);
2337+
GotoIfNot(IsJSReceiver(key), &if_symbol);
2338+
var_hash = LoadJSReceiverIdentityHash(CAST(key), if_no_hash);
2339+
Goto(&return_result);
2340+
Bind(&if_symbol);
2341+
CSA_DCHECK(this, IsSymbol(key));
2342+
CSA_DCHECK(this, Word32BinaryNot(
2343+
Word32And(LoadSymbolFlags(CAST(key)),
2344+
Symbol::IsInPublicSymbolTableBit::kMask)));
2345+
var_hash = ChangeInt32ToIntPtr(LoadNameHash(CAST(key), nullptr));
2346+
Goto(&return_result);
2347+
Bind(&return_result);
2348+
return var_hash.value();
2349+
}
2350+
25062351
TNode<HeapObject> WeakCollectionsBuiltinsAssembler::AllocateTable(
25072352
Variant variant, TNode<IntPtrT> at_least_space_for) {
25082353
// See HashTable::New().
@@ -2732,8 +2577,7 @@ TF_BUILTIN(WeakMapLookupHashIndex, WeakCollectionsBuiltinsAssembler) {
27322577

27332578
GotoIfCannotBeWeakKey(key, &if_cannot_be_weak_key);
27342579

2735-
TNode<IntPtrT> hash =
2736-
LoadJSReceiverIdentityHash(CAST(key), &if_cannot_be_weak_key);
2580+
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_weak_key);
27372581
TNode<IntPtrT> capacity = LoadTableCapacity(table);
27382582
TNode<IntPtrT> key_index = FindKeyIndexForKey(
27392583
table, key, hash, EntryMask(capacity), &if_cannot_be_weak_key);
@@ -2798,8 +2642,7 @@ TF_BUILTIN(WeakCollectionDelete, WeakCollectionsBuiltinsAssembler) {
27982642

27992643
GotoIfCannotBeWeakKey(key, &if_cannot_be_weak_key);
28002644

2801-
TNode<IntPtrT> hash =
2802-
LoadJSReceiverIdentityHash(CAST(key), &if_cannot_be_weak_key);
2645+
TNode<IntPtrT> hash = GetHash(CAST(key), &if_cannot_be_weak_key);
28032646
TNode<EphemeronHashTable> table = LoadTable(collection);
28042647
TNode<IntPtrT> capacity = LoadTableCapacity(table);
28052648
TNode<IntPtrT> key_index = FindKeyIndexForKey(
@@ -2823,18 +2666,18 @@ TF_BUILTIN(WeakCollectionDelete, WeakCollectionsBuiltinsAssembler) {
28232666
TF_BUILTIN(WeakCollectionSet, WeakCollectionsBuiltinsAssembler) {
28242667
auto context = Parameter<Context>(Descriptor::kContext);
28252668
auto collection = Parameter<JSWeakCollection>(Descriptor::kCollection);
2826-
auto key = Parameter<JSReceiver>(Descriptor::kKey);
2669+
auto key = Parameter<HeapObject>(Descriptor::kKey);
28272670
auto value = Parameter<Object>(Descriptor::kValue);
28282671

2829-
CSA_DCHECK(this, IsJSReceiver(key));
2672+
CSA_DCHECK(this, Word32Or(IsJSReceiver(key), IsSymbol(key)));
28302673

28312674
Label call_runtime(this), if_no_hash(this), if_not_found(this);
28322675

28332676
TNode<EphemeronHashTable> table = LoadTable(collection);
28342677
TNode<IntPtrT> capacity = LoadTableCapacity(table);
28352678
TNode<IntPtrT> entry_mask = EntryMask(capacity);
28362679

2837-
TVARIABLE(IntPtrT, var_hash, LoadJSReceiverIdentityHash(key, &if_no_hash));
2680+
TVARIABLE(IntPtrT, var_hash, GetHash(key, &if_no_hash));
28382681
TNode<IntPtrT> key_index = FindKeyIndexForKey(table, key, var_hash.value(),
28392682
entry_mask, &if_not_found);
28402683

@@ -2843,6 +2686,7 @@ TF_BUILTIN(WeakCollectionSet, WeakCollectionsBuiltinsAssembler) {
28432686

28442687
BIND(&if_no_hash);
28452688
{
2689+
CSA_DCHECK(this, IsJSReceiver(key));
28462690
var_hash = SmiUntag(CreateIdentityHash(key));
28472691
Goto(&if_not_found);
28482692
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy