#ifndef V8_OBJECTS_SWISS_NAME_DICTIONARY_H_
#define V8_OBJECTS_SWISS_NAME_DICTIONARY_H_
#include <cstdint>
#include <optional>
#include "src/base/export-template.h"
#include "src/common/globals.h"
#include "src/objects/fixed-array.h"
#include "src/objects/internal-index.h"
#include "src/objects/js-objects.h"
#include "src/objects/swiss-hash-table-helpers.h"
#include "src/roots/roots.h"
#include "src/objects/object-macros.h"
namespace v8::internal {
class V8_EXPORT_PRIVATE SwissNameDictionary : public HeapObject {
public:
using Group = swiss_table::Group;
template <typename IsolateT, template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<SwissNameDictionary>,
DirectHandle<SwissNameDictionary>>)
inline static HandleType<SwissNameDictionary> Add(
IsolateT* isolate, HandleType<SwissNameDictionary> table,
DirectHandle<Name> key, DirectHandle<Object> value,
PropertyDetails details, InternalIndex* entry_out = nullptr);
template <template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<SwissNameDictionary>,
DirectHandle<SwissNameDictionary>>)
static HandleType<SwissNameDictionary> Shrink(
Isolate* isolate, HandleType<SwissNameDictionary> table);
template <template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<SwissNameDictionary>,
DirectHandle<SwissNameDictionary>>)
static HandleType<SwissNameDictionary> DeleteEntry(
Isolate* isolate, HandleType<SwissNameDictionary> table,
InternalIndex entry);
template <typename IsolateT>
inline InternalIndex FindEntry(IsolateT* isolate, Tagged<Object> key);
template <typename IsolateT>
inline InternalIndex FindEntry(IsolateT* isolate, DirectHandle<Object> key);
static inline bool IsKey(ReadOnlyRoots roots, Tagged<Object> key_candidate);
inline bool ToKey(ReadOnlyRoots roots, InternalIndex entry,
Tagged<Object>* out_key);
inline Tagged<Object> KeyAt(InternalIndex entry);
inline Tagged<Name> NameAt(InternalIndex entry);
inline Tagged<Object> ValueAt(InternalIndex entry);
inline std::optional<Tagged<Object>> TryValueAt(InternalIndex entry);
inline PropertyDetails DetailsAt(InternalIndex entry);
inline void ValueAtPut(InternalIndex entry, Tagged<Object> value);
inline void DetailsAtPut(InternalIndex entry, PropertyDetails value);
inline int NumberOfElements();
inline int NumberOfDeletedElements();
inline int Capacity();
inline int UsedCapacity();
int NumberOfEnumerableProperties();
inline bool may_have_interesting_properties() { UNREACHABLE(); }
inline void set_may_have_interesting_properties(bool value) { UNREACHABLE(); }
static DirectHandle<SwissNameDictionary> ShallowCopy(
Isolate* isolate, DirectHandle<SwissNameDictionary> table);
bool EqualsForTesting(Tagged<SwissNameDictionary> other);
template <typename IsolateT>
void Initialize(IsolateT* isolate, Tagged<ByteArray> meta_table,
int capacity);
template <typename IsolateT, template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<SwissNameDictionary>,
DirectHandle<SwissNameDictionary>>)
static HandleType<SwissNameDictionary> Rehash(
IsolateT* isolate, HandleType<SwissNameDictionary> table,
int new_capacity);
template <typename IsolateT>
void Rehash(IsolateT* isolate);
inline void SetHash(int hash);
inline int Hash();
Tagged<Object> SlowReverseLookup(Isolate* isolate, Tagged<Object> value);
class IndexIterator {
public:
inline IndexIterator(DirectHandle<SwissNameDictionary> dict, int start);
inline IndexIterator& operator++();
inline bool operator==(const IndexIterator& b) const;
inline bool operator!=(const IndexIterator& b) const;
inline InternalIndex operator*();
private:
int used_capacity_;
int enum_index_;
DirectHandle<SwissNameDictionary> dict_;
};
class IndexIterable {
public:
inline explicit IndexIterable(DirectHandle<SwissNameDictionary> dict);
inline IndexIterator begin();
inline IndexIterator end();
private:
DirectHandle<SwissNameDictionary> dict_;
};
inline IndexIterable IterateEntriesOrdered();
inline IndexIterable IterateEntries();
inline int EntryForEnumerationIndex(int enumeration_index);
inline static constexpr bool IsValidCapacity(int capacity);
inline static int CapacityFor(int at_least_space_for);
inline static constexpr int MaxUsableCapacity(int capacity);
inline static constexpr int MaxCapacity();
inline static constexpr int SizeFor(int capacity);
inline static constexpr int MetaTableSizePerEntryFor(int capacity);
inline static constexpr int MetaTableSizeFor(int capacity);
inline static constexpr int DataTableSize(int capacity);
inline static constexpr int CtrlTableSize(int capacity);
static constexpr bool kIsOrderedDictionaryType = true;
static constexpr int kNotFoundSentinel = -1;
static const int kGroupWidth = Group::kWidth;
static const bool kUseSIMD = kGroupWidth == 16;
class BodyDescriptor;
static constexpr int kInitialCapacity = kSwissNameDictionaryInitialCapacity;
static constexpr int kDataTableEntryCount = 2;
static constexpr int kDataTableKeyEntryIndex = 0;
static constexpr int kDataTableValueEntryIndex = kDataTableKeyEntryIndex + 1;
static constexpr int kMetaTableElementCountFieldIndex = 0;
static constexpr int kMetaTableDeletedElementCountFieldIndex = 1;
static constexpr int kMetaTableEnumerationDataStartIndex = 2;
static constexpr int kMax1ByteMetaTableCapacity = (1 << 8);
static constexpr int kMax2ByteMetaTableCapacity = (1 << 16);
using Offset = int;
inline static constexpr Offset PrefixOffset();
inline static constexpr Offset CapacityOffset();
inline static constexpr Offset MetaTablePointerOffset();
inline static constexpr Offset DataTableStartOffset();
inline static constexpr Offset DataTableEndOffset(int capacity);
inline static constexpr Offset CtrlTableStartOffset(int capacity);
inline static constexpr Offset PropertyDetailsTableStartOffset(int capacity);
#if VERIFY_HEAP
void SwissNameDictionaryVerify(Isolate* isolate, bool slow_checks);
#endif
DECL_VERIFIER(SwissNameDictionary)
DECL_PRINTER(SwissNameDictionary)
OBJECT_CONSTRUCTORS(SwissNameDictionary, HeapObject);
private:
using ctrl_t = swiss_table::ctrl_t;
using Ctrl = swiss_table::Ctrl;
template <typename IsolateT, template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<SwissNameDictionary>,
DirectHandle<SwissNameDictionary>>)
inline static HandleType<SwissNameDictionary> EnsureGrowable(
IsolateT* isolate, HandleType<SwissNameDictionary> table);
inline uint8_t* PropertyDetailsTable();
inline void ClearDataTableEntry(Isolate* isolate, int entry);
inline void SetKey(int entry, Tagged<Object> key);
inline void DetailsAtPut(int entry, PropertyDetails value);
inline void ValueAtPut(int entry, Tagged<Object> value);
inline PropertyDetails DetailsAt(int entry);
inline Tagged<Object> ValueAtRaw(int entry);
inline Tagged<Object> KeyAt(int entry);
inline bool ToKey(ReadOnlyRoots roots, int entry, Tagged<Object>* out_key);
inline int FindFirstEmpty(uint32_t hash);
inline int AddInternal(Tagged<Name> key, Tagged<Object> value,
PropertyDetails details);
inline ctrl_t* CtrlTable();
inline static bool IsEmpty(ctrl_t c);
inline static bool IsFull(ctrl_t c);
inline static bool IsDeleted(ctrl_t c);
inline static bool IsEmptyOrDeleted(ctrl_t c);
inline void SetCtrl(int entry, ctrl_t h);
inline ctrl_t GetCtrl(int entry);
inline Tagged<Object> LoadFromDataTable(int entry, int data_offset);
inline Tagged<Object> LoadFromDataTable(PtrComprCageBase cage_base, int entry,
int data_offset);
inline void StoreToDataTable(int entry, int data_offset, Tagged<Object> data);
inline void StoreToDataTableNoBarrier(int entry, int data_offset,
Tagged<Object> data);
inline void SetCapacity(int capacity);
inline void SetNumberOfElements(int elements);
inline void SetNumberOfDeletedElements(int deleted_elements);
static inline swiss_table::ProbeSequence<Group::kWidth> probe(uint32_t hash,
int capacity);
inline void SetEntryForEnumerationIndex(int enumeration_index, int entry);
DECL_ACCESSORS(meta_table, Tagged<ByteArray>)
inline void SetMetaTableField(int field_index, int value);
inline int GetMetaTableField(int field_index);
template <typename T>
inline static void SetMetaTableField(Tagged<ByteArray> meta_table,
int field_index, int value);
template <typename T>
inline static int GetMetaTableField(Tagged<ByteArray> meta_table,
int field_index);
};
}
#include "src/objects/object-macros-undef.h"
#endif