Revert "[dict-proto] C++ implementation of SwissNameDictionary, pt. 3"
This reverts commit 2f8a7561cb
.
Reason for revert: Speculative revert, lots of segfaults on Arm:
https://ci.chromium.org/p/v8/builders/ci/V8%20Arm%20-%20debug/17781
Original change's description:
> [dict-proto] C++ implementation of SwissNameDictionary, pt. 3
>
> This CL is part of a series that adds the C++ implementation of
> SwissNameDictionary, a deterministic property backing store based on
> Swiss Tables.
>
> This CL adds the initialization code, factory functions and a
> canonical SwissNameDictionary plus all helpers required for that.
>
> Bug: v8:11388
> Change-Id: I6bb92740afefc7d05433cfa62023e6da5e8213c7
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2688058
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Reviewed-by: Marja Hölttä <marja@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Commit-Queue: Frank Emrich <emrich@google.com>
> Cr-Commit-Position: refs/heads/master@{#72824}
Bug: v8:11388
Change-Id: Ia5dae584b0fb452b12c5d64ee63ffa418c83f91b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2698758
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72829}
This commit is contained in:
parent
6a358500a7
commit
1ff071c1e2
@ -22,7 +22,6 @@
|
||||
#include "src/objects/source-text-module.h"
|
||||
#include "src/objects/string-inl.h"
|
||||
#include "src/objects/string.h"
|
||||
#include "src/objects/swiss-name-dictionary-inl.h"
|
||||
#include "src/objects/template-objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -849,43 +848,6 @@ HeapObject FactoryBase<Impl>::AllocateRaw(int size, AllocationType allocation,
|
||||
return impl()->AllocateRaw(size, allocation, alignment);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<SwissNameDictionary>
|
||||
FactoryBase<Impl>::NewSwissNameDictionaryWithCapacity(
|
||||
int capacity, AllocationType allocation) {
|
||||
DCHECK(SwissNameDictionary::IsValidCapacity(capacity));
|
||||
|
||||
if (capacity == 0) {
|
||||
DCHECK_NE(read_only_roots().at(RootIndex::kEmptySwissPropertyDictionary),
|
||||
kNullAddress);
|
||||
|
||||
return read_only_roots().empty_swiss_property_dictionary_handle();
|
||||
}
|
||||
|
||||
if (capacity > SwissNameDictionary::MaxCapacity()) {
|
||||
isolate()->FatalProcessOutOfHeapMemory("invalid table size");
|
||||
}
|
||||
|
||||
int meta_table_length = SwissNameDictionary::MetaTableSizeFor(capacity);
|
||||
Handle<ByteArray> meta_table =
|
||||
impl()->NewByteArray(meta_table_length, allocation);
|
||||
|
||||
Map map = read_only_roots().swiss_name_dictionary_map();
|
||||
int size = SwissNameDictionary::SizeFor(capacity);
|
||||
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
|
||||
Handle<SwissNameDictionary> table(SwissNameDictionary::cast(result),
|
||||
isolate());
|
||||
table->Initialize(isolate(), *meta_table, capacity);
|
||||
return table;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<SwissNameDictionary> FactoryBase<Impl>::NewSwissNameDictionary(
|
||||
int at_least_space_for, AllocationType allocation) {
|
||||
return NewSwissNameDictionaryWithCapacity(
|
||||
SwissNameDictionary::CapacityFor(at_least_space_for), allocation);
|
||||
}
|
||||
|
||||
// Instantiate FactoryBase for the two variants we want.
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) FactoryBase<Factory>;
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
|
@ -221,13 +221,6 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
|
||||
|
||||
Handle<ClassPositions> NewClassPositions(int start, int end);
|
||||
|
||||
Handle<SwissNameDictionary> NewSwissNameDictionary(
|
||||
int at_least_space_for = kSwissNameDictionaryInitialCapacity,
|
||||
AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
Handle<SwissNameDictionary> NewSwissNameDictionaryWithCapacity(
|
||||
int capacity, AllocationType allocation);
|
||||
|
||||
protected:
|
||||
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
|
||||
HeapObject AllocateRawArray(int size, AllocationType allocation);
|
||||
|
@ -553,27 +553,6 @@ Handle<PropertyDescriptorObject> Factory::NewPropertyDescriptorObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
Handle<SwissNameDictionary> Factory::CreateCanonicalEmptySwissNameDictionary() {
|
||||
// This function is only supposed to be used to create the canonical empty
|
||||
// version and should not be used afterwards.
|
||||
DCHECK_EQ(kNullAddress, ReadOnlyRoots(isolate()).at(
|
||||
RootIndex::kEmptySwissPropertyDictionary));
|
||||
|
||||
ReadOnlyRoots roots(isolate());
|
||||
|
||||
Handle<ByteArray> empty_meta_table =
|
||||
NewByteArray(SwissNameDictionary::kMetaTableEnumerationTableStartOffset,
|
||||
AllocationType::kReadOnly);
|
||||
|
||||
Map map = roots.swiss_name_dictionary_map();
|
||||
int size = SwissNameDictionary::SizeFor(0);
|
||||
HeapObject obj =
|
||||
AllocateRawWithImmortalMap(size, AllocationType::kReadOnly, map);
|
||||
SwissNameDictionary result = SwissNameDictionary::cast(obj);
|
||||
result.Initialize(isolate(), *empty_meta_table, 0);
|
||||
return handle(result, isolate());
|
||||
}
|
||||
|
||||
// Internalized strings are created in the old generation (data space).
|
||||
Handle<String> Factory::InternalizeUtf8String(
|
||||
const Vector<const char>& string) {
|
||||
|
@ -171,8 +171,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
int capacity = kSmallOrderedHashMapMinCapacity,
|
||||
AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
Handle<SwissNameDictionary> CreateCanonicalEmptySwissNameDictionary();
|
||||
|
||||
// Create a new PrototypeInfo struct.
|
||||
Handle<PrototypeInfo> NewPrototypeInfo();
|
||||
|
||||
|
@ -819,11 +819,6 @@ void Heap::CreateInitialObjects() {
|
||||
.ToHandleChecked();
|
||||
set_empty_ordered_property_dictionary(*empty_ordered_property_dictionary);
|
||||
|
||||
// Allocate the empty SwissNameDictionary
|
||||
Handle<SwissNameDictionary> empty_swiss_property_dictionary =
|
||||
factory->CreateCanonicalEmptySwissNameDictionary();
|
||||
set_empty_swiss_property_dictionary(*empty_swiss_property_dictionary);
|
||||
|
||||
// Allocate the empty FeedbackMetadata.
|
||||
Handle<FeedbackMetadata> empty_feedback_metadata =
|
||||
factory->NewFeedbackMetadata(0, 0, AllocationType::kReadOnly);
|
||||
|
@ -5,8 +5,6 @@
|
||||
#ifndef V8_OBJECTS_SWISS_NAME_DICTIONARY_INL_H_
|
||||
#define V8_OBJECTS_SWISS_NAME_DICTIONARY_INL_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/base/macros.h"
|
||||
#include "src/execution/isolate-utils-inl.h"
|
||||
#include "src/heap/heap.h"
|
||||
@ -28,41 +26,10 @@ namespace internal {
|
||||
CAST_ACCESSOR(SwissNameDictionary)
|
||||
OBJECT_CONSTRUCTORS_IMPL(SwissNameDictionary, HeapObject)
|
||||
|
||||
const swiss_table::ctrl_t* SwissNameDictionary::CtrlTable() {
|
||||
return reinterpret_cast<ctrl_t*>(
|
||||
field_address(CtrlTableStartOffset(Capacity())));
|
||||
}
|
||||
|
||||
int SwissNameDictionary::Capacity() {
|
||||
return ReadField<int32_t>(CapacityOffset());
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SetCapacity(int capacity) {
|
||||
DCHECK(IsValidCapacity(capacity));
|
||||
|
||||
WriteField(CapacityOffset(), capacity);
|
||||
}
|
||||
|
||||
int SwissNameDictionary::NumberOfElements() {
|
||||
return GetMetaTableField(kMetaTableElementCountOffset);
|
||||
}
|
||||
|
||||
int SwissNameDictionary::NumberOfDeletedElements() {
|
||||
return GetMetaTableField(kMetaTableDeletedElementCountOffset);
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SetNumberOfElements(int elements) {
|
||||
SetMetaTableField(kMetaTableElementCountOffset, elements);
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SetNumberOfDeletedElements(int deleted_elements) {
|
||||
SetMetaTableField(kMetaTableDeletedElementCountOffset, deleted_elements);
|
||||
}
|
||||
|
||||
int SwissNameDictionary::UsedCapacity() {
|
||||
return NumberOfElements() + NumberOfDeletedElements();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr bool SwissNameDictionary::IsValidCapacity(int capacity) {
|
||||
return capacity == 0 || (capacity >= kInitialCapacity &&
|
||||
@ -88,180 +55,6 @@ constexpr int SwissNameDictionary::SizeFor(int capacity) {
|
||||
return PropertyDetailsTableStartOffset(capacity) + capacity;
|
||||
}
|
||||
|
||||
// We use 7/8th as maximum load factor for non-special cases.
|
||||
// For 16-wide groups, that gives an average of two empty slots per group.
|
||||
// Similar to Abseil's CapacityToGrowth.
|
||||
// static
|
||||
constexpr int SwissNameDictionary::MaxUsableCapacity(int capacity) {
|
||||
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
|
||||
|
||||
if (Group::kWidth == 8 && capacity == 4) {
|
||||
// If the group size is 16 we can fully utilize capacity 4: There will be
|
||||
// enough kEmpty entries in the ctrl table.
|
||||
return 3;
|
||||
}
|
||||
return capacity - capacity / 8;
|
||||
}
|
||||
|
||||
// Returns |at_least_space_for| * 8/7 for non-special cases. Similar to Abseil's
|
||||
// GrowthToLowerboundCapacity.
|
||||
// static
|
||||
int SwissNameDictionary::CapacityFor(int at_least_space_for) {
|
||||
if (at_least_space_for <= 4) {
|
||||
if (at_least_space_for == 0) {
|
||||
return 0;
|
||||
} else if (at_least_space_for < 4) {
|
||||
return 4;
|
||||
} else if (kGroupWidth == 16) {
|
||||
DCHECK_EQ(4, at_least_space_for);
|
||||
return 4;
|
||||
} else if (kGroupWidth == 8) {
|
||||
DCHECK_EQ(4, at_least_space_for);
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
int non_normalized = at_least_space_for + at_least_space_for / 7;
|
||||
return base::bits::RoundUpToPowerOfTwo32(non_normalized);
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SetMetaTableField(int field_index, int value) {
|
||||
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
|
||||
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
|
||||
// constants.
|
||||
int capacity = Capacity();
|
||||
ByteArray meta_table = this->meta_table();
|
||||
if (capacity <= kMax1ByteMetaTableCapacity) {
|
||||
SetMetaTableField<uint8_t>(meta_table, field_index, value);
|
||||
} else if (capacity <= kMax2ByteMetaTableCapacity) {
|
||||
SetMetaTableField<uint16_t>(meta_table, field_index, value);
|
||||
} else {
|
||||
SetMetaTableField<uint32_t>(meta_table, field_index, value);
|
||||
}
|
||||
}
|
||||
|
||||
int SwissNameDictionary::GetMetaTableField(int field_index) {
|
||||
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
|
||||
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
|
||||
// constants.
|
||||
int capacity = Capacity();
|
||||
ByteArray meta_table = this->meta_table();
|
||||
if (capacity <= kMax1ByteMetaTableCapacity) {
|
||||
return GetMetaTableField<uint8_t>(meta_table, field_index);
|
||||
} else if (capacity <= kMax2ByteMetaTableCapacity) {
|
||||
return GetMetaTableField<uint16_t>(meta_table, field_index);
|
||||
} else {
|
||||
return GetMetaTableField<uint32_t>(meta_table, field_index);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename T>
|
||||
void SwissNameDictionary::SetMetaTableField(ByteArray meta_table,
|
||||
int field_index, int value) {
|
||||
STATIC_ASSERT((std::is_same<T, uint8_t>::value) ||
|
||||
(std::is_same<T, uint16_t>::value) ||
|
||||
(std::is_same<T, uint32_t>::value));
|
||||
DCHECK_LE(value, std::numeric_limits<T>::max());
|
||||
DCHECK_LT(meta_table.GetDataStartAddress() + field_index * sizeof(T),
|
||||
meta_table.GetDataEndAddress());
|
||||
T* raw_data = reinterpret_cast<T*>(meta_table.GetDataStartAddress());
|
||||
raw_data[field_index] = value;
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename T>
|
||||
int SwissNameDictionary::GetMetaTableField(ByteArray meta_table,
|
||||
int field_index) {
|
||||
STATIC_ASSERT((std::is_same<T, uint8_t>::value) ||
|
||||
(std::is_same<T, uint16_t>::value) ||
|
||||
(std::is_same<T, uint32_t>::value));
|
||||
DCHECK_LT(meta_table.GetDataStartAddress() + field_index * sizeof(T),
|
||||
meta_table.GetDataEndAddress());
|
||||
T* raw_data = reinterpret_cast<T*>(meta_table.GetDataStartAddress());
|
||||
return raw_data[field_index];
|
||||
}
|
||||
|
||||
constexpr int SwissNameDictionary::MetaTableSizePerEntryFor(int capacity) {
|
||||
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
|
||||
|
||||
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
|
||||
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
|
||||
// constants.
|
||||
if (capacity <= kMax1ByteMetaTableCapacity) {
|
||||
return sizeof(uint8_t);
|
||||
} else if (capacity <= kMax2ByteMetaTableCapacity) {
|
||||
return sizeof(uint16_t);
|
||||
} else {
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int SwissNameDictionary::MetaTableSizeFor(int capacity) {
|
||||
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
|
||||
|
||||
int per_entry_size = MetaTableSizePerEntryFor(capacity);
|
||||
|
||||
// The enumeration table only needs to have as many slots as there can be
|
||||
// present + deleted entries in the hash table (= maximum load factor *
|
||||
// capactiy). Two more slots to store the number of present and deleted
|
||||
// entries.
|
||||
return per_entry_size * (MaxUsableCapacity(capacity) + 2);
|
||||
}
|
||||
|
||||
template <typename LocalIsolate>
|
||||
void SwissNameDictionary::Initialize(LocalIsolate* isolate,
|
||||
ByteArray meta_table, int capacity) {
|
||||
DCHECK(IsValidCapacity(capacity));
|
||||
DisallowHeapAllocation no_gc;
|
||||
ReadOnlyRoots roots(isolate);
|
||||
|
||||
SetCapacity(capacity);
|
||||
SetHash(PropertyArray::kNoHashSentinel);
|
||||
|
||||
ctrl_t* ctrl_table = reinterpret_cast<ctrl_t*>(
|
||||
field_address(CtrlTableStartOffset(Capacity())));
|
||||
memset(ctrl_table, Ctrl::kEmpty, CtrlTableSize(capacity));
|
||||
|
||||
MemsetTagged(RawField(DataTableStartOffset()), roots.the_hole_value(),
|
||||
capacity * kDataTableEntryCount);
|
||||
|
||||
set_meta_table(meta_table);
|
||||
|
||||
SetNumberOfElements(0);
|
||||
SetNumberOfDeletedElements(0);
|
||||
|
||||
// We leave the enumeration table PropertyDetails table and uninitialized.
|
||||
}
|
||||
|
||||
void SwissNameDictionary::SetHash(int32_t hash) {
|
||||
WriteField(PrefixOffset(), hash);
|
||||
}
|
||||
|
||||
int SwissNameDictionary::Hash() { return ReadField<int32_t>(PrefixOffset()); }
|
||||
|
||||
// static
|
||||
constexpr int SwissNameDictionary::MaxCapacity() {
|
||||
int const_size =
|
||||
DataTableStartOffset() + ByteArray::kHeaderSize +
|
||||
// Size for present and deleted element count at max capacity:
|
||||
2 * sizeof(uint32_t);
|
||||
int per_entry_size =
|
||||
// size of data table entries:
|
||||
kDataTableEntryCount * kTaggedSize +
|
||||
// ctrl table entry size:
|
||||
kOneByteSize +
|
||||
// PropertyDetails table entry size:
|
||||
kOneByteSize +
|
||||
// Enumeration table entry size at maximum capacity:
|
||||
sizeof(uint32_t);
|
||||
|
||||
int result = (FixedArray::kMaxSize - const_size) / per_entry_size;
|
||||
CONSTEXPR_DCHECK(result <= Smi::kMaxValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr int SwissNameDictionary::PrefixOffset() {
|
||||
return HeapObject::kHeaderSize;
|
||||
@ -298,10 +91,6 @@ constexpr int SwissNameDictionary::PropertyDetailsTableStartOffset(
|
||||
return CtrlTableStartOffset(capacity) + CtrlTableSize(capacity);
|
||||
}
|
||||
|
||||
ACCESSORS_CHECKED2(SwissNameDictionary, meta_table, ByteArray,
|
||||
MetaTablePointerOffset(), true,
|
||||
value.length() >= kMetaTableEnumerationTableStartOffset)
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -8,30 +8,5 @@
|
||||
#include "src/objects/swiss-name-dictionary-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// The largest value we ever have to store in the enumeration table is
|
||||
// Capacity() - 1. The largest value we ever have to store for the present or
|
||||
// deleted element count is MaxUsableCapacity(Capacity()). All data in the
|
||||
// meta table is unsigned. Using this, we verify the values of the constants
|
||||
// |kMax1ByteMetaTableCapacity| and |kMax2ByteMetaTableCapacity|.
|
||||
STATIC_ASSERT(SwissNameDictionary::kMax1ByteMetaTableCapacity - 1 <=
|
||||
std::numeric_limits<uint8_t>::max());
|
||||
STATIC_ASSERT(SwissNameDictionary::MaxUsableCapacity(
|
||||
SwissNameDictionary::kMax1ByteMetaTableCapacity) <=
|
||||
std::numeric_limits<uint8_t>::max());
|
||||
STATIC_ASSERT(SwissNameDictionary::kMax2ByteMetaTableCapacity - 1 <=
|
||||
std::numeric_limits<uint16_t>::max());
|
||||
STATIC_ASSERT(SwissNameDictionary::MaxUsableCapacity(
|
||||
SwissNameDictionary::kMax2ByteMetaTableCapacity) <=
|
||||
std::numeric_limits<uint16_t>::max());
|
||||
|
||||
template void SwissNameDictionary::Initialize(Isolate* isolate,
|
||||
ByteArray meta_table,
|
||||
int capacity);
|
||||
template void SwissNameDictionary::Initialize(LocalIsolate* isolate,
|
||||
ByteArray meta_table,
|
||||
int capacity);
|
||||
|
||||
} // namespace internal
|
||||
namespace internal {} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -40,6 +40,7 @@ namespace internal {
|
||||
// identity hash: 4 bytes, raw int32_t
|
||||
// Meta table pointer: kTaggedSize bytes.
|
||||
// See below for explanation of the meta table.
|
||||
// For capacity 0, this contains the Smi |kNoMetaTableSentinel| instead.
|
||||
// Data table:
|
||||
// For each logical bucket of the hash table, contains the corresponding key
|
||||
// and value.
|
||||
@ -72,40 +73,16 @@ class SwissNameDictionary : public HeapObject {
|
||||
public:
|
||||
using Group = swiss_table::Group;
|
||||
|
||||
inline int NumberOfElements();
|
||||
inline int NumberOfDeletedElements();
|
||||
|
||||
inline int Capacity();
|
||||
inline int UsedCapacity();
|
||||
|
||||
template <typename LocalIsolate>
|
||||
void Initialize(LocalIsolate* isolate, ByteArray meta_table, int capacity);
|
||||
|
||||
inline void SetHash(int hash);
|
||||
inline int Hash();
|
||||
|
||||
inline static constexpr bool IsValidCapacity(int capacity);
|
||||
inline static int CapacityFor(int at_least_space_for);
|
||||
|
||||
// Given a capacity, how much of it can we fill before resizing?
|
||||
inline static constexpr int MaxUsableCapacity(int capacity);
|
||||
|
||||
// The maximum allowed capacity for any SwissNameDictionary.
|
||||
inline static constexpr int MaxCapacity();
|
||||
|
||||
// Returns total size in bytes required for a table of given capacity.
|
||||
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);
|
||||
|
||||
// Indicates that IterateEntries() returns entries ordered.
|
||||
static constexpr bool kIsOrderedDictionaryType = true;
|
||||
|
||||
static const int kGroupWidth = Group::kWidth;
|
||||
// TODO(v8:11388) This is a temporary placeholder for the actual value, which
|
||||
// is added here in a follow-up CL.
|
||||
static const int kGroupWidth = 8;
|
||||
|
||||
class BodyDescriptor;
|
||||
|
||||
@ -116,19 +93,9 @@ class SwissNameDictionary : public HeapObject {
|
||||
// Defines how many kTaggedSize sized values are associcated which each entry
|
||||
// in the data table.
|
||||
static constexpr int kDataTableEntryCount = 2;
|
||||
static constexpr int kDataTableKeyEntryIndex = 0;
|
||||
static constexpr int kDataTableValueEntryIndex = kDataTableKeyEntryIndex + 1;
|
||||
|
||||
static constexpr int kMetaTableElementCountOffset = 0;
|
||||
static constexpr int kMetaTableDeletedElementCountOffset = 1;
|
||||
static constexpr int kMetaTableEnumerationTableStartOffset = 2;
|
||||
|
||||
// The maximum capacity of any SwissNameDictionary whose meta table can use 1
|
||||
// byte per entry.
|
||||
static constexpr int kMax1ByteMetaTableCapacity = (1 << 8);
|
||||
// The maximum capacity of any SwissNameDictionary whose meta table can use 2
|
||||
// bytes per entry.
|
||||
static constexpr int kMax2ByteMetaTableCapacity = (1 << 16);
|
||||
inline static constexpr int DataTableSize(int capacity);
|
||||
inline static constexpr int CtrlTableSize(int capacity);
|
||||
|
||||
// TODO(v8:11388) We would like to use Torque-generated constants here, but
|
||||
// those are currently incorrect.
|
||||
@ -147,28 +114,6 @@ class SwissNameDictionary : public HeapObject {
|
||||
DECL_PRINTER(SwissNameDictionary)
|
||||
DECL_CAST(SwissNameDictionary)
|
||||
OBJECT_CONSTRUCTORS(SwissNameDictionary, HeapObject);
|
||||
|
||||
private:
|
||||
using ctrl_t = swiss_table::ctrl_t;
|
||||
using Ctrl = swiss_table::Ctrl;
|
||||
|
||||
// Not intended for modification, use set_ctrl instead to get correct copying
|
||||
// of first group.
|
||||
inline const ctrl_t* CtrlTable();
|
||||
|
||||
inline void SetCapacity(int capacity);
|
||||
inline void SetNumberOfElements(int elements);
|
||||
inline void SetNumberOfDeletedElements(int deleted_elements);
|
||||
|
||||
DECL_ACCESSORS(meta_table, ByteArray)
|
||||
inline void SetMetaTableField(int field_index, int value);
|
||||
inline int GetMetaTableField(int field_index);
|
||||
|
||||
template <typename T>
|
||||
inline static void SetMetaTableField(ByteArray meta_table, int field_index,
|
||||
int value);
|
||||
template <typename T>
|
||||
inline static int GetMetaTableField(ByteArray meta_table, int field_index);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -167,8 +167,6 @@ class Symbol;
|
||||
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
|
||||
V(OrderedNameDictionary, empty_ordered_property_dictionary, \
|
||||
EmptyOrderedPropertyDictionary) \
|
||||
V(SwissNameDictionary, empty_swiss_property_dictionary, \
|
||||
EmptySwissPropertyDictionary) \
|
||||
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
|
||||
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
|
||||
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
|
||||
|
@ -275,7 +275,6 @@ v8_source_set("cctest_sources") {
|
||||
"test-smi-lexicographic-compare.cc",
|
||||
"test-strings.cc",
|
||||
"test-strtod.cc",
|
||||
"test-swiss-name-dictionary.cc",
|
||||
"test-symbols.cc",
|
||||
"test-thread-termination.cc",
|
||||
"test-threads.cc",
|
||||
|
@ -1,81 +0,0 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#include "src/objects/swiss-name-dictionary-inl.h"
|
||||
#include "test/cctest/cctest.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace test_swiss_hash_table {
|
||||
|
||||
TEST(CapacityFor) {
|
||||
for (int elements = 0; elements <= 32; elements++) {
|
||||
int capacity = SwissNameDictionary::CapacityFor(elements);
|
||||
if (elements == 0) {
|
||||
CHECK_EQ(0, capacity);
|
||||
} else if (elements <= 3) {
|
||||
CHECK_EQ(4, capacity);
|
||||
} else if (elements == 4) {
|
||||
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 8, capacity == 8);
|
||||
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 16, capacity == 4);
|
||||
} else if (elements <= 7) {
|
||||
CHECK_EQ(8, capacity);
|
||||
} else if (elements <= 14) {
|
||||
CHECK_EQ(16, capacity);
|
||||
} else if (elements <= 28) {
|
||||
CHECK_EQ(32, capacity);
|
||||
} else if (elements <= 32) {
|
||||
CHECK_EQ(64, capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MaxUsableCapacity) {
|
||||
CHECK_EQ(0, SwissNameDictionary::MaxUsableCapacity(0));
|
||||
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 8,
|
||||
SwissNameDictionary::MaxUsableCapacity(4) == 3);
|
||||
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 16,
|
||||
SwissNameDictionary::MaxUsableCapacity(4) == 4);
|
||||
CHECK_EQ(7, SwissNameDictionary::MaxUsableCapacity(8));
|
||||
CHECK_EQ(14, SwissNameDictionary::MaxUsableCapacity(16));
|
||||
CHECK_EQ(28, SwissNameDictionary::MaxUsableCapacity(32));
|
||||
}
|
||||
|
||||
TEST(SizeFor) {
|
||||
int baseline = HeapObject::kHeaderSize +
|
||||
// prefix:
|
||||
4 +
|
||||
// capacity:
|
||||
4 +
|
||||
// meta table:
|
||||
kTaggedSize;
|
||||
|
||||
int size_0 = baseline +
|
||||
// ctrl table:
|
||||
SwissNameDictionary::kGroupWidth;
|
||||
|
||||
int size_4 = baseline +
|
||||
// data table:
|
||||
4 * 2 * kTaggedSize +
|
||||
// ctrl table:
|
||||
4 + SwissNameDictionary::kGroupWidth +
|
||||
// property details table:
|
||||
4;
|
||||
|
||||
int size_8 = baseline +
|
||||
// data table:
|
||||
8 * 2 * kTaggedSize +
|
||||
// ctrl table:
|
||||
8 + SwissNameDictionary::kGroupWidth +
|
||||
// property details table:
|
||||
8;
|
||||
|
||||
CHECK_EQ(SwissNameDictionary::SizeFor(0), size_0);
|
||||
CHECK_EQ(SwissNameDictionary::SizeFor(4), size_4);
|
||||
CHECK_EQ(SwissNameDictionary::SizeFor(8), size_8);
|
||||
}
|
||||
|
||||
} // namespace test_swiss_hash_table
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -322,70 +322,70 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x03151): (67, "SelfReferenceMarkerMap"),
|
||||
("read_only_space", 0x03179): (67, "BasicBlockCountersMarkerMap"),
|
||||
("read_only_space", 0x031bd): (87, "ArrayBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x032bd): (100, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x05411): (72, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x05439): (73, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05461): (74, "CallableTaskMap"),
|
||||
("read_only_space", 0x05489): (75, "CallbackTaskMap"),
|
||||
("read_only_space", 0x054b1): (76, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x054d9): (79, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05501): (80, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x05529): (81, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x05551): (82, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05579): (83, "AccessorPairMap"),
|
||||
("read_only_space", 0x055a1): (84, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x055c9): (85, "AllocationMementoMap"),
|
||||
("read_only_space", 0x055f1): (88, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x05619): (89, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x05641): (90, "BaselineDataMap"),
|
||||
("read_only_space", 0x05669): (91, "BreakPointMap"),
|
||||
("read_only_space", 0x05691): (92, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x056b9): (93, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x056e1): (95, "ClassPositionsMap"),
|
||||
("read_only_space", 0x05709): (96, "DebugInfoMap"),
|
||||
("read_only_space", 0x05731): (99, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x05759): (101, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05781): (102, "ModuleRequestMap"),
|
||||
("read_only_space", 0x057a9): (103, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x057d1): (104, "PromiseReactionMap"),
|
||||
("read_only_space", 0x057f9): (105, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x05821): (106, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x05849): (107, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x05871): (108, "ScriptMap"),
|
||||
("read_only_space", 0x05899): (109, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x058c1): (110, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x058e9): (111, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x05911): (112, "Tuple2Map"),
|
||||
("read_only_space", 0x05939): (113, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05961): (114, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x05989): (115, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x059b1): (116, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x059d9): (135, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x05a01): (152, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x05a29): (157, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x05a51): (156, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x05a79): (172, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x05aa1): (182, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x05ac9): (169, "InternalClassMap"),
|
||||
("read_only_space", 0x05af1): (178, "SmiPairMap"),
|
||||
("read_only_space", 0x05b19): (177, "SmiBoxMap"),
|
||||
("read_only_space", 0x05b41): (146, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x05b69): (147, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x05b91): (68, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x05bb9): (69, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x05be1): (133, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05c09): (170, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x05c31): (148, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x05c59): (179, "SortStateMap"),
|
||||
("read_only_space", 0x05c81): (86, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05ca9): (86, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05cd1): (77, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05cf9): (77, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05d21): (77, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05d49): (78, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05d71): (78, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05d99): (78, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05dc1): (78, "StoreHandler3Map"),
|
||||
("read_only_space", 0x03291): (100, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x053e5): (72, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x0540d): (73, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05435): (74, "CallableTaskMap"),
|
||||
("read_only_space", 0x0545d): (75, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05485): (76, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x054ad): (79, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x054d5): (80, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x054fd): (81, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x05525): (82, "AccessorInfoMap"),
|
||||
("read_only_space", 0x0554d): (83, "AccessorPairMap"),
|
||||
("read_only_space", 0x05575): (84, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x0559d): (85, "AllocationMementoMap"),
|
||||
("read_only_space", 0x055c5): (88, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x055ed): (89, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x05615): (90, "BaselineDataMap"),
|
||||
("read_only_space", 0x0563d): (91, "BreakPointMap"),
|
||||
("read_only_space", 0x05665): (92, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x0568d): (93, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x056b5): (95, "ClassPositionsMap"),
|
||||
("read_only_space", 0x056dd): (96, "DebugInfoMap"),
|
||||
("read_only_space", 0x05705): (99, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x0572d): (101, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05755): (102, "ModuleRequestMap"),
|
||||
("read_only_space", 0x0577d): (103, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x057a5): (104, "PromiseReactionMap"),
|
||||
("read_only_space", 0x057cd): (105, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x057f5): (106, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x0581d): (107, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x05845): (108, "ScriptMap"),
|
||||
("read_only_space", 0x0586d): (109, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x05895): (110, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x058bd): (111, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x058e5): (112, "Tuple2Map"),
|
||||
("read_only_space", 0x0590d): (113, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05935): (114, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x0595d): (115, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x05985): (116, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x059ad): (135, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x059d5): (152, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x059fd): (157, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x05a25): (156, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x05a4d): (172, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x05a75): (182, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x05a9d): (169, "InternalClassMap"),
|
||||
("read_only_space", 0x05ac5): (178, "SmiPairMap"),
|
||||
("read_only_space", 0x05aed): (177, "SmiBoxMap"),
|
||||
("read_only_space", 0x05b15): (146, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x05b3d): (147, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x05b65): (68, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x05b8d): (69, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x05bb5): (133, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05bdd): (170, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x05c05): (148, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x05c2d): (179, "SortStateMap"),
|
||||
("read_only_space", 0x05c55): (86, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05c7d): (86, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05ca5): (77, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05ccd): (77, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05cf5): (77, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05d1d): (78, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05d45): (78, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05d6d): (78, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05d95): (78, "StoreHandler3Map"),
|
||||
("map_space", 0x02119): (1057, "ExternalMap"),
|
||||
("map_space", 0x02141): (1098, "JSMessageObjectMap"),
|
||||
}
|
||||
@ -422,21 +422,20 @@ KNOWN_OBJECTS = {
|
||||
("read_only_space", 0x03245): "EmptyFeedbackMetadata",
|
||||
("read_only_space", 0x03251): "EmptyPropertyDictionary",
|
||||
("read_only_space", 0x03279): "EmptyOrderedPropertyDictionary",
|
||||
("read_only_space", 0x03291): "EmptySwissPropertyDictionary",
|
||||
("read_only_space", 0x032e5): "NoOpInterceptorInfo",
|
||||
("read_only_space", 0x0330d): "EmptyWeakArrayList",
|
||||
("read_only_space", 0x03319): "InfinityValue",
|
||||
("read_only_space", 0x03325): "MinusZeroValue",
|
||||
("read_only_space", 0x03331): "MinusInfinityValue",
|
||||
("read_only_space", 0x0333d): "SelfReferenceMarker",
|
||||
("read_only_space", 0x0337d): "BasicBlockCountersMarker",
|
||||
("read_only_space", 0x033c1): "OffHeapTrampolineRelocationInfo",
|
||||
("read_only_space", 0x033cd): "TrampolineTrivialCodeDataContainer",
|
||||
("read_only_space", 0x033d9): "TrampolinePromiseRejectionCodeDataContainer",
|
||||
("read_only_space", 0x033e5): "GlobalThisBindingScopeInfo",
|
||||
("read_only_space", 0x0341d): "EmptyFunctionScopeInfo",
|
||||
("read_only_space", 0x03445): "NativeScopeInfo",
|
||||
("read_only_space", 0x03461): "HashSeed",
|
||||
("read_only_space", 0x032b9): "NoOpInterceptorInfo",
|
||||
("read_only_space", 0x032e1): "EmptyWeakArrayList",
|
||||
("read_only_space", 0x032ed): "InfinityValue",
|
||||
("read_only_space", 0x032f9): "MinusZeroValue",
|
||||
("read_only_space", 0x03305): "MinusInfinityValue",
|
||||
("read_only_space", 0x03311): "SelfReferenceMarker",
|
||||
("read_only_space", 0x03351): "BasicBlockCountersMarker",
|
||||
("read_only_space", 0x03395): "OffHeapTrampolineRelocationInfo",
|
||||
("read_only_space", 0x033a1): "TrampolineTrivialCodeDataContainer",
|
||||
("read_only_space", 0x033ad): "TrampolinePromiseRejectionCodeDataContainer",
|
||||
("read_only_space", 0x033b9): "GlobalThisBindingScopeInfo",
|
||||
("read_only_space", 0x033f1): "EmptyFunctionScopeInfo",
|
||||
("read_only_space", 0x03419): "NativeScopeInfo",
|
||||
("read_only_space", 0x03435): "HashSeed",
|
||||
("old_space", 0x02119): "ArgumentsIteratorAccessor",
|
||||
("old_space", 0x0215d): "ArrayLengthAccessor",
|
||||
("old_space", 0x021a1): "BoundFunctionLengthAccessor",
|
||||
|
Loading…
Reference in New Issue
Block a user