[csa] Typify and generalize CSA::DescriptorLookup() implementation.
This CL prepares ground for adding CSA implementation of TransitionArray lookup. Bug: v8:7310 Change-Id: Ie82e4db8f8a0cdb1dd7bbb759fd60ad55855fe72 Reviewed-on: https://chromium-review.googlesource.com/983920 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#52298}
This commit is contained in:
parent
93c920037b
commit
9a29c90277
@ -314,7 +314,7 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries(
|
|||||||
CSA_ASSERT(this, WordEqual(map, LoadMap(object)));
|
CSA_ASSERT(this, WordEqual(map, LoadMap(object)));
|
||||||
TNode<Uint32T> descriptor_index = TNode<Uint32T>::UncheckedCast(
|
TNode<Uint32T> descriptor_index = TNode<Uint32T>::UncheckedCast(
|
||||||
TruncateIntPtrToInt32(var_descriptor_number.value()));
|
TruncateIntPtrToInt32(var_descriptor_number.value()));
|
||||||
Node* next_key = DescriptorArrayGetKey(descriptors, descriptor_index);
|
Node* next_key = GetKey(descriptors, descriptor_index);
|
||||||
|
|
||||||
// Skip Symbols.
|
// Skip Symbols.
|
||||||
GotoIf(IsSymbol(next_key), &loop_condition);
|
GotoIf(IsSymbol(next_key), &loop_condition);
|
||||||
@ -332,8 +332,8 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries(
|
|||||||
|
|
||||||
VARIABLE(var_property_value, MachineRepresentation::kTagged,
|
VARIABLE(var_property_value, MachineRepresentation::kTagged,
|
||||||
UndefinedConstant());
|
UndefinedConstant());
|
||||||
Node* descriptor_name_index = DescriptorArrayToKeyIndex(
|
TNode<IntPtrT> descriptor_name_index = ToKeyIndex<DescriptorArray>(
|
||||||
TruncateIntPtrToInt32(var_descriptor_number.value()));
|
Unsigned(TruncateIntPtrToInt32(var_descriptor_number.value())));
|
||||||
|
|
||||||
// Let value be ? Get(O, key).
|
// Let value be ? Get(O, key).
|
||||||
LoadPropertyFromFastObject(object, map, descriptors,
|
LoadPropertyFromFastObject(object, map, descriptors,
|
||||||
|
@ -1405,9 +1405,11 @@ TNode<HeapObject> CodeStubAssembler::LoadFastProperties(
|
|||||||
TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
|
TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
|
||||||
SloppyTNode<JSObject> object) {
|
SloppyTNode<JSObject> object) {
|
||||||
CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object)));
|
CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object)));
|
||||||
Node* properties = LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
|
TNode<Object> properties =
|
||||||
return SelectTaggedConstant<HeapObject>(
|
LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
|
||||||
TaggedIsSmi(properties), EmptyPropertyDictionaryConstant(), properties);
|
return SelectTaggedConstant<HeapObject>(TaggedIsSmi(properties),
|
||||||
|
EmptyPropertyDictionaryConstant(),
|
||||||
|
CAST(properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
|
TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
|
||||||
@ -6720,109 +6722,130 @@ void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
|
|||||||
template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
|
template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
|
||||||
Label*);
|
Label*);
|
||||||
|
|
||||||
void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
|
template <typename Array>
|
||||||
Node* descriptors, Node* nof,
|
void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
|
||||||
Label* if_found,
|
TNode<Array> array,
|
||||||
Variable* var_name_index,
|
TNode<Uint32T> number_of_valid_entries,
|
||||||
Label* if_not_found) {
|
Label* if_found,
|
||||||
Comment("DescriptorLookupLinear");
|
TVariable<IntPtrT>* var_name_index,
|
||||||
Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0));
|
Label* if_not_found) {
|
||||||
Node* factor = IntPtrConstant(DescriptorArray::kEntrySize);
|
Comment("LookupLinear");
|
||||||
Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor));
|
TNode<IntPtrT> first_inclusive = IntPtrConstant(Array::ToKeyIndex(0));
|
||||||
|
TNode<IntPtrT> factor = IntPtrConstant(Array::kEntrySize);
|
||||||
|
TNode<IntPtrT> last_exclusive = IntPtrAdd(
|
||||||
|
first_inclusive,
|
||||||
|
IntPtrMul(ChangeInt32ToIntPtr(number_of_valid_entries), factor));
|
||||||
|
|
||||||
BuildFastLoop(last_exclusive, first_inclusive,
|
BuildFastLoop(last_exclusive, first_inclusive,
|
||||||
[this, descriptors, unique_name, if_found,
|
[=](SloppyTNode<IntPtrT> name_index) {
|
||||||
var_name_index](Node* name_index) {
|
TNode<Name> candidate_name =
|
||||||
Node* candidate_name =
|
CAST(LoadFixedArrayElement(array, name_index));
|
||||||
LoadFixedArrayElement(descriptors, name_index);
|
*var_name_index = name_index;
|
||||||
var_name_index->Bind(name_index);
|
|
||||||
GotoIf(WordEqual(candidate_name, unique_name), if_found);
|
GotoIf(WordEqual(candidate_name, unique_name), if_found);
|
||||||
},
|
},
|
||||||
-DescriptorArray::kEntrySize, INTPTR_PARAMETERS,
|
-Array::kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPre);
|
||||||
IndexAdvanceMode::kPre);
|
|
||||||
Goto(if_not_found);
|
Goto(if_not_found);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) {
|
template <>
|
||||||
return LoadAndUntagToWord32FixedArrayElement(
|
TNode<Uint32T> CodeStubAssembler::NumberOfEntries<DescriptorArray>(
|
||||||
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
|
TNode<DescriptorArray> descriptors) {
|
||||||
|
return Unsigned(LoadAndUntagToWord32FixedArrayElement(
|
||||||
|
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorNumberToIndex(
|
template <typename Array>
|
||||||
SloppyTNode<Uint32T> descriptor_number) {
|
TNode<IntPtrT> CodeStubAssembler::EntryIndexToIndex(
|
||||||
Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize);
|
TNode<Uint32T> entry_index) {
|
||||||
Node* index = Int32Mul(descriptor_number, descriptor_size);
|
TNode<Int32T> descriptor_size = Int32Constant(Array::kEntrySize);
|
||||||
|
TNode<Word32T> index = Int32Mul(entry_index, descriptor_size);
|
||||||
return ChangeInt32ToIntPtr(index);
|
return ChangeInt32ToIntPtr(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
|
template <typename Array>
|
||||||
return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
|
TNode<IntPtrT> CodeStubAssembler::ToKeyIndex(TNode<Uint32T> entry_index) {
|
||||||
DescriptorNumberToIndex(descriptor_number));
|
return IntPtrAdd(IntPtrConstant(Array::ToKeyIndex(0)),
|
||||||
|
EntryIndexToIndex<Array>(entry_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
|
template TNode<IntPtrT> CodeStubAssembler::ToKeyIndex<DescriptorArray>(
|
||||||
Node* descriptors, Node* descriptor_number) {
|
TNode<Uint32T>);
|
||||||
Node* details = DescriptorArrayGetDetails(
|
|
||||||
TNode<DescriptorArray>::UncheckedCast(descriptors),
|
template <>
|
||||||
TNode<Uint32T>::UncheckedCast(descriptor_number));
|
TNode<Uint32T> CodeStubAssembler::GetSortedKeyIndex<DescriptorArray>(
|
||||||
|
TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
|
||||||
|
TNode<Uint32T> details =
|
||||||
|
DescriptorArrayGetDetails(descriptors, descriptor_number);
|
||||||
return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
|
return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
|
template <>
|
||||||
Node* descriptor_number) {
|
TNode<Uint32T> CodeStubAssembler::GetSortedKeyIndex<TransitionArray>(
|
||||||
const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
|
TNode<TransitionArray> transitions, TNode<Uint32T> transition_number) {
|
||||||
return LoadFixedArrayElement(
|
return transition_number;
|
||||||
descriptors, DescriptorNumberToIndex(descriptor_number), key_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Array>
|
||||||
|
TNode<Name> CodeStubAssembler::GetKey(TNode<Array> array,
|
||||||
|
TNode<Uint32T> entry_index) {
|
||||||
|
const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
|
||||||
|
return CAST(LoadFixedArrayElement(
|
||||||
|
array, EntryIndexToIndex<Array>(entry_index), key_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
template TNode<Name> CodeStubAssembler::GetKey<DescriptorArray>(
|
||||||
|
TNode<DescriptorArray>, TNode<Uint32T>);
|
||||||
|
|
||||||
TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails(
|
TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails(
|
||||||
TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
|
TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
|
||||||
const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
|
const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
|
||||||
return TNode<Uint32T>::UncheckedCast(LoadAndUntagToWord32FixedArrayElement(
|
return Unsigned(LoadAndUntagToWord32FixedArrayElement(
|
||||||
descriptors, DescriptorNumberToIndex(descriptor_number), details_offset));
|
descriptors, EntryIndexToIndex<DescriptorArray>(descriptor_number),
|
||||||
|
details_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
|
template <typename Array>
|
||||||
Node* descriptors, Node* nof,
|
void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
|
||||||
Label* if_found,
|
TNode<Array> array,
|
||||||
Variable* var_name_index,
|
TNode<Uint32T> number_of_valid_entries,
|
||||||
Label* if_not_found) {
|
Label* if_found,
|
||||||
Comment("DescriptorLookupBinary");
|
TVariable<IntPtrT>* var_name_index,
|
||||||
VARIABLE(var_low, MachineRepresentation::kWord32, Int32Constant(0));
|
Label* if_not_found) {
|
||||||
Node* limit =
|
Comment("LookupBinary");
|
||||||
Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1));
|
TVARIABLE(Uint32T, var_low, Unsigned(Int32Constant(0)));
|
||||||
VARIABLE(var_high, MachineRepresentation::kWord32, limit);
|
TNode<Uint32T> limit =
|
||||||
Node* hash = LoadNameHashField(unique_name);
|
Unsigned(Int32Sub(NumberOfEntries<Array>(array), Int32Constant(1)));
|
||||||
|
TVARIABLE(Uint32T, var_high, limit);
|
||||||
|
TNode<Uint32T> hash = LoadNameHashField(unique_name);
|
||||||
CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
|
CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
|
||||||
|
|
||||||
// Assume non-empty array.
|
// Assume non-empty array.
|
||||||
CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value()));
|
CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value()));
|
||||||
|
|
||||||
Variable* loop_vars[] = {&var_high, &var_low};
|
Label binary_loop(this, {&var_high, &var_low});
|
||||||
Label binary_loop(this, 2, loop_vars);
|
|
||||||
Goto(&binary_loop);
|
Goto(&binary_loop);
|
||||||
BIND(&binary_loop);
|
BIND(&binary_loop);
|
||||||
{
|
{
|
||||||
// mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2").
|
// mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2").
|
||||||
Node* mid =
|
TNode<Uint32T> mid = Unsigned(
|
||||||
Int32Add(var_low.value(),
|
Int32Add(var_low.value(),
|
||||||
Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1));
|
Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1)));
|
||||||
// mid_name = descriptors->GetSortedKey(mid).
|
// mid_name = array->GetSortedKey(mid).
|
||||||
Node* sorted_key_index = DescriptorArrayGetSortedKeyIndex(descriptors, mid);
|
TNode<Uint32T> sorted_key_index = GetSortedKeyIndex<Array>(array, mid);
|
||||||
Node* mid_name = DescriptorArrayGetKey(descriptors, sorted_key_index);
|
TNode<Name> mid_name = GetKey<Array>(array, sorted_key_index);
|
||||||
|
|
||||||
Node* mid_hash = LoadNameHashField(mid_name);
|
TNode<Uint32T> mid_hash = LoadNameHashField(mid_name);
|
||||||
|
|
||||||
Label mid_greater(this), mid_less(this), merge(this);
|
Label mid_greater(this), mid_less(this), merge(this);
|
||||||
Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
|
Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
|
||||||
BIND(&mid_greater);
|
BIND(&mid_greater);
|
||||||
{
|
{
|
||||||
var_high.Bind(mid);
|
var_high = mid;
|
||||||
Goto(&merge);
|
Goto(&merge);
|
||||||
}
|
}
|
||||||
BIND(&mid_less);
|
BIND(&mid_less);
|
||||||
{
|
{
|
||||||
var_low.Bind(Int32Add(mid, Int32Constant(1)));
|
var_low = Unsigned(Int32Add(mid, Int32Constant(1)));
|
||||||
Goto(&merge);
|
Goto(&merge);
|
||||||
}
|
}
|
||||||
BIND(&merge);
|
BIND(&merge);
|
||||||
@ -6835,54 +6858,67 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
|
|||||||
{
|
{
|
||||||
GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found);
|
GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found);
|
||||||
|
|
||||||
Node* sort_index =
|
TNode<Uint32T> sort_index =
|
||||||
DescriptorArrayGetSortedKeyIndex(descriptors, var_low.value());
|
GetSortedKeyIndex<Array>(array, var_low.value());
|
||||||
Node* current_name = DescriptorArrayGetKey(descriptors, sort_index);
|
TNode<Name> current_name = GetKey<Array>(array, sort_index);
|
||||||
Node* current_hash = LoadNameHashField(current_name);
|
TNode<Uint32T> current_hash = LoadNameHashField(current_name);
|
||||||
GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
|
GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
|
||||||
Label next(this);
|
Label next(this);
|
||||||
GotoIf(WordNotEqual(current_name, unique_name), &next);
|
GotoIf(WordNotEqual(current_name, unique_name), &next);
|
||||||
GotoIf(Int32GreaterThanOrEqual(sort_index, nof), if_not_found);
|
GotoIf(Uint32GreaterThanOrEqual(sort_index, number_of_valid_entries),
|
||||||
var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index));
|
if_not_found);
|
||||||
|
*var_name_index = ToKeyIndex<Array>(sort_index);
|
||||||
Goto(if_found);
|
Goto(if_found);
|
||||||
|
|
||||||
BIND(&next);
|
BIND(&next);
|
||||||
var_low.Bind(Int32Add(var_low.value(), Int32Constant(1)));
|
var_low = Unsigned(Int32Add(var_low.value(), Int32Constant(1)));
|
||||||
Goto(&scan_loop);
|
Goto(&scan_loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors,
|
void CodeStubAssembler::DescriptorLookup(
|
||||||
Node* bitfield3, Label* if_found,
|
SloppyTNode<Name> unique_name, SloppyTNode<DescriptorArray> descriptors,
|
||||||
Variable* var_name_index,
|
SloppyTNode<Uint32T> bitfield3, Label* if_found,
|
||||||
Label* if_not_found) {
|
TVariable<IntPtrT>* var_name_index, Label* if_not_found) {
|
||||||
Comment("DescriptorArrayLookup");
|
Comment("DescriptorArrayLookup");
|
||||||
Node* nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
|
TNode<Uint32T> nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
|
||||||
GotoIf(Word32Equal(nof, Int32Constant(0)), if_not_found);
|
Lookup<DescriptorArray>(unique_name, descriptors, nof, if_found,
|
||||||
|
var_name_index, if_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Array>
|
||||||
|
void CodeStubAssembler::Lookup(TNode<Name> unique_name, TNode<Array> array,
|
||||||
|
TNode<Uint32T> number_of_valid_entries,
|
||||||
|
Label* if_found,
|
||||||
|
TVariable<IntPtrT>* var_name_index,
|
||||||
|
Label* if_not_found) {
|
||||||
|
Comment("ArrayLookup");
|
||||||
|
if (!number_of_valid_entries) {
|
||||||
|
number_of_valid_entries = NumberOfEntries(array);
|
||||||
|
}
|
||||||
|
GotoIf(Word32Equal(number_of_valid_entries, Int32Constant(0)), if_not_found);
|
||||||
Label linear_search(this), binary_search(this);
|
Label linear_search(this), binary_search(this);
|
||||||
const int kMaxElementsForLinearSearch = 32;
|
const int kMaxElementsForLinearSearch = 32;
|
||||||
Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)),
|
Branch(Uint32LessThanOrEqual(number_of_valid_entries,
|
||||||
|
Int32Constant(kMaxElementsForLinearSearch)),
|
||||||
&linear_search, &binary_search);
|
&linear_search, &binary_search);
|
||||||
BIND(&linear_search);
|
BIND(&linear_search);
|
||||||
{
|
{
|
||||||
DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof),
|
LookupLinear<Array>(unique_name, array, number_of_valid_entries, if_found,
|
||||||
if_found, var_name_index, if_not_found);
|
var_name_index, if_not_found);
|
||||||
}
|
}
|
||||||
BIND(&binary_search);
|
BIND(&binary_search);
|
||||||
{
|
{
|
||||||
DescriptorLookupBinary(unique_name, descriptors, nof, if_found,
|
LookupBinary<Array>(unique_name, array, number_of_valid_entries, if_found,
|
||||||
var_name_index, if_not_found);
|
var_name_index, if_not_found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::TryLookupProperty(
|
void CodeStubAssembler::TryLookupProperty(
|
||||||
Node* object, Node* map, Node* instance_type, Node* unique_name,
|
Node* object, Node* map, Node* instance_type, Node* unique_name,
|
||||||
Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
|
Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
|
||||||
Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found,
|
TVariable<HeapObject>* var_meta_storage, TVariable<IntPtrT>* var_name_index,
|
||||||
Label* if_bailout) {
|
Label* if_not_found, Label* if_bailout) {
|
||||||
DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep());
|
|
||||||
DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep());
|
|
||||||
|
|
||||||
Label if_objectisspecial(this);
|
Label if_objectisspecial(this);
|
||||||
GotoIf(IsSpecialReceiverInstanceType(instance_type), &if_objectisspecial);
|
GotoIf(IsSpecialReceiverInstanceType(instance_type), &if_objectisspecial);
|
||||||
|
|
||||||
@ -6897,16 +6933,16 @@ void CodeStubAssembler::TryLookupProperty(
|
|||||||
&if_isfastmap);
|
&if_isfastmap);
|
||||||
BIND(&if_isfastmap);
|
BIND(&if_isfastmap);
|
||||||
{
|
{
|
||||||
Node* descriptors = LoadMapDescriptors(map);
|
TNode<DescriptorArray> descriptors = LoadMapDescriptors(map);
|
||||||
var_meta_storage->Bind(descriptors);
|
*var_meta_storage = descriptors;
|
||||||
|
|
||||||
DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast,
|
DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast,
|
||||||
var_name_index, if_not_found);
|
var_name_index, if_not_found);
|
||||||
}
|
}
|
||||||
BIND(&if_isslowmap);
|
BIND(&if_isslowmap);
|
||||||
{
|
{
|
||||||
Node* dictionary = LoadSlowProperties(object);
|
TNode<NameDictionary> dictionary = CAST(LoadSlowProperties(object));
|
||||||
var_meta_storage->Bind(dictionary);
|
*var_meta_storage = dictionary;
|
||||||
|
|
||||||
NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
|
NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
|
||||||
var_name_index, if_not_found);
|
var_name_index, if_not_found);
|
||||||
@ -6923,8 +6959,8 @@ void CodeStubAssembler::TryLookupProperty(
|
|||||||
Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
|
Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask;
|
||||||
GotoIf(IsSetWord32(bit_field, mask), if_bailout);
|
GotoIf(IsSetWord32(bit_field, mask), if_bailout);
|
||||||
|
|
||||||
Node* dictionary = LoadSlowProperties(object);
|
TNode<GlobalDictionary> dictionary = CAST(LoadSlowProperties(object));
|
||||||
var_meta_storage->Bind(dictionary);
|
*var_meta_storage = dictionary;
|
||||||
|
|
||||||
NameDictionaryLookup<GlobalDictionary>(
|
NameDictionaryLookup<GlobalDictionary>(
|
||||||
dictionary, unique_name, if_found_global, var_name_index, if_not_found);
|
dictionary, unique_name, if_found_global, var_name_index, if_not_found);
|
||||||
@ -6937,8 +6973,8 @@ void CodeStubAssembler::TryHasOwnProperty(Node* object, Node* map,
|
|||||||
Label* if_not_found,
|
Label* if_not_found,
|
||||||
Label* if_bailout) {
|
Label* if_bailout) {
|
||||||
Comment("TryHasOwnProperty");
|
Comment("TryHasOwnProperty");
|
||||||
VARIABLE(var_meta_storage, MachineRepresentation::kTagged);
|
TVARIABLE(HeapObject, var_meta_storage);
|
||||||
VARIABLE(var_name_index, MachineType::PointerRepresentation());
|
TVARIABLE(IntPtrT, var_name_index);
|
||||||
|
|
||||||
Label if_found_global(this);
|
Label if_found_global(this);
|
||||||
TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
|
TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
|
||||||
@ -7240,8 +7276,8 @@ void CodeStubAssembler::TryGetOwnProperty(
|
|||||||
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
|
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
|
||||||
Comment("TryGetOwnProperty");
|
Comment("TryGetOwnProperty");
|
||||||
|
|
||||||
VARIABLE(var_meta_storage, MachineRepresentation::kTagged);
|
TVARIABLE(HeapObject, var_meta_storage);
|
||||||
VARIABLE(var_entry, MachineType::PointerRepresentation());
|
TVARIABLE(IntPtrT, var_entry);
|
||||||
|
|
||||||
Label if_found_fast(this), if_found_dict(this), if_found_global(this);
|
Label if_found_fast(this), if_found_dict(this), if_found_global(this);
|
||||||
|
|
||||||
@ -7249,8 +7285,7 @@ void CodeStubAssembler::TryGetOwnProperty(
|
|||||||
if (!var_details) {
|
if (!var_details) {
|
||||||
var_details = &local_var_details;
|
var_details = &local_var_details;
|
||||||
}
|
}
|
||||||
Variable* vars[] = {var_value, var_details};
|
Label if_found(this, {var_value, var_details});
|
||||||
Label if_found(this, 2, vars);
|
|
||||||
|
|
||||||
TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
|
TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
|
||||||
&if_found_dict, &if_found_global, &var_meta_storage,
|
&if_found_dict, &if_found_global, &var_meta_storage,
|
||||||
|
@ -1706,7 +1706,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
void TryLookupProperty(Node* object, Node* map, Node* instance_type,
|
void TryLookupProperty(Node* object, Node* map, Node* instance_type,
|
||||||
Node* unique_name, Label* if_found_fast,
|
Node* unique_name, Label* if_found_fast,
|
||||||
Label* if_found_dict, Label* if_found_global,
|
Label* if_found_dict, Label* if_found_global,
|
||||||
Variable* var_meta_storage, Variable* var_name_index,
|
TVariable<HeapObject>* var_meta_storage,
|
||||||
|
TVariable<IntPtrT>* var_name_index,
|
||||||
Label* if_not_found, Label* if_bailout);
|
Label* if_not_found, Label* if_bailout);
|
||||||
|
|
||||||
// This method jumps to if_found if the element is known to exist. To
|
// This method jumps to if_found if the element is known to exist. To
|
||||||
@ -2010,22 +2011,44 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
void PerformStackCheck(Node* context);
|
void PerformStackCheck(Node* context);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DescriptorLookup(Node* unique_name, Node* descriptors, Node* bitfield3,
|
// Implements DescriptorArray::Search().
|
||||||
Label* if_found, Variable* var_name_index,
|
void DescriptorLookup(SloppyTNode<Name> unique_name,
|
||||||
|
SloppyTNode<DescriptorArray> descriptors,
|
||||||
|
SloppyTNode<Uint32T> bitfield3, Label* if_found,
|
||||||
|
TVariable<IntPtrT>* var_name_index,
|
||||||
Label* if_not_found);
|
Label* if_not_found);
|
||||||
void DescriptorLookupLinear(Node* unique_name, Node* descriptors, Node* nof,
|
|
||||||
Label* if_found, Variable* var_name_index,
|
// Implements generic search procedure like i::Search<Array>().
|
||||||
Label* if_not_found);
|
template <typename Array>
|
||||||
void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof,
|
void Lookup(TNode<Name> unique_name, TNode<Array> array,
|
||||||
Label* if_found, Variable* var_name_index,
|
TNode<Uint32T> number_of_valid_entries, Label* if_found,
|
||||||
Label* if_not_found);
|
TVariable<IntPtrT>* var_name_index, Label* if_not_found);
|
||||||
Node* DescriptorNumberToIndex(SloppyTNode<Uint32T> descriptor_number);
|
|
||||||
// Implements DescriptorArray::ToKeyIndex.
|
// Implements generic linear search procedure like i::LinearSearch<Array>().
|
||||||
// Returns an untagged IntPtr.
|
template <typename Array>
|
||||||
Node* DescriptorArrayToKeyIndex(Node* descriptor_number);
|
void LookupLinear(TNode<Name> unique_name, TNode<Array> array,
|
||||||
// Implements DescriptorArray::GetKey.
|
TNode<Uint32T> number_of_valid_entries, Label* if_found,
|
||||||
Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number);
|
TVariable<IntPtrT>* var_name_index, Label* if_not_found);
|
||||||
// Implements DescriptorArray::GetKey.
|
|
||||||
|
// Implements generic binary search procedure like i::BinarySearch<Array>().
|
||||||
|
template <typename Array>
|
||||||
|
void LookupBinary(TNode<Name> unique_name, TNode<Array> array,
|
||||||
|
TNode<Uint32T> number_of_valid_entries, Label* if_found,
|
||||||
|
TVariable<IntPtrT>* var_name_index, Label* if_not_found);
|
||||||
|
|
||||||
|
// Converts [Descriptor/Transition]Array entry number to a fixed array index.
|
||||||
|
template <typename Array>
|
||||||
|
TNode<IntPtrT> EntryIndexToIndex(TNode<Uint32T> entry_index);
|
||||||
|
|
||||||
|
// Implements [Descriptor/Transition]Array::ToKeyIndex.
|
||||||
|
template <typename Array>
|
||||||
|
TNode<IntPtrT> ToKeyIndex(TNode<Uint32T> entry_index);
|
||||||
|
|
||||||
|
// Implements [Descriptor/Transition]Array::GetKey.
|
||||||
|
template <typename Array>
|
||||||
|
TNode<Name> GetKey(TNode<Array> array, TNode<Uint32T> entry_index);
|
||||||
|
|
||||||
|
// Implements DescriptorArray::GetDetails.
|
||||||
TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
|
TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
|
||||||
TNode<Uint32T> descriptor_number);
|
TNode<Uint32T> descriptor_number);
|
||||||
|
|
||||||
@ -2079,13 +2102,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
Node* SelectImpl(TNode<BoolT> condition, const NodeGenerator& true_body,
|
Node* SelectImpl(TNode<BoolT> condition, const NodeGenerator& true_body,
|
||||||
const NodeGenerator& false_body, MachineRepresentation rep);
|
const NodeGenerator& false_body, MachineRepresentation rep);
|
||||||
|
|
||||||
// Implements DescriptorArray::number_of_entries.
|
// Implements [Descriptor/Transition]Array::number_of_entries.
|
||||||
// Returns an untagged int32.
|
template <typename Array>
|
||||||
Node* DescriptorArrayNumberOfEntries(Node* descriptors);
|
TNode<Uint32T> NumberOfEntries(TNode<Array> array);
|
||||||
// Implements DescriptorArray::GetSortedKeyIndex.
|
|
||||||
// Returns an untagged int32.
|
// Implements [Descriptor/Transition]Array::GetSortedKeyIndex.
|
||||||
Node* DescriptorArrayGetSortedKeyIndex(Node* descriptors,
|
template <typename Array>
|
||||||
Node* descriptor_number);
|
TNode<Uint32T> GetSortedKeyIndex(TNode<Array> descriptors,
|
||||||
|
TNode<Uint32T> entry_index);
|
||||||
|
|
||||||
Node* CollectFeedbackForString(Node* instance_type);
|
Node* CollectFeedbackForString(Node* instance_type);
|
||||||
void GenerateEqual_Same(Node* value, Label* if_equal, Label* if_notequal,
|
void GenerateEqual_Same(Node* value, Label* if_equal, Label* if_notequal,
|
||||||
|
@ -2060,7 +2060,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
|
|||||||
Node* descriptors = LoadMapDescriptors(receiver_map);
|
Node* descriptors = LoadMapDescriptors(receiver_map);
|
||||||
|
|
||||||
Label if_descriptor_found(this), stub_cache(this);
|
Label if_descriptor_found(this), stub_cache(this);
|
||||||
VARIABLE(var_name_index, MachineType::PointerRepresentation());
|
TVARIABLE(IntPtrT, var_name_index);
|
||||||
Label* notfound =
|
Label* notfound =
|
||||||
use_stub_cache == kUseStubCache ? &stub_cache : &lookup_prototype_chain;
|
use_stub_cache == kUseStubCache ? &stub_cache : &lookup_prototype_chain;
|
||||||
DescriptorLookup(p->name, descriptors, bitfield3, &if_descriptor_found,
|
DescriptorLookup(p->name, descriptors, bitfield3, &if_descriptor_found,
|
||||||
|
@ -541,8 +541,8 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain(
|
|||||||
Label next_proto(this);
|
Label next_proto(this);
|
||||||
{
|
{
|
||||||
Label found(this), found_fast(this), found_dict(this), found_global(this);
|
Label found(this), found_fast(this), found_dict(this), found_global(this);
|
||||||
VARIABLE(var_meta_storage, MachineRepresentation::kTagged);
|
TVARIABLE(HeapObject, var_meta_storage);
|
||||||
VARIABLE(var_entry, MachineType::PointerRepresentation());
|
TVARIABLE(IntPtrT, var_entry);
|
||||||
TryLookupProperty(holder, holder_map, instance_type, name, &found_fast,
|
TryLookupProperty(holder, holder_map, instance_type, name, &found_fast,
|
||||||
&found_dict, &found_global, &var_meta_storage,
|
&found_dict, &found_global, &var_meta_storage,
|
||||||
&var_entry, &next_proto, bailout);
|
&var_entry, &next_proto, bailout);
|
||||||
@ -626,7 +626,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
|||||||
Comment("fast property store");
|
Comment("fast property store");
|
||||||
Node* descriptors = LoadMapDescriptors(receiver_map);
|
Node* descriptors = LoadMapDescriptors(receiver_map);
|
||||||
Label descriptor_found(this), lookup_transition(this);
|
Label descriptor_found(this), lookup_transition(this);
|
||||||
VARIABLE(var_name_index, MachineType::PointerRepresentation());
|
TVARIABLE(IntPtrT, var_name_index);
|
||||||
Label* notfound = use_stub_cache == kUseStubCache ? &stub_cache : slow;
|
Label* notfound = use_stub_cache == kUseStubCache ? &stub_cache : slow;
|
||||||
DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found,
|
DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found,
|
||||||
&var_name_index, &lookup_transition);
|
&var_name_index, &lookup_transition);
|
||||||
|
Loading…
Reference in New Issue
Block a user