/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/objects/off-heap-hash-table.h
195 строк
7 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2023 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. #ifndef V8_OBJECTS_OFF_HEAP_HASH_TABLE_H_ #define V8_OBJECTS_OFF_HEAP_HASH_TABLE_H_ #include "src/common/globals.h" #include "src/execution/isolate-utils.h" #include "src/objects/compressed-slots.h" #include "src/objects/slots.h" #include "src/objects/smi.h" #include "src/objects/visitors.h" #include "src/roots/roots.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" namespace v8 { namespace internal { // A base class for building off-heap hash tables (e.g. the string table) that // stores tagged values. // // It is a variable sized structure, with a "header" followed directly in memory // by the elements themselves. These are accessed as offsets from the elements_ // field, which itself provides storage for the first element. // // The elements themselves are stored as an open-addressed hash table, with // quadratic probing and Smi 0 and Smi 1 as the empty and deleted sentinels, // respectively. // // It is a CRTP class whose derived class must provide the following // definitions: // // // The number of elements per table entry. // static constexpr int kEntrySize; // // // The factor by which to decide if the table ought to shrink. // static constexpr int kMaxEmptyFactor; // // // The minimum number of elements for new tables. // static constexpr int kMinCapacity; // // // Computes the hash of a key {obj}. // static uint32_t Hash(Tagged<Object> obj); // // // Returns whether the lookup key {key} matches the key element {obj}. // template <typename IsolateT, typename Key> // static bool KeyIsMatch(IsolateT* isolate, Key key, Tagged<Object> obj); // // // Load the key object at entry {index}, decompressing it if needed. // Tagged<Object> GetKey(PtrComprCageBase, InternalIndex index); // // // Store the key object at the entry {index}. // void SetKey(InternalIndex index, Tagged<Object> key); // // // Store an entire entry at {index}. The arity of this function must be // // kEntrySize + 1. // void Set(InternalIndex index, Tagged<Object>...); // // // Copy an entry in this table at {from_index} into the entry in {to} at // // {to_index}, exclusive of the key. // void CopyEntryExcludingKeyInto(PtrComprCageBase, InternalIndex from_index, // Derived* to, InternalIndex to_index); // template <typename Derived> class OffHeapHashTableBase { public: static constexpr Tagged<Smi> empty_element() { return Smi::FromInt(0); } static constexpr Tagged<Smi> deleted_element() { return Smi::FromInt(1); } static bool IsKey(Tagged<Object> k) { return k != empty_element() && k != deleted_element(); } int capacity() const { return capacity_; } int number_of_elements() const { return number_of_elements_; } int number_of_deleted_elements() const { return number_of_deleted_elements_; } OffHeapObjectSlot slot(InternalIndex index, int offset = 0) const { DCHECK_LT(offset, Derived::kEntrySize); return OffHeapObjectSlot( &elements_[index.as_uint32() * Derived::kEntrySize + offset]); } template <typename... Args> void AddAt(PtrComprCageBase cage_base, InternalIndex entry, Args&&... args) { Derived* derived_this = static_cast<Derived*>(this); DCHECK_EQ(derived_this->GetKey(cage_base, entry), empty_element()); DCHECK_LT(number_of_elements_ + 1, capacity()); DCHECK(HasSufficientCapacityToAdd(1)); derived_this->Set(entry, std::forward<Args>(args)...); number_of_elements_++; } template <typename... Args> void OverwriteDeletedAt(PtrComprCageBase cage_base, InternalIndex entry, Args&&... args) { Derived* derived_this = static_cast<Derived*>(this); DCHECK_EQ(derived_this->GetKey(cage_base, entry), deleted_element()); DCHECK_LT(number_of_elements_ + 1, capacity()); DCHECK(HasSufficientCapacityToAdd(capacity(), number_of_elements(), number_of_deleted_elements() - 1, 1)); derived_this->Set(entry, std::forward<Args>(args)...); number_of_elements_++; number_of_deleted_elements_--; } void ElementsRemoved(int count) { DCHECK_LE(count, number_of_elements_); number_of_elements_ -= count; number_of_deleted_elements_ += count; } size_t GetSizeExcludingHeader() const { return GetSizeExcludingHeader(capacity_); } template <typename IsolateT, typename FindKey> inline InternalIndex FindEntry(IsolateT* isolate, FindKey key, uint32_t hash) const; inline InternalIndex FindInsertionEntry(PtrComprCageBase cage_base, uint32_t hash) const; template <typename IsolateT, typename FindKey> inline InternalIndex FindEntryOrInsertionEntry(IsolateT* isolate, FindKey key, uint32_t hash) const; inline bool ShouldResizeToAdd(int number_of_additional_elements, int* new_capacity); inline void RehashInto(PtrComprCageBase cage_base, Derived* new_table); inline void IterateElements(Root root, RootVisitor* visitor); inline void IterateElementsRange(Root root, RootVisitor* visitor, int start, int end); protected: explicit OffHeapHashTableBase(int capacity); // Returns probe entry. static inline InternalIndex FirstProbe(uint32_t hash, uint32_t size) { return InternalIndex(hash & (size - 1)); } static inline InternalIndex NextProbe(InternalIndex last, uint32_t number, uint32_t size) { return InternalIndex((last.as_uint32() + number) & (size - 1)); } bool HasSufficientCapacityToAdd(int number_of_additional_elements) const { return HasSufficientCapacityToAdd(capacity(), number_of_elements(), number_of_deleted_elements(), number_of_additional_elements); } static inline bool HasSufficientCapacityToAdd( int capacity, int number_of_elements, int number_of_deleted_elements, int number_of_additional_elements); static inline int ComputeCapacity(int at_least_space_for); static inline int ComputeCapacityWithShrink(int current_capacity, int at_least_space_for); static inline size_t GetSizeExcludingHeader(int capacity) { // Subtract sizeof(Tagged_t) from the result, as the member elements_ // already supplies the storage for the first element. return (capacity * sizeof(Tagged_t) * Derived::kEntrySize) - sizeof(Tagged_t); } // Returns memory to hold a Derived, which may be inline inside Container. The // offset of the elements_ field relative to Container must be passed for // static layout checks. template <typename Container, size_t OffsetOfElementsInContainer> static inline void* Allocate(int capacity); static inline void Free(void* container); int number_of_elements_; int number_of_deleted_elements_; const int capacity_; Tagged_t elements_[1]; }; } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_OFF_HEAP_HASH_TABLE_H_