Commit d1e751e2 authored by Frank Emrich's avatar Frank Emrich Committed by Commit Bot

[dict-proto] CSA/Torque implementation of SwissNameDictionary, pt. 3

This CL adds:

a) Allocation and Copy operations on the CSA side

b) Helpers needed for that on both the CSA and Torque side

Bug: v8:11330
Change-Id: I322c84e1762d2d3503a0d4809c6e1c0bc9d442e1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2775563Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73651}
parent c10aa432
......@@ -457,12 +457,13 @@ const kNameDictionaryInitialCapacity:
constexpr int32 generates 'NameDictionary::kInitialCapacity';
const kSwissNameDictionaryInitialCapacity:
constexpr int32 generates 'SwissNameDictionary::kInitialCapacity';
const kSwissNameDictionaryGroupWidth:
constexpr int32 generates 'SwissNameDictionary::kGroupWidth';
const kWasmArrayHeaderSize:
constexpr int32 generates 'WasmArray::kHeaderSize';
const kHeapObjectHeaderSize:
constexpr int32 generates 'HeapObject::kHeaderSize';
const kDictModePrototypes:
constexpr bool generates 'V8_DICT_MODE_PROTOTYPES_BOOL';
......@@ -1094,6 +1095,7 @@ extern macro IntPtrToTaggedIndex(intptr): TaggedIndex;
extern macro TaggedIndexToSmi(TaggedIndex): Smi;
extern macro SmiToTaggedIndex(Smi): TaggedIndex;
extern macro RoundIntPtrToFloat64(intptr): float64;
extern macro IntPtrRoundUpToPowerOfTwo32(intptr): intptr;
extern macro ChangeFloat32ToFloat64(float32): float64;
extern macro ChangeNumberToFloat64(Number): float64;
extern macro ChangeNumberToUint32(Number): uint32;
......
This diff is collapsed.
......@@ -1728,6 +1728,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint,
TNode<IntPtrT> digit_index);
// Allocate a ByteArray with the given non-zero length.
TNode<ByteArray> AllocateNonEmptyByteArray(TNode<UintPtrT> length,
AllocationFlags flags);
// Allocate a ByteArray with the given length.
TNode<ByteArray> AllocateByteArray(TNode<UintPtrT> length,
AllocationFlags flags = kNone);
......@@ -3723,6 +3727,18 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<SwissNameDictionary> AllocateSwissNameDictionary(
int at_least_space_for);
TNode<SwissNameDictionary> AllocateSwissNameDictionaryWithCapacity(
TNode<IntPtrT> capacity);
// MT stands for "minus tag".
TNode<IntPtrT> SwissNameDictionaryOffsetIntoDataTableMT(
TNode<SwissNameDictionary> dict, TNode<IntPtrT> index, int field_index);
// MT stands for "minus tag".
TNode<IntPtrT> SwissNameDictionaryOffsetIntoPropertyDetailsTableMT(
TNode<SwissNameDictionary> dict, TNode<IntPtrT> capacity,
TNode<IntPtrT> index);
TNode<IntPtrT> LoadSwissNameDictionaryNumberOfElements(
TNode<SwissNameDictionary> table, TNode<IntPtrT> capacity);
......@@ -3743,12 +3759,18 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Uint32T> SwissNameDictionaryUpdateCountsForDeletion(
TNode<ByteArray> meta_table, TNode<IntPtrT> capacity);
void StoreSwissNameDictionaryCapacity(TNode<SwissNameDictionary> table,
TNode<Int32T> capacity);
void StoreSwissNameDictionaryEnumToEntryMapping(
TNode<SwissNameDictionary> table, TNode<IntPtrT> capacity,
TNode<IntPtrT> enum_index, TNode<Int32T> entry);
TNode<Uint64T> LoadSwissNameDictionaryCtrlTableGroup(TNode<IntPtrT> address);
TNode<SwissNameDictionary> CopySwissNameDictionary(
TNode<SwissNameDictionary> original);
private:
friend class CodeStubArguments;
......
......@@ -202,6 +202,11 @@ static_assert(kDeleted == -2,
// Table implementations rely on this being 7.
static constexpr int kH2Bits = 7;
static constexpr int kNotFullMask = (1 << kH2Bits);
static_assert(
kEmpty & kDeleted & kSentinel & kNotFullMask,
"Special markers need to have the MSB to make checking for them efficient");
// Extracts H1 from the given overall hash, which means discarding the lowest 7
// bits of the overall hash. H1 is used to determine the first group to probe.
inline static uint32_t H1(uint32_t hash) { return (hash >> kH2Bits); }
......
......@@ -10,6 +10,102 @@ extern class SwissNameDictionary extends HeapObject {
const capacity: int32;
meta_table: ByteArray;
data_table[Convert<intptr>(capacity) * 2]: JSAny|TheHole;
ctrl_table[Convert<intptr>(capacity) + kSwissNameDictionaryGroupWidth]: uint8;
ctrl_table[Convert<intptr>(capacity) + swiss_table::kGroupWidth]: uint8;
property_details_table[Convert<intptr>(capacity)]: uint8;
}
namespace swiss_table {
const kDataTableEntryCount: constexpr intptr
generates 'SwissNameDictionary::kDataTableEntryCount';
const kMax1ByteMetaTableCapacity: constexpr int32
generates 'SwissNameDictionary::kMax1ByteMetaTableCapacity';
const kMax2ByteMetaTableCapacity: constexpr int32
generates 'SwissNameDictionary::kMax2ByteMetaTableCapacity';
// Counterpart for SwissNameDictionary::CapacityFor in C++.
@export
macro SwissNameDictionaryCapacityFor(atLeastSpaceFor: intptr): intptr {
if (atLeastSpaceFor <= 4) {
if (atLeastSpaceFor == 0) {
return 0;
} else if (atLeastSpaceFor < kSwissNameDictionaryInitialCapacity) {
return 4;
} else if (FromConstexpr<bool>(kGroupWidth == 16)) {
assert(atLeastSpaceFor == 4);
return 4;
} else if (FromConstexpr<bool>(kGroupWidth == 8)) {
assert(atLeastSpaceFor == 4);
return 8;
}
}
const nonNormalized = atLeastSpaceFor + atLeastSpaceFor / 7;
return IntPtrRoundUpToPowerOfTwo32(nonNormalized);
}
// Counterpart for SwissNameDictionary::MaxUsableCapacity in C++.
@export
macro SwissNameDictionaryMaxUsableCapacity(capacity: intptr): intptr {
assert(capacity == 0 || capacity >= kSwissNameDictionaryInitialCapacity);
if (FromConstexpr<bool>(kGroupWidth == 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;
}
// Counterpart for SwissNameDictionary::SizeFor in C++.
@export
macro SwissNameDictionarySizeFor(capacity: intptr): intptr {
const constant: constexpr int32 = kHeapObjectHeaderSize + 8 + kTaggedSize;
const dynamic: intptr =
capacity * FromConstexpr<intptr>(2 * kTaggedSize + 2) +
FromConstexpr<intptr>(kGroupWidth);
return constant + dynamic;
}
// Counterpart for SwissNameDictionary::MetaTableSizePerEntryFor in C++.
@export
macro SwissNameDictionaryMetaTableSizePerEntryFor(capacity: intptr): intptr {
if (capacity <= kMax1ByteMetaTableCapacity) {
return 1;
} else if (capacity <= kMax2ByteMetaTableCapacity) {
return 2;
} else {
return 4;
}
}
// Counterpart for SwissNameDictionary::MetaTableSizeFor in C++.
@export
macro SwissNameDictionaryMetaTableSizeFor(capacity: intptr): intptr {
const perEntry: intptr =
SwissNameDictionaryMetaTableSizePerEntryFor(capacity);
const maxUsable: intptr =
Convert<intptr>(SwissNameDictionaryMaxUsableCapacity(capacity));
return (2 + maxUsable) * perEntry;
}
//
// Offsets. MT stands for "minus tag"
//
const kDataTableStartOffsetMT: constexpr intptr
generates 'SwissNameDictionary::DataTableStartOffset() - kHeapObjectTag';
@export
macro SwissNameDictionaryDataTableStartOffsetMT(): intptr {
return kDataTableStartOffsetMT;
}
@export
macro SwissNameDictionaryCtrlTableStartOffsetMT(capacity: intptr): intptr {
return kDataTableStartOffsetMT +
kDataTableEntryCount * FromConstexpr<intptr>(kTaggedSize) * capacity;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment