Skip to content

Commit 1ad0cd5

Browse files
ulanCommit Bot
authored andcommitted
Separate DescriptorArray from WeakFixedArray
This patch gives DescriptorArray its own visitor id and its own layout that is independent from the layout of WeakFixedArray. This allows us to use raw 16-bit integers for keeping track of the number of descriptors (total, non-slack, and marked). As a side-effect, we save one word per descriptor array on 64-bit. v8:8486 Change-Id: If8389dde446319e5b3491abc948b52539dba235c Reviewed-on: https://chromium-review.googlesource.com/c/1349245 Commit-Queue: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#57845}
1 parent 0397f78 commit 1ad0cd5

36 files changed

+590
-448
lines changed

src/api.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4399,7 +4399,7 @@ MaybeLocal<Array> v8::Object::GetPropertyNames(
43994399
accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
44004400
DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
44014401
self->map()->EnumLength() == 0 ||
4402-
self->map()->instance_descriptors()->GetEnumCache()->keys() != *value);
4402+
self->map()->instance_descriptors()->enum_cache()->keys() != *value);
44034403
auto result = isolate->factory()->NewJSArrayWithElements(value);
44044404
RETURN_ESCAPED(Utils::ToLocal(result));
44054405
}

src/base/atomicops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace v8 {
4040
namespace base {
4141

4242
typedef char Atomic8;
43+
typedef int16_t Atomic16;
4344
typedef int32_t Atomic32;
4445
#if defined(V8_HOST_ARCH_64_BIT)
4546
// We need to be able to go between Atomic64 and AtomicWord implicitly. This
@@ -97,10 +98,12 @@ Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
9798

9899
void SeqCst_MemoryFence();
99100
void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value);
101+
void Relaxed_Store(volatile Atomic16* ptr, Atomic16 value);
100102
void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value);
101103
void Release_Store(volatile Atomic32* ptr, Atomic32 value);
102104

103105
Atomic8 Relaxed_Load(volatile const Atomic8* ptr);
106+
Atomic16 Relaxed_Load(volatile const Atomic16* ptr);
104107
Atomic32 Relaxed_Load(volatile const Atomic32* ptr);
105108
Atomic32 Acquire_Load(volatile const Atomic32* ptr);
106109

src/base/atomicops_internals_portable.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ inline void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value) {
9898
__atomic_store_n(ptr, value, __ATOMIC_RELAXED);
9999
}
100100

101+
inline void Relaxed_Store(volatile Atomic16* ptr, Atomic16 value) {
102+
__atomic_store_n(ptr, value, __ATOMIC_RELAXED);
103+
}
104+
101105
inline void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value) {
102106
__atomic_store_n(ptr, value, __ATOMIC_RELAXED);
103107
}
@@ -110,6 +114,10 @@ inline Atomic8 Relaxed_Load(volatile const Atomic8* ptr) {
110114
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
111115
}
112116

117+
inline Atomic16 Relaxed_Load(volatile const Atomic16* ptr) {
118+
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
119+
}
120+
113121
inline Atomic32 Relaxed_Load(volatile const Atomic32* ptr) {
114122
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
115123
}

src/base/atomicops_internals_std.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ inline void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value) {
8686
std::memory_order_relaxed);
8787
}
8888

89+
inline void Relaxed_Store(volatile Atomic16* ptr, Atomic16 value) {
90+
std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
91+
std::memory_order_relaxed);
92+
}
93+
8994
inline void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value) {
9095
std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
9196
std::memory_order_relaxed);
@@ -101,6 +106,11 @@ inline Atomic8 Relaxed_Load(volatile const Atomic8* ptr) {
101106
std::memory_order_relaxed);
102107
}
103108

109+
inline Atomic16 Relaxed_Load(volatile const Atomic16* ptr) {
110+
return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
111+
std::memory_order_relaxed);
112+
}
113+
104114
inline Atomic32 Relaxed_Load(volatile const Atomic32* ptr) {
105115
return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
106116
std::memory_order_relaxed);

src/builtins/builtins-function-gen.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
4747
Comment("Check descriptor array length");
4848
TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map);
4949
// Minimum descriptor array length required for fast path.
50-
const int min_descriptors_length = DescriptorArray::LengthFor(i::Max(
51-
JSFunction::kLengthDescriptorIndex, JSFunction::kNameDescriptorIndex));
52-
TNode<Smi> descriptors_length = LoadWeakFixedArrayLength(descriptors);
53-
GotoIf(SmiLessThanOrEqual(descriptors_length,
54-
SmiConstant(min_descriptors_length)),
55-
&slow);
50+
const int min_nof_descriptors = i::Max(JSFunction::kLengthDescriptorIndex,
51+
JSFunction::kNameDescriptorIndex);
52+
TNode<Int32T> nof_descriptors = LoadNumberOfDescriptors(descriptors);
53+
GotoIf(
54+
Int32LessThanOrEqual(nof_descriptors, Int32Constant(min_nof_descriptors)),
55+
&slow);
5656

5757
// Check whether the length and name properties are still present as
5858
// AccessorInfo objects. In that case, their value can be recomputed even if

src/code-stub-assembler.cc

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,13 @@ TNode<IntPtrT> CodeStubAssembler::LoadAndUntagWeakFixedArrayLength(
16051605
return LoadAndUntagObjectField(array, WeakFixedArray::kLengthOffset);
16061606
}
16071607

1608+
TNode<Int32T> CodeStubAssembler::LoadNumberOfDescriptors(
1609+
TNode<DescriptorArray> array) {
1610+
return UncheckedCast<Int32T>(
1611+
LoadObjectField(array, DescriptorArray::kNumberOfDescriptorsOffset,
1612+
MachineType::Int16()));
1613+
}
1614+
16081615
TNode<Int32T> CodeStubAssembler::LoadMapBitField(SloppyTNode<Map> map) {
16091616
CSA_SLOW_ASSERT(this, IsMap(map));
16101617
return UncheckedCast<Int32T>(
@@ -1961,7 +1968,8 @@ TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<PropertyArray> array) {
19611968
template <>
19621969
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
19631970
TNode<DescriptorArray> array) {
1964-
return LoadAndUntagWeakFixedArrayLength(array);
1971+
return IntPtrMul(ChangeInt32ToIntPtr(LoadNumberOfDescriptors(array)),
1972+
IntPtrConstant(DescriptorArray::kEntrySize));
19651973
}
19661974

19671975
template <>
@@ -8701,7 +8709,8 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
87018709
TVariable<IntPtrT>* var_name_index,
87028710
Label* if_not_found) {
87038711
static_assert(std::is_base_of<FixedArray, Array>::value ||
8704-
std::is_base_of<WeakFixedArray, Array>::value,
8712+
std::is_base_of<WeakFixedArray, Array>::value ||
8713+
std::is_base_of<DescriptorArray, Array>::value,
87058714
"T must be a descendant of FixedArray or a WeakFixedArray");
87068715
Comment("LookupLinear");
87078716
TNode<IntPtrT> first_inclusive = IntPtrConstant(Array::ToKeyIndex(0));
@@ -8725,9 +8734,7 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
87258734
template <>
87268735
TNode<Uint32T> CodeStubAssembler::NumberOfEntries<DescriptorArray>(
87278736
TNode<DescriptorArray> descriptors) {
8728-
return Unsigned(LoadAndUntagToWord32ArrayElement(
8729-
descriptors, WeakFixedArray::kHeaderSize,
8730-
IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)));
8737+
return Unsigned(LoadNumberOfDescriptors(descriptors));
87318738
}
87328739

87338740
template <>
@@ -8780,9 +8787,9 @@ TNode<Uint32T> CodeStubAssembler::GetSortedKeyIndex<TransitionArray>(
87808787
template <typename Array>
87818788
TNode<Name> CodeStubAssembler::GetKey(TNode<Array> array,
87828789
TNode<Uint32T> entry_index) {
8783-
static_assert(std::is_base_of<FixedArray, Array>::value ||
8784-
std::is_base_of<WeakFixedArray, Array>::value,
8785-
"T must be a descendant of FixedArray or a TransitionArray");
8790+
static_assert(std::is_base_of<TransitionArray, Array>::value ||
8791+
std::is_base_of<DescriptorArray, Array>::value,
8792+
"T must be a descendant of DescriptorArray or TransitionArray");
87868793
const int key_offset = Array::ToKeyIndex(0) * kPointerSize;
87878794
TNode<MaybeObject> element =
87888795
LoadArrayElement(array, Array::kHeaderSize,
@@ -13703,8 +13710,8 @@ void CodeStubAssembler::GotoIfInitialPrototypePropertiesModified(
1370313710
for (int i = 0; i < properties.length(); i++) {
1370413711
// Assert the descriptor index is in-bounds.
1370513712
int descriptor = properties[i].descriptor_index;
13706-
CSA_ASSERT(this, SmiLessThan(SmiConstant(descriptor),
13707-
LoadWeakFixedArrayLength(descriptors)));
13713+
CSA_ASSERT(this, Int32LessThan(Int32Constant(descriptor),
13714+
LoadNumberOfDescriptors(descriptors)));
1370813715
// Assert that the name is correct. This essentially checks that
1370913716
// the descriptor index corresponds to the insertion order in
1371013717
// the bootstrapper.

src/code-stub-assembler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
931931
TNode<Smi> LoadWeakFixedArrayLength(TNode<WeakFixedArray> array);
932932
TNode<IntPtrT> LoadAndUntagWeakFixedArrayLength(
933933
SloppyTNode<WeakFixedArray> array);
934+
// Load the number of descriptors in DescriptorArray.
935+
TNode<Int32T> LoadNumberOfDescriptors(TNode<DescriptorArray> array);
934936
// Load the bit field of a Map.
935937
TNode<Int32T> LoadMapBitField(SloppyTNode<Map> map);
936938
// Load bit field 2 of a map.

src/heap/factory.cc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,6 @@ Handle<T> Factory::NewWeakFixedArrayWithMap(RootIndex map_root_index,
343343
template Handle<FixedArray> Factory::NewFixedArrayWithMap<FixedArray>(
344344
RootIndex, int, PretenureFlag);
345345

346-
template Handle<DescriptorArray>
347-
Factory::NewWeakFixedArrayWithMap<DescriptorArray>(RootIndex, int,
348-
PretenureFlag);
349-
350346
Handle<FixedArray> Factory::NewFixedArray(int length, PretenureFlag pretenure) {
351347
DCHECK_LE(0, length);
352348
if (length == 0) return empty_fixed_array();
@@ -1857,6 +1853,22 @@ Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name,
18571853
return cell;
18581854
}
18591855

1856+
Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
1857+
int slack) {
1858+
int number_of_all_descriptors = number_of_descriptors + slack;
1859+
// Zero-length case must be handled outside.
1860+
DCHECK_LT(0, number_of_all_descriptors);
1861+
int size = DescriptorArray::SizeFor(number_of_all_descriptors);
1862+
DCHECK_LT(size, kMaxRegularHeapObjectSize);
1863+
HeapObject* obj =
1864+
isolate()->heap()->AllocateRawWithRetryOrFail(size, OLD_SPACE);
1865+
obj->set_map_after_allocation(*descriptor_array_map(), SKIP_WRITE_BARRIER);
1866+
DescriptorArray* array = DescriptorArray::cast(obj);
1867+
array->Initialize(*empty_enum_cache(), *undefined_value(),
1868+
number_of_descriptors, slack);
1869+
return Handle<DescriptorArray>(array, isolate());
1870+
}
1871+
18601872
Handle<TransitionArray> Factory::NewTransitionArray(int number_of_transitions,
18611873
int slack) {
18621874
int capacity = TransitionArray::LengthFor(number_of_transitions + slack);

src/heap/factory.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,8 @@ class V8_EXPORT_PRIVATE Factory {
483483
Handle<FeedbackCell> NewManyClosuresCell(Handle<HeapObject> value);
484484
Handle<FeedbackCell> NewNoFeedbackCell();
485485

486+
Handle<DescriptorArray> NewDescriptorArray(int number_of_entries,
487+
int slack = 0);
486488
Handle<TransitionArray> NewTransitionArray(int number_of_transitions,
487489
int slack = 0);
488490

src/heap/mark-compact-inl.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,16 @@ void MarkingVisitor<fixed_array_mode, retaining_path_mode,
367367
// just mark the entire descriptor array.
368368
if (!map->is_prototype_map()) {
369369
DescriptorArray* descriptors = map->instance_descriptors();
370-
if (MarkObjectWithoutPush(map, descriptors) && descriptors->length() > 0) {
371-
VisitPointers(descriptors, descriptors->data_start(),
372-
descriptors->GetDescriptorEndSlot(0));
370+
if (MarkObjectWithoutPush(map, descriptors)) {
371+
VisitPointers(descriptors, descriptors->GetFirstPointerSlot(),
372+
descriptors->GetDescriptorSlot(0));
373373
}
374374
int start = 0;
375375
int end = map->NumberOfOwnDescriptors();
376376
if (start < end) {
377-
VisitPointers(descriptors, descriptors->GetDescriptorStartSlot(start),
378-
descriptors->GetDescriptorEndSlot(end));
377+
VisitPointers(descriptors,
378+
MaybeObjectSlot(descriptors->GetDescriptorSlot(start)),
379+
MaybeObjectSlot(descriptors->GetDescriptorSlot(end)));
379380
}
380381
}
381382

0 commit comments

Comments
 (0)