Commit 69cec109 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[csa] Use high-level DescriptorArray accessors.

This fixes places that assume that DescriptorArray is a WeakFixedArray.

In addition to the existing:
 - LoadDetailsByKeyIndex
 - LoadValueByKeyIndex
 - LoadFieldTypeByKeyIndex
This introduces Load*ByDescriptorEntry versions and LoadKeyByKeyIndex.

Bug: v8:8486
Change-Id: I958867138df7756c715ae3d449b3206a32076514
Reviewed-on: https://chromium-review.googlesource.com/c/1346501
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57727}
parent 8c124893
......@@ -60,24 +60,23 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
Comment("Check name and length properties");
{
const int length_index = JSFunction::kLengthDescriptorIndex;
TNode<Name> maybe_length = CAST(LoadWeakFixedArrayElement(
descriptors, DescriptorArray::ToKeyIndex(length_index)));
TNode<Name> maybe_length =
LoadKeyByDescriptorEntry(descriptors, length_index);
GotoIf(WordNotEqual(maybe_length, LoadRoot(RootIndex::klength_string)),
&slow);
TNode<Object> maybe_length_accessor = CAST(LoadWeakFixedArrayElement(
descriptors, DescriptorArray::ToValueIndex(length_index)));
TNode<Object> maybe_length_accessor =
LoadValueByDescriptorEntry(descriptors, length_index);
GotoIf(TaggedIsSmi(maybe_length_accessor), &slow);
Node* length_value_map = LoadMap(CAST(maybe_length_accessor));
GotoIfNot(IsAccessorInfoMap(length_value_map), &slow);
const int name_index = JSFunction::kNameDescriptorIndex;
TNode<Name> maybe_name = CAST(LoadWeakFixedArrayElement(
descriptors, DescriptorArray::ToKeyIndex(name_index)));
TNode<Name> maybe_name = LoadKeyByDescriptorEntry(descriptors, name_index);
GotoIf(WordNotEqual(maybe_name, LoadRoot(RootIndex::kname_string)), &slow);
TNode<Object> maybe_name_accessor = CAST(LoadWeakFixedArrayElement(
descriptors, DescriptorArray::ToValueIndex(name_index)));
TNode<Object> maybe_name_accessor =
LoadValueByDescriptorEntry(descriptors, name_index);
GotoIf(TaggedIsSmi(maybe_name_accessor), &slow);
TNode<Map> name_value_map = LoadMap(CAST(maybe_name_accessor));
GotoIfNot(IsAccessorInfoMap(name_value_map), &slow);
......
......@@ -318,15 +318,15 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries(
// Currently, we will not invoke getters,
// so, map will not be changed.
CSA_ASSERT(this, WordEqual(map, LoadMap(object)));
TNode<Uint32T> descriptor_index = TNode<Uint32T>::UncheckedCast(
TruncateIntPtrToInt32(var_descriptor_number.value()));
Node* next_key = GetKey(descriptors, descriptor_index);
TNode<IntPtrT> descriptor_entry = var_descriptor_number.value();
Node* next_key = LoadKeyByDescriptorEntry(descriptors, descriptor_entry);
// Skip Symbols.
GotoIf(IsSymbol(next_key), &next_descriptor);
TNode<Uint32T> details = TNode<Uint32T>::UncheckedCast(
DescriptorArrayGetDetails(descriptors, descriptor_index));
TNode<Uint32T> details =
LoadDetailsByDescriptorEntry(descriptors, descriptor_entry);
TNode<Uint32T> kind = LoadPropertyKind(details);
// If property is accessor, we escape fast path and call runtime.
......
......@@ -2902,14 +2902,14 @@ void CodeStubAssembler::EnsureArrayLengthWritable(TNode<Map> map,
int length_index = JSArray::kLengthDescriptorIndex;
#ifdef DEBUG
TNode<Name> maybe_length = CAST(LoadWeakFixedArrayElement(
descriptors, DescriptorArray::ToKeyIndex(length_index)));
TNode<Name> maybe_length =
LoadKeyByDescriptorEntry(descriptors, length_index);
CSA_ASSERT(this,
WordEqual(maybe_length, LoadRoot(RootIndex::klength_string)));
#endif
TNode<Uint32T> details = LoadDetailsByKeyIndex(
descriptors, IntPtrConstant(DescriptorArray::ToKeyIndex(length_index)));
TNode<Uint32T> details =
LoadDetailsByDescriptorEntry(descriptors, length_index);
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
bailout);
}
......@@ -8230,30 +8230,81 @@ TNode<IntPtrT> CodeStubAssembler::EntryToIndex(TNode<IntPtrT> entry,
field_index));
}
TNode<Name> CodeStubAssembler::LoadKeyByKeyIndex(
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
return CAST(LoadWeakFixedArrayElement(container, key_index, 0));
}
TNode<Uint32T> CodeStubAssembler::LoadDetailsByKeyIndex(
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
const int kKeyToDetailsOffset =
(DescriptorArray::kEntryDetailsIndex - DescriptorArray::kEntryKeyIndex) *
kPointerSize;
const int kKeyToDetails =
DescriptorArray::ToDetailsIndex(0) - DescriptorArray::ToKeyIndex(0);
return Unsigned(LoadAndUntagToWord32ArrayElement(
container, WeakFixedArray::kHeaderSize, key_index, kKeyToDetailsOffset));
container, WeakFixedArray::kHeaderSize, key_index,
kKeyToDetails * kPointerSize));
}
TNode<Object> CodeStubAssembler::LoadValueByKeyIndex(
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
const int kKeyToValueOffset =
(DescriptorArray::kEntryValueIndex - DescriptorArray::kEntryKeyIndex) *
kPointerSize;
return CAST(
LoadWeakFixedArrayElement(container, key_index, kKeyToValueOffset));
const int kKeyToValue =
DescriptorArray::ToValueIndex(0) - DescriptorArray::ToKeyIndex(0);
return CAST(LoadWeakFixedArrayElement(container, key_index,
kKeyToValue * kPointerSize));
}
TNode<MaybeObject> CodeStubAssembler::LoadFieldTypeByKeyIndex(
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
const int kKeyToValueOffset =
(DescriptorArray::kEntryValueIndex - DescriptorArray::kEntryKeyIndex) *
kPointerSize;
return LoadWeakFixedArrayElement(container, key_index, kKeyToValueOffset);
const int kKeyToValue =
DescriptorArray::ToValueIndex(0) - DescriptorArray::ToKeyIndex(0);
return LoadWeakFixedArrayElement(container, key_index,
kKeyToValue * kPointerSize);
}
TNode<IntPtrT> CodeStubAssembler::DescriptorEntryToIndex(
TNode<IntPtrT> descriptor_entry) {
return IntPtrMul(descriptor_entry,
IntPtrConstant(DescriptorArray::kEntrySize));
}
TNode<Name> CodeStubAssembler::LoadKeyByDescriptorEntry(
TNode<DescriptorArray> container, TNode<IntPtrT> descriptor_entry) {
return CAST(LoadWeakFixedArrayElement(
container, DescriptorEntryToIndex(descriptor_entry),
DescriptorArray::ToKeyIndex(0) * kPointerSize));
}
TNode<Name> CodeStubAssembler::LoadKeyByDescriptorEntry(
TNode<DescriptorArray> container, int descriptor_entry) {
return CAST(LoadWeakFixedArrayElement(
container, DescriptorArray::ToKeyIndex(descriptor_entry)));
}
TNode<Uint32T> CodeStubAssembler::LoadDetailsByDescriptorEntry(
TNode<DescriptorArray> container, TNode<IntPtrT> descriptor_entry) {
return Unsigned(LoadAndUntagToWord32ArrayElement(
container, WeakFixedArray::kHeaderSize,
DescriptorEntryToIndex(descriptor_entry),
DescriptorArray::ToDetailsIndex(0) * kPointerSize));
}
TNode<Uint32T> CodeStubAssembler::LoadDetailsByDescriptorEntry(
TNode<DescriptorArray> container, int descriptor_entry) {
return Unsigned(LoadAndUntagToWord32ArrayElement(
container, WeakFixedArray::kHeaderSize, IntPtrConstant(0),
DescriptorArray::ToDetailsIndex(descriptor_entry) * kPointerSize));
}
TNode<Object> CodeStubAssembler::LoadValueByDescriptorEntry(
TNode<DescriptorArray> container, int descriptor_entry) {
return CAST(LoadWeakFixedArrayElement(
container, DescriptorArray::ToValueIndex(descriptor_entry)));
}
TNode<MaybeObject> CodeStubAssembler::LoadFieldTypeByDescriptorEntry(
TNode<DescriptorArray> container, TNode<IntPtrT> descriptor_entry) {
return LoadWeakFixedArrayElement(
container, DescriptorEntryToIndex(descriptor_entry),
DescriptorArray::ToValueIndex(0) * kPointerSize);
}
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<NameDictionary>(
......@@ -8809,18 +8860,13 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
void CodeStubAssembler::DescriptorArrayForEach(
VariableList& variable_list, TNode<Uint32T> start_descriptor,
TNode<Uint32T> end_descriptor, const ForEachDescriptorBodyFunction& body) {
TNode<IntPtrT> start_index =
IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
EntryIndexToIndex<DescriptorArray>(start_descriptor));
TNode<IntPtrT> end_index =
IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
EntryIndexToIndex<DescriptorArray>(end_descriptor));
TNode<IntPtrT> start_index = ToKeyIndex<DescriptorArray>(start_descriptor);
TNode<IntPtrT> end_index = ToKeyIndex<DescriptorArray>(end_descriptor);
BuildFastLoop(variable_list, start_index, end_index,
[=](Node* index) {
TNode<UintPtrT> descriptor_key_index =
TNode<UintPtrT>::UncheckedCast(index);
TNode<IntPtrT> descriptor_key_index =
TNode<IntPtrT>::UncheckedCast(index);
body(descriptor_key_index);
},
DescriptorArray::kEntrySize, INTPTR_PARAMETERS,
......@@ -8842,9 +8888,9 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty(
DescriptorArrayForEach(
list, Unsigned(Int32Constant(0)), nof_descriptors,
[=, &var_stable](TNode<UintPtrT> descriptor_key_index) {
[=, &var_stable](TNode<IntPtrT> descriptor_key_index) {
TNode<Name> next_key =
CAST(LoadWeakFixedArrayElement(descriptors, descriptor_key_index));
LoadKeyByKeyIndex(descriptors, descriptor_key_index);
TVARIABLE(Object, var_value, SmiConstant(0));
Label callback(this), next_iteration(this);
......@@ -13644,10 +13690,9 @@ void CodeStubAssembler::GotoIfInitialPrototypePropertiesModified(
// Assert that the name is correct. This essentially checks that
// the descriptor index corresponds to the insertion order in
// the bootstrapper.
CSA_ASSERT(this, WordEqual(LoadWeakFixedArrayElement(
descriptors,
DescriptorArray::ToKeyIndex(descriptor)),
LoadRoot(properties[i].name_root_index)));
CSA_ASSERT(this,
WordEqual(LoadKeyByDescriptorEntry(descriptors, descriptor),
LoadRoot(properties[i].name_root_index)));
TNode<Uint32T> details =
DescriptorArrayGetDetails(descriptors, Uint32Constant(descriptor));
......
......@@ -2474,13 +2474,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return LoadFixedArrayElement(CAST(container), key_index, kKeyToValueOffset);
}
TNode<Uint32T> LoadDetailsByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<Object> LoadValueByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<MaybeObject> LoadFieldTypeByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
// Stores the details for the entry with the given key_index.
// |details| must be a Smi.
template <class ContainerType>
......@@ -3209,7 +3202,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
TNode<Uint32T> descriptor_number);
typedef std::function<void(TNode<UintPtrT> descriptor_key_index)>
typedef std::function<void(TNode<IntPtrT> descriptor_key_index)>
ForEachDescriptorBodyFunction;
void DescriptorArrayForEach(VariableList& variable_list,
......@@ -3217,6 +3210,33 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Uint32T> end_descriptor,
const ForEachDescriptorBodyFunction& body);
// Descriptor array accessors based on key_index, which is equal to
// DescriptorArray::ToKeyIndex(descriptor).
TNode<Name> LoadKeyByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<Uint32T> LoadDetailsByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<Object> LoadValueByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<MaybeObject> LoadFieldTypeByKeyIndex(TNode<DescriptorArray> container,
TNode<IntPtrT> key_index);
TNode<IntPtrT> DescriptorEntryToIndex(TNode<IntPtrT> descriptor);
// Descriptor array accessors based on descriptor.
TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
TNode<IntPtrT> descriptor);
TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
int descriptor);
TNode<Uint32T> LoadDetailsByDescriptorEntry(
TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);
TNode<Uint32T> LoadDetailsByDescriptorEntry(
TNode<DescriptorArray> descriptors, int descriptor);
TNode<Object> LoadValueByDescriptorEntry(TNode<DescriptorArray> descriptors,
int descriptor);
TNode<MaybeObject> LoadFieldTypeByDescriptorEntry(
TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);
typedef std::function<void(TNode<Name> key, TNode<Object> value)>
ForEachKeyValueFunction;
......
......@@ -215,7 +215,8 @@ void AccessorAssembler::HandleLoadCallbackProperty(const LoadICParameters* p,
TNode<WordT> handler_word,
ExitPoint* exit_point) {
Comment("native_data_property_load");
Node* descriptor = DecodeWord<LoadHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word));
Label runtime(this, Label::kDeferred);
Callable callable = CodeFactory::ApiGetter(isolate());
......@@ -325,22 +326,15 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word,
}
}
TNode<Object> AccessorAssembler::LoadDescriptorValue(TNode<Map> map,
Node* descriptor) {
return CAST(LoadDescriptorValueOrFieldType(map, descriptor));
TNode<Object> AccessorAssembler::LoadDescriptorValue(
TNode<Map> map, TNode<IntPtrT> descriptor_entry) {
return CAST(LoadDescriptorValueOrFieldType(map, descriptor_entry));
}
TNode<MaybeObject> AccessorAssembler::LoadDescriptorValueOrFieldType(
TNode<Map> map, SloppyTNode<IntPtrT> descriptor) {
TNode<Map> map, TNode<IntPtrT> descriptor_entry) {
TNode<DescriptorArray> descriptors = LoadMapDescriptors(map);
TNode<IntPtrT> scaled_descriptor =
IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize));
TNode<IntPtrT> value_index = IntPtrAdd(
scaled_descriptor, IntPtrConstant(DescriptorArray::kFirstIndex +
DescriptorArray::kEntryValueIndex));
CSA_ASSERT(this, UintPtrLessThan(descriptor, LoadAndUntagWeakFixedArrayLength(
descriptors)));
return LoadWeakFixedArrayElement(descriptors, value_index);
return LoadFieldTypeByDescriptorEntry(descriptors, descriptor_entry);
}
void AccessorAssembler::HandleLoadICSmiHandlerCase(
......@@ -497,7 +491,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
BIND(&constant);
{
Comment("constant_load");
Node* descriptor = DecodeWord<LoadHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word));
Node* value = LoadDescriptorValue(LoadMap(holder), descriptor);
exit_point->Return(value);
......@@ -526,7 +521,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
BIND(&accessor);
{
Comment("accessor_load");
Node* descriptor = DecodeWord<LoadHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<LoadHandler::DescriptorBits>(handler_word));
Node* accessor_pair = LoadDescriptorValue(LoadMap(holder), descriptor);
CSA_ASSERT(this, IsAccessorPair(accessor_pair));
Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
......@@ -827,7 +823,8 @@ void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable,
void AccessorAssembler::HandleStoreICNativeDataProperty(
const StoreICParameters* p, Node* holder, Node* handler_word) {
Comment("native_data_property_store");
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word));
Node* accessor_info = LoadDescriptorValue(LoadMap(holder), descriptor);
CSA_CHECK(this, IsAccessorInfo(accessor_info));
......@@ -986,13 +983,11 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase(
TNode<IntPtrT> last_key_index = UncheckedCast<IntPtrT>(IntPtrAdd(
IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor)));
if (flags & kValidateTransitionHandler) {
Node* key = LoadWeakFixedArrayElement(descriptors, last_key_index);
TNode<Name> key = LoadKeyByKeyIndex(descriptors, last_key_index);
GotoIf(WordNotEqual(key, p->name), miss);
} else {
CSA_ASSERT(this,
WordEqual(BitcastMaybeObjectToWord(LoadWeakFixedArrayElement(
descriptors, last_key_index)),
p->name));
CSA_ASSERT(this, WordEqual(LoadKeyByKeyIndex(descriptors, last_key_index),
p->name));
}
Node* details = LoadDetailsByKeyIndex(descriptors, last_key_index);
if (flags & kValidateTransitionHandler) {
......@@ -1254,7 +1249,8 @@ void AccessorAssembler::CheckPrototypeValidityCell(Node* maybe_validity_cell,
void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p,
Node* holder, Node* handler_word) {
Comment("accessor_store");
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word));
Node* accessor_pair = LoadDescriptorValue(LoadMap(holder), descriptor);
CSA_ASSERT(this, IsAccessorPair(accessor_pair));
Node* setter = LoadObjectField(accessor_pair, AccessorPair::kSetterOffset);
......@@ -1585,7 +1581,8 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder,
IntPtrConstant(StoreHandler::kConstField)),
&done);
}
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
TNode<IntPtrT> descriptor =
Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word));
TNode<MaybeObject> maybe_field_type =
LoadDescriptorValueOrFieldType(LoadMap(holder), descriptor);
......
......@@ -148,9 +148,10 @@ class AccessorAssembler : public CodeStubAssembler {
TVariable<MaybeObject>* var_handler, Label* if_handler,
Label* miss, ExitPoint* exit_point);
TNode<Object> LoadDescriptorValue(TNode<Map> map, Node* descriptor);
TNode<Object> LoadDescriptorValue(TNode<Map> map,
TNode<IntPtrT> descriptor_entry);
TNode<MaybeObject> LoadDescriptorValueOrFieldType(
TNode<Map> map, SloppyTNode<IntPtrT> descriptor);
TNode<Map> map, TNode<IntPtrT> descriptor_entry);
void LoadIC_Uninitialized(const LoadICParameters* p);
......
......@@ -312,8 +312,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
// The length property is non-configurable, so it's guaranteed to always
// be the first property.
TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map);
TNode<Uint32T> details = LoadDetailsByKeyIndex(
descriptors, IntPtrConstant(DescriptorArray::ToKeyIndex(0)));
TNode<Uint32T> details = LoadDetailsByDescriptorEntry(descriptors, 0);
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
slow);
}
......
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