5#ifndef V8_OBJECTS_HASH_TABLE_H_
6#define V8_OBJECTS_HASH_TABLE_H_
61template <
typename KeyT>
71 inline int NumberOfElements()
const;
74 inline int NumberOfDeletedElements()
const;
77 inline int Capacity()
const;
83 inline void ElementAdded();
87 inline void ElementRemoved();
88 inline void ElementsRemoved(
int n);
92 static inline int ComputeCapacity(
int at_least_space_for);
94 static const int kNumberOfElementsIndex = 0;
95 static const int kNumberOfDeletedElementsIndex = 1;
96 static const int kCapacityIndex = 2;
97 static const int kPrefixStartIndex = 3;
100 static const int kMinCapacity = 4;
104 inline void SetInitialNumberOfElements(
int nof);
108 inline void SetNumberOfElements(
int nof);
111 inline void SetNumberOfDeletedElements(
int nod);
115 return InternalIndex((last.as_uint32() + number) & (size - 1));
119template <
typename Derived,
typename ShapeT>
120class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
121 :
public HashTableBase {
126 using TodoShape = ShapeT;
127 using Key =
typename TodoShape::Key;
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);
136 static inline DirectHandle<Map> GetMap(RootsTable& roots);
139 void IteratePrefix(ObjectVisitor* visitor);
140 void IterateElements(ObjectVisitor* visitor);
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));
152 uint32_t coefficient = size >> TodoShape::kHashBits;
154 return InternalIndex((hash * coefficient) & (size - 1));
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);
164 void Rehash(PtrComprCageBase cage_base);
168 static inline bool IsKey(ReadOnlyRoots roots, Tagged<Object> k);
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);
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,
182 inline void SetKeyAt(InternalIndex entry, Tagged<Object> value,
183 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
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 =
195 static const int kMaxCapacity =
196 (FixedArray::kMaxLength - kElementsStartIndex) / kEntrySize;
199 static const int kMinShrinkCapacity = 16;
202 static const int kMinCapacityForPretenure = 256;
207 static constexpr inline int EntryToIndex(InternalIndex entry) {
208 return (entry.as_int() * kEntrySize) + kElementsStartIndex;
212 static constexpr inline InternalIndex IndexToEntry(
int index) {
213 return InternalIndex((index - kElementsStartIndex) / kEntrySize);
217 static constexpr inline int SlotToIndex(Address
object, Address slot) {
218 return static_cast<int>((slot -
object -
sizeof(HashTableBase)) /
223 template <
typename IsolateT,
template <
typename>
typename HandleType>
224 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
226 IsolateT* isolate, HandleType<Derived> table,
int n = 1,
227 AllocationType allocation = AllocationType::kYoung);
230 bool HasSufficientCapacityToAdd(
int number_of_additional_elements);
235 static bool HasSufficientCapacityToAdd(
int capacity,
int number_of_elements,
236 int number_of_deleted_elements,
237 int number_of_additional_elements);
240 friend class ObjectHashTable;
242 template <
typename IsolateT>
244 IsolateT* isolate,
int capacity, AllocationType allocation);
248 InternalIndex FindInsertionEntry(PtrComprCageBase cage_base,
249 ReadOnlyRoots roots, uint32_t hash);
250 template <
typename IsolateT>
251 InternalIndex FindInsertionEntry(IsolateT* isolate, uint32_t hash);
255 static int ComputeCapacityWithShrink(
int current_capacity,
256 int at_least_room_for);
259 template <
template <
typename>
typename HandleType>
260 requires(std::is_convertible_v<HandleType<Derived>, DirectHandle<Derived>>)
262 Isolate* isolate, HandleType<Derived> table,
int additionalCapacity = 0);
265 void Rehash(PtrComprCageBase cage_base, Tagged<Derived> new_table);
267 inline void set_key(
int index, Tagged<Object> value);
268 inline void set_key(
int index, Tagged<Object> value, WriteBarrierMode mode);
272 static_assert(EntryToIndex(InternalIndex(kMaxRegularCapacity)) <
273 FixedArray::kMaxRegularLength);
275 static const int kMaxRegularEntry = kMaxRegularCapacity / kEntrySize;
276 static const int kMaxRegularIndex =
277 EntryToIndex(InternalIndex(kMaxRegularEntry));
278 static_assert(OffsetOfElementAt(kMaxRegularIndex) <
282 inline void SetCapacity(
int capacity);
287 InternalIndex EntryForProbe(ReadOnlyRoots roots, Tagged<Object> k,
int probe,
288 InternalIndex expected);
290 void Swap(InternalIndex entry1, InternalIndex entry2, WriteBarrierMode mode);
293#define EXTERN_DECLARE_HASH_TABLE(DERIVED, SHAPE) \
294 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) \
295 HashTable<class DERIVED, SHAPE>; \
297 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
298 HashTable<DERIVED, SHAPE>::New(Isolate*, int, AllocationType, \
300 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
301 HashTable<DERIVED, SHAPE>::New(LocalIsolate*, int, AllocationType, \
304 extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle<DERIVED> \
305 HashTable<DERIVED, SHAPE>::EnsureCapacity(Isolate*, Handle<DERIVED>, int, \
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); \
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);
336 uint32_t
Hash()
const {
return hash_; }
355 static const int kPrefixSize = 0;
356 static const int kEntryValueIndex = 1;
357 static const int kEntrySize = 2;
358 static const bool kMatchNeedsHoleCheck =
false;
365 static const bool kDoHashSpreading =
false;
366 static const uint32_t kHashBits = 0;
374 static const bool kDoHashSpreading =
true;
378template <
typename Derived,
typename Shape>
379class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) ObjectHashTableBase
380 :
public HashTable<Derived, Shape> {
411 return HashTable<Derived, Shape>::EntryToIndex(entry) +
412 Shape::kEntryValueIndex;
416 void AddEntry(InternalIndex entry, Tagged<Object>
key, Tagged<Object> value);
417 void RemoveEntry(InternalIndex entry);
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>;
443 :
public ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape> {
448 class BodyDescriptor;
468 static const int kEntrySize = 1 +
N;
471template <
typename Derived,
int N>
473 :
public HashTable<Derived, ObjectMultiHashTableShape<N>> {
475 static_assert(
N > 1,
"use ObjectHashTable instead if N = 1");
493 return HashTable<Derived, ObjectMultiHashTableShape<N>>::EntryToIndex(
505 static const int kPrefixSize = 0;
506 static const int kEntrySize = 1;
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;
537 :
public HashTable<NameToIndexHashTable, NameToIndexShape> {
539 static const int kEntryValueIndex = NameToIndexShape::kEntryValueIndex;
548 template <
typename IsolateT>
562 return EntryToIndex(entry) + NameToIndexShape::kEntryValueIndex;
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;
581 :
public HashTable<RegisteredSymbolTable, RegisteredSymbolTableShape> {
599 return EntryToIndex(entry) + RegisteredSymbolTableShape::kEntryValueIndex;
static Tagged< Object > Unwrap(Tagged< Object > key)
static const uint32_t kHashBits
static InternalIndex NextProbe(InternalIndex last, uint32_t number, uint32_t size)
virtual bool IsMatch(Tagged< Object > other)=0
HashTableKey(uint32_t hash)
void set_hash(uint32_t hash)
virtual ~HashTableKey()=default
static int EntryToValueIndex(InternalIndex entry)
static DirectHandle< Object > AsHandle(DirectHandle< Name > key)
static constexpr int EntryToValueIndexStart(InternalIndex entry)
static int EntryToValueIndex(InternalIndex entry)
#define EXTERN_DECLARE_HASH_TABLE(DERIVED, SHAPE)
#define EXTERN_DECLARE_OBJECT_BASE_HASH_TABLE(DERIVED, SHAPE)
constexpr bool IsPowerOfTwo(T value)
constexpr int kTaggedSize
constexpr int kMaxRegularHeapObjectSize
#define DECL_PRINTER(Name)
#define NON_EXPORTED_BASE(code)
#define DCHECK_LE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
#define OFFSET_OF_DATA_START(Type)
#define V8_WARN_UNUSED_RESULT
std::unique_ptr< ValueMirror > key