v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
hash-table.h
Go to the documentation of this file.
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_HASH_TABLE_H_
6#define V8_OBJECTS_HASH_TABLE_H_
7
10#include "src/base/macros.h"
11#include "src/common/globals.h"
14#include "src/objects/smi.h"
16#include "src/roots/roots.h"
17
18// Has to be the last include (doesn't have include guards):
20
21namespace v8 {
22namespace internal {
23
24// HashTable is a subclass of FixedArray that implements a hash table
25// that uses open addressing and quadratic probing.
26//
27// In order for the quadratic probing to work, elements that have not
28// yet been used and elements that have been deleted are
29// distinguished. Probing continues when deleted elements are
30// encountered and stops when unused elements are encountered.
31//
32// - Elements with key == undefined have not been used yet.
33// - Elements with key == the_hole have been deleted.
34//
35// The hash table class is parameterized with a Shape.
36// Shape must be a class with the following interface:
37// class ExampleShape {
38// public:
39// // Tells whether key matches other.
40// static bool IsMatch(Key key, Tagged<Object> other);
41// // Returns the hash value for key.
42// static uint32_t Hash(ReadOnlyRoots roots, Key key);
43// // Returns the hash value for object.
44// static uint32_t HashForObject(ReadOnlyRoots roots,
45// Tagged<Object> object);
46// // Convert key to an object.
47// static inline DirectHandle<Object> AsHandle(Isolate* isolate, Key key);
48// // The prefix size indicates number of elements in the beginning
49// // of the backing storage.
50// static const int kPrefixSize = ..;
51// // The Element size indicates number of elements per entry.
52// static const int kEntrySize = ..;
53// // Indicates whether IsMatch can deal with other being the_hole (a
54// // deleted entry).
55// static const bool kMatchNeedsHoleCheck = ..;
56// };
57// The prefix size indicates an amount of memory in the
58// beginning of the backing storage that can be used for non-element
59// information by subclasses.
60
61template <typename KeyT>
63 public:
64 using Key = KeyT;
66};
67
69 public:
70 // Returns the number of elements in the hash table.
71 inline int NumberOfElements() const;
72
73 // Returns the number of deleted elements in the hash table.
74 inline int NumberOfDeletedElements() const;
75
76 // Returns the capacity of the hash table.
77 inline int Capacity() const;
78
79 inline InternalIndex::Range IterateEntries() const;
80
81 // ElementAdded should be called whenever an element is added to a
82 // hash table.
83 inline void ElementAdded();
84
85 // ElementRemoved should be called whenever an element is removed from
86 // a hash table.
87 inline void ElementRemoved();
88 inline void ElementsRemoved(int n);
89
90 // Computes the required capacity for a table holding the given
91 // number of elements. May be more than HashTable::kMaxCapacity.
92 static inline int ComputeCapacity(int at_least_space_for);
93
94 static const int kNumberOfElementsIndex = 0;
95 static const int kNumberOfDeletedElementsIndex = 1;
96 static const int kCapacityIndex = 2;
97 static const int kPrefixStartIndex = 3;
98
99 // Minimum capacity for newly created hash tables.
100 static const int kMinCapacity = 4;
101
102 // Set the number of elements in the hash table after a bulk of elements was
103 // added.
104 inline void SetInitialNumberOfElements(int nof);
105
106 protected:
107 // Update the number of elements in the hash table.
108 inline void SetNumberOfElements(int nof);
109
110 // Update the number of deleted elements in the hash table.
111 inline void SetNumberOfDeletedElements(int nod);
112
113 inline static InternalIndex NextProbe(InternalIndex last, uint32_t number,
114 uint32_t size) {
115 return InternalIndex((last.as_uint32() + number) & (size - 1));
116 }
117};
118
119template <typename Derived, typename ShapeT>
120class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
121 : public HashTableBase {
122 public:
123 // TODO(jgruber): Derive from TaggedArrayBase instead of FixedArray, and
124 // merge with TaggedArrayBase's Shape class. Once the naming conflict is
125 // resolved rename all TodoShape occurrences back to Shape.
126 using TodoShape = ShapeT;
127 using Key = typename TodoShape::Key;
128
129 // Returns a new HashTable object.
130 template <typename IsolateT>
132 IsolateT* isolate, int at_least_space_for,
133 AllocationType allocation = AllocationType::kYoung,
134 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
135
136 static inline DirectHandle<Map> GetMap(RootsTable& roots);
137
138 // Garbage collection support.
139 void IteratePrefix(ObjectVisitor* visitor);
140 void IterateElements(ObjectVisitor* visitor);
141
142 // Returns probe entry.
143 inline static InternalIndex FirstProbe(uint32_t hash, uint32_t size) {
144 if (!TodoShape::kDoHashSpreading || size <= (1u << TodoShape::kHashBits)) {
145 return InternalIndex(hash & (size - 1));
146 }
147 // If the hash only has N bits and size is large, the hashes will all be
148 // clustered at the beginning of the hash table. This distributes the
149 // items more evenly and makes the lookup chains shorter.
150 DCHECK_GE(TodoShape::kHashBits, 1);
151 DCHECK_LE(TodoShape::kHashBits, 32);
152 uint32_t coefficient = size >> TodoShape::kHashBits;
153 DCHECK_GE(coefficient, 2);
154 return InternalIndex((hash * coefficient) & (size - 1));
155 }
156
157 // Find entry for key otherwise return kNotFound.
158 inline InternalIndex FindEntry(PtrComprCageBase cage_base,
159 ReadOnlyRoots roots, Key key, int32_t hash);
160 template <typename IsolateT>
161 inline InternalIndex FindEntry(IsolateT* isolate, Key key);
162
163 // Rehashes the table in-place.
164 void Rehash(PtrComprCageBase cage_base);
165
166 // Returns whether k is a real key. The hole and undefined are not allowed as
167 // keys and can be used to indicate missing or deleted elements.
168 static inline bool IsKey(ReadOnlyRoots roots, Tagged<Object> k);
169
170 inline bool ToKey(ReadOnlyRoots roots, InternalIndex entry,
171 Tagged<Object>* out_k);
172 inline bool ToKey(PtrComprCageBase cage_base, InternalIndex entry,
173 Tagged<Object>* out_k);
174
175 // Returns the key at entry.
176 inline Tagged<Object> KeyAt(InternalIndex entry);
177 inline Tagged<Object> KeyAt(PtrComprCageBase cage_base, InternalIndex entry);
178 inline Tagged<Object> KeyAt(InternalIndex entry, RelaxedLoadTag tag);
179 inline Tagged<Object> KeyAt(PtrComprCageBase cage_base, InternalIndex entry,
180 RelaxedLoadTag tag);
181
182 inline void SetKeyAt(InternalIndex entry, Tagged<Object> value,
183 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
184
185 static const int kElementsStartIndex =
186 kPrefixStartIndex + TodoShape::kPrefixSize;
187 static const int kEntrySize = TodoShape::kEntrySize;
188 static_assert(kEntrySize > 0);
189 static const int kEntryKeyIndex = 0;
190 static const int kElementsStartOffset =
191 OFFSET_OF_DATA_START(HashTableBase) + kElementsStartIndex * kTaggedSize;
192 // Maximal capacity of HashTable. Based on maximal length of underlying
193 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
194 // cannot overflow.
195 static const int kMaxCapacity =
196 (FixedArray::kMaxLength - kElementsStartIndex) / kEntrySize;
197
198 // Don't shrink a HashTable below this capacity.
199 static const int kMinShrinkCapacity = 16;
200
201 // Pretenure hashtables above this capacity.
202 static const int kMinCapacityForPretenure = 256;
203
204 static const int kMaxRegularCapacity = kMaxRegularHeapObjectSize / 32;
205
206 // Returns the index for an entry (of the key)
207 static constexpr inline int EntryToIndex(InternalIndex entry) {
208 return (entry.as_int() * kEntrySize) + kElementsStartIndex;
209 }
210
211 // Returns the entry for an index (of the key)
212 static constexpr inline InternalIndex IndexToEntry(int index) {
213 return InternalIndex((index - kElementsStartIndex) / kEntrySize);
214 }
215
216 // Returns the index for a slot address in the object.
217 static constexpr inline int SlotToIndex(Address object, Address slot) {
218 return static_cast<int>((slot - object - sizeof(HashTableBase)) /
220 }
221
222 // Ensure enough space for n additional elements.
223 template <typename IsolateT, template <typename> typename HandleType>
224 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
225 V8_WARN_UNUSED_RESULT static HandleType<Derived> EnsureCapacity(
226 IsolateT* isolate, HandleType<Derived> table, int n = 1,
227 AllocationType allocation = AllocationType::kYoung);
228
229 // Returns true if this table has sufficient capacity for adding n elements.
230 bool HasSufficientCapacityToAdd(int number_of_additional_elements);
231
232 // Returns true if a table with the given parameters has sufficient capacity
233 // for adding n elements. Can be used to check hypothetical capacities without
234 // actually allocating a table with that capacity.
235 static bool HasSufficientCapacityToAdd(int capacity, int number_of_elements,
236 int number_of_deleted_elements,
237 int number_of_additional_elements);
238
239 protected:
240 friend class ObjectHashTable;
241
242 template <typename IsolateT>
243 V8_WARN_UNUSED_RESULT static Handle<Derived> NewInternal(
244 IsolateT* isolate, int capacity, AllocationType allocation);
245
246 // Find the entry at which to insert element with the given key that
247 // has the given hash value.
248 InternalIndex FindInsertionEntry(PtrComprCageBase cage_base,
249 ReadOnlyRoots roots, uint32_t hash);
250 template <typename IsolateT>
251 InternalIndex FindInsertionEntry(IsolateT* isolate, uint32_t hash);
252
253 // Computes the capacity a table with the given capacity would need to have
254 // room for the given number of elements, also allowing it to shrink.
255 static int ComputeCapacityWithShrink(int current_capacity,
256 int at_least_room_for);
257
258 // Shrink the hash table.
259 template <template <typename> typename HandleType>
260 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
261 V8_WARN_UNUSED_RESULT static HandleType<Derived> Shrink(
262 Isolate* isolate, HandleType<Derived> table, int additionalCapacity = 0);
263
264 // Rehashes this hash-table into the new table.
265 void Rehash(PtrComprCageBase cage_base, Tagged<Derived> new_table);
266
267 inline void set_key(int index, Tagged<Object> value);
268 inline void set_key(int index, Tagged<Object> value, WriteBarrierMode mode);
269
270 private:
271 // Ensure that kMaxRegularCapacity yields a non-large object dictionary.
272 static_assert(EntryToIndex(InternalIndex(kMaxRegularCapacity)) <
273 FixedArray::kMaxRegularLength);
274 static_assert(v8::base::bits::IsPowerOfTwo(kMaxRegularCapacity));
275 static const int kMaxRegularEntry = kMaxRegularCapacity / kEntrySize;
276 static const int kMaxRegularIndex =
277 EntryToIndex(InternalIndex(kMaxRegularEntry));
278 static_assert(OffsetOfElementAt(kMaxRegularIndex) <
280
281 // Sets the capacity of the hash table.
282 inline void SetCapacity(int capacity);
283
284 // Returns _expected_ if one of entries given by the first _probe_ probes is
285 // equal to _expected_. Otherwise, returns the entry given by the probe
286 // number _probe_.
287 InternalIndex EntryForProbe(ReadOnlyRoots roots, Tagged<Object> k, int probe,
288 InternalIndex expected);
289
290 void Swap(InternalIndex entry1, InternalIndex entry2, WriteBarrierMode mode);
291};
292
293#define EXTERN_DECLARE_HASH_TABLE(DERIVED, SHAPE) \
294 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
295 HashTable<class DERIVED, SHAPE>; \
296 \
297 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
298 HashTable<DERIVED, SHAPE>::New(Isolate*, int, AllocationType, \
299 MinimumCapacity); \
300 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
301 HashTable<DERIVED, SHAPE>::New(LocalIsolate*, int, AllocationType, \
302 MinimumCapacity); \
303 \
304 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
305 HashTable<DERIVED, SHAPE>::EnsureCapacity(Isolate*, Handle<DERIVED>, int, \
306 AllocationType); \
307 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
308 HashTable<DERIVED, SHAPE>::EnsureCapacity(LocalIsolate*, Handle<DERIVED>, \
309 int, AllocationType); \
310 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
311 DirectHandle<DERIVED> \
312 HashTable<DERIVED, SHAPE>::EnsureCapacity( \
313 Isolate*, DirectHandle<DERIVED>, int, AllocationType); \
314 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
315 DirectHandle<DERIVED> \
316 HashTable<DERIVED, SHAPE>::EnsureCapacity( \
317 LocalIsolate*, DirectHandle<DERIVED>, int, AllocationType); \
318 \
319 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
320 HashTable<DERIVED, SHAPE>::Shrink(Isolate*, Handle<DERIVED>, int); \
321 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
322 DirectHandle<DERIVED> \
323 HashTable<DERIVED, SHAPE>::Shrink(Isolate*, DirectHandle<DERIVED>, int);
324
325// HashTableKey is an abstract superclass for virtual key behavior.
327 public:
328 explicit HashTableKey(uint32_t hash) : hash_(hash) {}
329
330 // Returns whether the other object matches this key.
331 virtual bool IsMatch(Tagged<Object> other) = 0;
332 // Returns the hash value for this key.
333 // Required.
334 virtual ~HashTableKey() = default;
335
336 uint32_t Hash() const { return hash_; }
337
338 protected:
339 void set_hash(uint32_t hash) {
340 DCHECK_EQ(0, hash_);
341 hash_ = hash;
342 }
343
344 private:
345 uint32_t hash_ = 0;
346};
347
348class ObjectHashTableShapeBase : public BaseShape<DirectHandle<Object>> {
349 public:
350 static inline bool IsMatch(DirectHandle<Object> key, Tagged<Object> other);
351 static inline uint32_t Hash(ReadOnlyRoots roots, DirectHandle<Object> key);
352 static inline uint32_t HashForObject(ReadOnlyRoots roots,
353 Tagged<Object> object);
354 static inline DirectHandle<Object> AsHandle(DirectHandle<Object> key);
355 static const int kPrefixSize = 0;
356 static const int kEntryValueIndex = 1;
357 static const int kEntrySize = 2;
358 static const bool kMatchNeedsHoleCheck = false;
359};
360
362 public:
363 // TODO(marja): Investigate whether adding hash spreading here would help
364 // other use cases.
365 static const bool kDoHashSpreading = false;
366 static const uint32_t kHashBits = 0;
367};
368
370 public:
371 // To support large WeakMaps, spread the probes more evenly if the hash table
372 // is big and we don't have enough hash bits to cover it all. This needs to be
373 // in sync with code generated by WeakCollectionsBuiltinsAssembler.
374 static const bool kDoHashSpreading = true;
375 static const uint32_t kHashBits;
376};
377
378template <typename Derived, typename Shape>
379class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) ObjectHashTableBase
380 : public HashTable<Derived, Shape> {
381 public:
382 // Looks up the value associated with the given key. The hole value is
383 // returned in case the key is not present.
385 Tagged<Object> Lookup(DirectHandle<Object> key, int32_t hash);
387 int32_t hash);
388
389 // Returns the value at entry.
390 Tagged<Object> ValueAt(InternalIndex entry);
391
392 // Overwrite all keys and values with the hole value.
393 static void FillEntriesWithHoles(DirectHandle<Derived>);
394
395 // Adds (or overwrites) the value associated with the given key.
398 static Handle<Derived> Put(Isolate* isolate, Handle<Derived> table,
400 DirectHandle<Object> value, int32_t hash);
401
402 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
403 static Handle<Derived> Remove(Isolate* isolate, Handle<Derived> table,
404 DirectHandle<Object> key, bool* was_present);
405 static Handle<Derived> Remove(Isolate* isolate, Handle<Derived> table,
406 DirectHandle<Object> key, bool* was_present,
407 int32_t hash);
408
409 // Returns the index to the value of an entry.
410 static inline int EntryToValueIndex(InternalIndex entry) {
411 return HashTable<Derived, Shape>::EntryToIndex(entry) +
412 Shape::kEntryValueIndex;
413 }
414
415 protected:
416 void AddEntry(InternalIndex entry, Tagged<Object> key, Tagged<Object> value);
417 void RemoveEntry(InternalIndex entry);
418};
419
420#define EXTERN_DECLARE_OBJECT_BASE_HASH_TABLE(DERIVED, SHAPE) \
421 EXTERN_DECLARE_HASH_TABLE(DERIVED, SHAPE) \
422 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
423 ObjectHashTableBase<class DERIVED, SHAPE>;
424
425EXTERN_DECLARE_OBJECT_BASE_HASH_TABLE(ObjectHashTable, ObjectHashTableShape)
426
427// ObjectHashTable maps keys that are arbitrary objects to object values by
428// using the identity hash of the key for hashing purposes.
430 : public ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape> {
431 public:
433};
434
437
438// EphemeronHashTable is similar to ObjectHashTable but gets special treatment
439// by the GC. The GC treats its entries as ephemerons: both key and value are
440// weak references, however if the key is strongly reachable its corresponding
441// value is also kept alive.
442class V8_EXPORT_PRIVATE EphemeronHashTable
443 : public ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape> {
444 public:
445 static inline Handle<Map> GetMap(RootsTable& roots);
446
447 DECL_PRINTER(EphemeronHashTable)
448 class BodyDescriptor;
449
450 protected:
451 friend class MarkCompactCollector;
452 friend class MinorMarkSweepCollector;
453 friend class ScavengerCollector;
454 friend class HashTable<EphemeronHashTable, EphemeronHashTableShape>;
455 friend class ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>;
456 inline void set_key(int index, Tagged<Object> value);
457 inline void set_key(int index, Tagged<Object> value, WriteBarrierMode mode);
458};
459
460// ObjectMultihashTable is a hash table that maps Object keys to N Object
461// values. The Object values are stored inline in the underlying FixedArray.
462//
463// This is not a generic multimap where each key can map to a variable number of
464// values. Each key always maps to exactly N values.
465template <int N>
467 public:
468 static const int kEntrySize = 1 + N;
469};
470
471template <typename Derived, int N>
473 : public HashTable<Derived, ObjectMultiHashTableShape<N>> {
474 public:
475 static_assert(N > 1, "use ObjectHashTable instead if N = 1");
476
477 // Returns the values associated with the given key. Return an std::array of
478 // holes if not found.
479 std::array<Tagged<Object>, N> Lookup(DirectHandle<Object> key);
480 std::array<Tagged<Object>, N> Lookup(PtrComprCageBase cage_base,
482
483 // Adds or overwrites the values associated with the given key.
484 static Handle<Derived> Put(Isolate* isolate, Handle<Derived> table,
486 const std::array<DirectHandle<Object>, N>& values);
487
488 private:
489 void SetEntryValues(InternalIndex entry,
490 const std::array<DirectHandle<Object>, N>& values);
491
492 static constexpr inline int EntryToValueIndexStart(InternalIndex entry) {
493 return HashTable<Derived, ObjectMultiHashTableShape<N>>::EntryToIndex(
494 entry) +
496 }
497};
498
500 : public ObjectMultiHashTableBase<ObjectTwoHashTable, 2> {
501};
502
504 public:
505 static const int kPrefixSize = 0;
506 static const int kEntrySize = 1;
507};
508
510
512 : public HashTable<ObjectHashSet, ObjectHashSetShape> {
513 public:
514 static Handle<ObjectHashSet> Add(Isolate* isolate, Handle<ObjectHashSet> set,
516
517 inline bool Has(Isolate* isolate, DirectHandle<Object> key, int32_t hash);
518 inline bool Has(Isolate* isolate, DirectHandle<Object> key);
519};
520
521class NameToIndexShape : public BaseShape<DirectHandle<Name>> {
522 public:
523 static inline bool IsMatch(DirectHandle<Name> key, Tagged<Object> other);
524 static inline uint32_t Hash(ReadOnlyRoots roots, DirectHandle<Name> key);
525 static inline uint32_t HashForObject(ReadOnlyRoots roots,
526 Tagged<Object> object);
528 static const int kPrefixSize = 0;
529 static const int kEntryValueIndex = 1;
530 static const int kEntrySize = 2;
531 static const bool kMatchNeedsHoleCheck = false;
532 static const bool kDoHashSpreading = false;
533 static const uint32_t kHashBits = 0;
534};
535
537 : public HashTable<NameToIndexHashTable, NameToIndexShape> {
538 public:
539 static const int kEntryValueIndex = NameToIndexShape::kEntryValueIndex;
540
541 inline static DirectHandle<Map> GetMap(RootsTable& roots);
542 int Lookup(DirectHandle<Name> key);
543
544 // Returns the value at entry.
545 Tagged<Object> ValueAt(InternalIndex entry);
546 int IndexAt(InternalIndex entry);
547
548 template <typename IsolateT>
549 static Handle<NameToIndexHashTable> Add(IsolateT* isolate,
552 int32_t value);
553
554 // Exposed for NameDictionaryLookupForwardedString slow path for forwarded
555 // strings.
556 using HashTable<NameToIndexHashTable, NameToIndexShape>::FindInsertionEntry;
557
559
560 private:
561 static inline int EntryToValueIndex(InternalIndex entry) {
562 return EntryToIndex(entry) + NameToIndexShape::kEntryValueIndex;
563 }
564};
565
566class RegisteredSymbolTableShape : public BaseShape<DirectHandle<String>> {
567 public:
568 static inline bool IsMatch(DirectHandle<String> key, Tagged<Object> other);
569 static inline uint32_t Hash(ReadOnlyRoots roots, DirectHandle<String> key);
570 static inline uint32_t HashForObject(ReadOnlyRoots roots,
571 Tagged<Object> object);
572 static const int kPrefixSize = 0;
573 static const int kEntryValueIndex = 1;
574 static const int kEntrySize = 2;
575 static const bool kMatchNeedsHoleCheck = false;
576 static const bool kDoHashSpreading = false;
577 static const uint32_t kHashBits = 0;
578};
579
581 : public HashTable<RegisteredSymbolTable, RegisteredSymbolTableShape> {
582 public:
583 Tagged<Object> SlowReverseLookup(Tagged<Object> value);
584
585 // Returns the value at entry.
586 Tagged<Object> ValueAt(InternalIndex entry);
587
588 inline static DirectHandle<Map> GetMap(RootsTable& roots);
589
590 static Handle<RegisteredSymbolTable> Add(Isolate* isolate,
594
596
597 private:
598 static inline int EntryToValueIndex(InternalIndex entry) {
599 return EntryToIndex(entry) + RegisteredSymbolTableShape::kEntryValueIndex;
600 }
601};
602
603} // namespace internal
604} // namespace v8
605
607
608#endif // V8_OBJECTS_HASH_TABLE_H_
static Tagged< Object > Unwrap(Tagged< Object > key)
Definition hash-table.h:65
static InternalIndex NextProbe(InternalIndex last, uint32_t number, uint32_t size)
Definition hash-table.h:113
virtual bool IsMatch(Tagged< Object > other)=0
uint32_t Hash() const
Definition hash-table.h:336
HashTableKey(uint32_t hash)
Definition hash-table.h:328
void set_hash(uint32_t hash)
Definition hash-table.h:339
virtual ~HashTableKey()=default
static int EntryToValueIndex(InternalIndex entry)
Definition hash-table.h:561
static DirectHandle< Object > AsHandle(DirectHandle< Name > key)
static constexpr int EntryToValueIndexStart(InternalIndex entry)
Definition hash-table.h:492
static int EntryToValueIndex(InternalIndex entry)
Definition hash-table.h:598
#define EXTERN_DECLARE_HASH_TABLE(DERIVED, SHAPE)
Definition hash-table.h:293
#define EXTERN_DECLARE_OBJECT_BASE_HASH_TABLE(DERIVED, SHAPE)
Definition hash-table.h:420
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
constexpr int kTaggedSize
Definition globals.h:542
constexpr int kMaxRegularHeapObjectSize
Definition globals.h:680
constexpr int N
#define DECL_PRINTER(Name)
#define NON_EXPORTED_BASE(code)
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define OFFSET_OF_DATA_START(Type)
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
std::unique_ptr< ValueMirror > key