diff --git a/src/builtins/builtins-object-gen.cc b/src/builtins/builtins-object-gen.cc index 1fea03b8bd..18875945f1 100644 --- a/src/builtins/builtins-object-gen.cc +++ b/src/builtins/builtins-object-gen.cc @@ -314,7 +314,7 @@ TNode ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( CSA_ASSERT(this, WordEqual(map, LoadMap(object))); TNode descriptor_index = TNode::UncheckedCast( TruncateIntPtrToInt32(var_descriptor_number.value())); - Node* next_key = DescriptorArrayGetKey(descriptors, descriptor_index); + Node* next_key = GetKey(descriptors, descriptor_index); // Skip Symbols. GotoIf(IsSymbol(next_key), &loop_condition); @@ -332,8 +332,8 @@ TNode ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( VARIABLE(var_property_value, MachineRepresentation::kTagged, UndefinedConstant()); - Node* descriptor_name_index = DescriptorArrayToKeyIndex( - TruncateIntPtrToInt32(var_descriptor_number.value())); + TNode descriptor_name_index = ToKeyIndex( + Unsigned(TruncateIntPtrToInt32(var_descriptor_number.value()))); // Let value be ? Get(O, key). LoadPropertyFromFastObject(object, map, descriptors, diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index bbba141c83..8e709e9f5f 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -1405,9 +1405,11 @@ TNode CodeStubAssembler::LoadFastProperties( TNode CodeStubAssembler::LoadSlowProperties( SloppyTNode object) { CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object))); - Node* properties = LoadObjectField(object, JSObject::kPropertiesOrHashOffset); - return SelectTaggedConstant( - TaggedIsSmi(properties), EmptyPropertyDictionaryConstant(), properties); + TNode properties = + LoadObjectField(object, JSObject::kPropertiesOrHashOffset); + return SelectTaggedConstant(TaggedIsSmi(properties), + EmptyPropertyDictionaryConstant(), + CAST(properties)); } TNode CodeStubAssembler::LoadElements( @@ -6720,109 +6722,130 @@ void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, template void CodeStubAssembler::Add(Node*, Node*, Node*, Label*); -void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, - Node* descriptors, Node* nof, - Label* if_found, - Variable* var_name_index, - Label* if_not_found) { - Comment("DescriptorLookupLinear"); - Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); - Node* factor = IntPtrConstant(DescriptorArray::kEntrySize); - Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); +template +void CodeStubAssembler::LookupLinear(TNode unique_name, + TNode array, + TNode number_of_valid_entries, + Label* if_found, + TVariable* var_name_index, + Label* if_not_found) { + Comment("LookupLinear"); + TNode first_inclusive = IntPtrConstant(Array::ToKeyIndex(0)); + TNode factor = IntPtrConstant(Array::kEntrySize); + TNode last_exclusive = IntPtrAdd( + first_inclusive, + IntPtrMul(ChangeInt32ToIntPtr(number_of_valid_entries), factor)); BuildFastLoop(last_exclusive, first_inclusive, - [this, descriptors, unique_name, if_found, - var_name_index](Node* name_index) { - Node* candidate_name = - LoadFixedArrayElement(descriptors, name_index); - var_name_index->Bind(name_index); + [=](SloppyTNode name_index) { + TNode candidate_name = + CAST(LoadFixedArrayElement(array, name_index)); + *var_name_index = name_index; GotoIf(WordEqual(candidate_name, unique_name), if_found); }, - -DescriptorArray::kEntrySize, INTPTR_PARAMETERS, - IndexAdvanceMode::kPre); + -Array::kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPre); Goto(if_not_found); } -Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) { - return LoadAndUntagToWord32FixedArrayElement( - descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)); +template <> +TNode CodeStubAssembler::NumberOfEntries( + TNode descriptors) { + return Unsigned(LoadAndUntagToWord32FixedArrayElement( + descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex))); } -Node* CodeStubAssembler::DescriptorNumberToIndex( - SloppyTNode descriptor_number) { - Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize); - Node* index = Int32Mul(descriptor_number, descriptor_size); +template +TNode CodeStubAssembler::EntryIndexToIndex( + TNode entry_index) { + TNode descriptor_size = Int32Constant(Array::kEntrySize); + TNode index = Int32Mul(entry_index, descriptor_size); return ChangeInt32ToIntPtr(index); } -Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) { - return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)), - DescriptorNumberToIndex(descriptor_number)); +template +TNode CodeStubAssembler::ToKeyIndex(TNode entry_index) { + return IntPtrAdd(IntPtrConstant(Array::ToKeyIndex(0)), + EntryIndexToIndex(entry_index)); } -Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex( - Node* descriptors, Node* descriptor_number) { - Node* details = DescriptorArrayGetDetails( - TNode::UncheckedCast(descriptors), - TNode::UncheckedCast(descriptor_number)); +template TNode CodeStubAssembler::ToKeyIndex( + TNode); + +template <> +TNode CodeStubAssembler::GetSortedKeyIndex( + TNode descriptors, TNode descriptor_number) { + TNode details = + DescriptorArrayGetDetails(descriptors, descriptor_number); return DecodeWord32(details); } -Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors, - Node* descriptor_number) { - const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize; - return LoadFixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), key_offset); +template <> +TNode CodeStubAssembler::GetSortedKeyIndex( + TNode transitions, TNode transition_number) { + return transition_number; } +template +TNode CodeStubAssembler::GetKey(TNode array, + TNode entry_index) { + const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize; + return CAST(LoadFixedArrayElement( + array, EntryIndexToIndex(entry_index), key_offset)); +} + +template TNode CodeStubAssembler::GetKey( + TNode, TNode); + TNode CodeStubAssembler::DescriptorArrayGetDetails( TNode descriptors, TNode descriptor_number) { const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; - return TNode::UncheckedCast(LoadAndUntagToWord32FixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), details_offset)); + return Unsigned(LoadAndUntagToWord32FixedArrayElement( + descriptors, EntryIndexToIndex(descriptor_number), + details_offset)); } -void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name, - Node* descriptors, Node* nof, - Label* if_found, - Variable* var_name_index, - Label* if_not_found) { - Comment("DescriptorLookupBinary"); - VARIABLE(var_low, MachineRepresentation::kWord32, Int32Constant(0)); - Node* limit = - Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1)); - VARIABLE(var_high, MachineRepresentation::kWord32, limit); - Node* hash = LoadNameHashField(unique_name); +template +void CodeStubAssembler::LookupBinary(TNode unique_name, + TNode array, + TNode number_of_valid_entries, + Label* if_found, + TVariable* var_name_index, + Label* if_not_found) { + Comment("LookupBinary"); + TVARIABLE(Uint32T, var_low, Unsigned(Int32Constant(0))); + TNode limit = + Unsigned(Int32Sub(NumberOfEntries(array), Int32Constant(1))); + TVARIABLE(Uint32T, var_high, limit); + TNode hash = LoadNameHashField(unique_name); CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0))); // Assume non-empty array. CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value())); - Variable* loop_vars[] = {&var_high, &var_low}; - Label binary_loop(this, 2, loop_vars); + Label binary_loop(this, {&var_high, &var_low}); Goto(&binary_loop); BIND(&binary_loop); { // mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2"). - Node* mid = + TNode mid = Unsigned( Int32Add(var_low.value(), - Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1)); - // mid_name = descriptors->GetSortedKey(mid). - Node* sorted_key_index = DescriptorArrayGetSortedKeyIndex(descriptors, mid); - Node* mid_name = DescriptorArrayGetKey(descriptors, sorted_key_index); + Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1))); + // mid_name = array->GetSortedKey(mid). + TNode sorted_key_index = GetSortedKeyIndex(array, mid); + TNode mid_name = GetKey(array, sorted_key_index); - Node* mid_hash = LoadNameHashField(mid_name); + TNode mid_hash = LoadNameHashField(mid_name); Label mid_greater(this), mid_less(this), merge(this); Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less); BIND(&mid_greater); { - var_high.Bind(mid); + var_high = mid; Goto(&merge); } BIND(&mid_less); { - var_low.Bind(Int32Add(mid, Int32Constant(1))); + var_low = Unsigned(Int32Add(mid, Int32Constant(1))); Goto(&merge); } BIND(&merge); @@ -6835,54 +6858,67 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name, { GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found); - Node* sort_index = - DescriptorArrayGetSortedKeyIndex(descriptors, var_low.value()); - Node* current_name = DescriptorArrayGetKey(descriptors, sort_index); - Node* current_hash = LoadNameHashField(current_name); + TNode sort_index = + GetSortedKeyIndex(array, var_low.value()); + TNode current_name = GetKey(array, sort_index); + TNode current_hash = LoadNameHashField(current_name); GotoIf(Word32NotEqual(current_hash, hash), if_not_found); Label next(this); GotoIf(WordNotEqual(current_name, unique_name), &next); - GotoIf(Int32GreaterThanOrEqual(sort_index, nof), if_not_found); - var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index)); + GotoIf(Uint32GreaterThanOrEqual(sort_index, number_of_valid_entries), + if_not_found); + *var_name_index = ToKeyIndex(sort_index); Goto(if_found); BIND(&next); - var_low.Bind(Int32Add(var_low.value(), Int32Constant(1))); + var_low = Unsigned(Int32Add(var_low.value(), Int32Constant(1))); Goto(&scan_loop); } } -void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors, - Node* bitfield3, Label* if_found, - Variable* var_name_index, - Label* if_not_found) { +void CodeStubAssembler::DescriptorLookup( + SloppyTNode unique_name, SloppyTNode descriptors, + SloppyTNode bitfield3, Label* if_found, + TVariable* var_name_index, Label* if_not_found) { Comment("DescriptorArrayLookup"); - Node* nof = DecodeWord32(bitfield3); - GotoIf(Word32Equal(nof, Int32Constant(0)), if_not_found); + TNode nof = DecodeWord32(bitfield3); + Lookup(unique_name, descriptors, nof, if_found, + var_name_index, if_not_found); +} + +template +void CodeStubAssembler::Lookup(TNode unique_name, TNode array, + TNode number_of_valid_entries, + Label* if_found, + TVariable* 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); const int kMaxElementsForLinearSearch = 32; - Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)), + Branch(Uint32LessThanOrEqual(number_of_valid_entries, + Int32Constant(kMaxElementsForLinearSearch)), &linear_search, &binary_search); BIND(&linear_search); { - DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof), - if_found, var_name_index, if_not_found); + LookupLinear(unique_name, array, number_of_valid_entries, if_found, + var_name_index, if_not_found); } BIND(&binary_search); { - DescriptorLookupBinary(unique_name, descriptors, nof, if_found, - var_name_index, if_not_found); + LookupBinary(unique_name, array, number_of_valid_entries, if_found, + var_name_index, if_not_found); } } void CodeStubAssembler::TryLookupProperty( Node* object, Node* map, Node* instance_type, Node* unique_name, Label* if_found_fast, Label* if_found_dict, Label* if_found_global, - Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, - Label* if_bailout) { - DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); - DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); - + TVariable* var_meta_storage, TVariable* var_name_index, + Label* if_not_found, Label* if_bailout) { Label if_objectisspecial(this); GotoIf(IsSpecialReceiverInstanceType(instance_type), &if_objectisspecial); @@ -6897,16 +6933,16 @@ void CodeStubAssembler::TryLookupProperty( &if_isfastmap); BIND(&if_isfastmap); { - Node* descriptors = LoadMapDescriptors(map); - var_meta_storage->Bind(descriptors); + TNode descriptors = LoadMapDescriptors(map); + *var_meta_storage = descriptors; DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast, var_name_index, if_not_found); } BIND(&if_isslowmap); { - Node* dictionary = LoadSlowProperties(object); - var_meta_storage->Bind(dictionary); + TNode dictionary = CAST(LoadSlowProperties(object)); + *var_meta_storage = dictionary; NameDictionaryLookup(dictionary, unique_name, if_found_dict, var_name_index, if_not_found); @@ -6923,8 +6959,8 @@ void CodeStubAssembler::TryLookupProperty( Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask; GotoIf(IsSetWord32(bit_field, mask), if_bailout); - Node* dictionary = LoadSlowProperties(object); - var_meta_storage->Bind(dictionary); + TNode dictionary = CAST(LoadSlowProperties(object)); + *var_meta_storage = dictionary; NameDictionaryLookup( 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_bailout) { Comment("TryHasOwnProperty"); - VARIABLE(var_meta_storage, MachineRepresentation::kTagged); - VARIABLE(var_name_index, MachineType::PointerRepresentation()); + TVARIABLE(HeapObject, var_meta_storage); + TVARIABLE(IntPtrT, var_name_index); Label if_found_global(this); 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()); Comment("TryGetOwnProperty"); - VARIABLE(var_meta_storage, MachineRepresentation::kTagged); - VARIABLE(var_entry, MachineType::PointerRepresentation()); + TVARIABLE(HeapObject, var_meta_storage); + TVARIABLE(IntPtrT, var_entry); Label if_found_fast(this), if_found_dict(this), if_found_global(this); @@ -7249,8 +7285,7 @@ void CodeStubAssembler::TryGetOwnProperty( if (!var_details) { var_details = &local_var_details; } - Variable* vars[] = {var_value, var_details}; - Label if_found(this, 2, vars); + Label if_found(this, {var_value, var_details}); TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast, &if_found_dict, &if_found_global, &var_meta_storage, diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h index c3b63bb36c..b0a60f4a76 100644 --- a/src/code-stub-assembler.h +++ b/src/code-stub-assembler.h @@ -1706,7 +1706,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { void TryLookupProperty(Node* object, Node* map, Node* instance_type, Node* unique_name, Label* if_found_fast, Label* if_found_dict, Label* if_found_global, - Variable* var_meta_storage, Variable* var_name_index, + TVariable* var_meta_storage, + TVariable* var_name_index, Label* if_not_found, Label* if_bailout); // 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); protected: - void DescriptorLookup(Node* unique_name, Node* descriptors, Node* bitfield3, - Label* if_found, Variable* var_name_index, + // Implements DescriptorArray::Search(). + void DescriptorLookup(SloppyTNode unique_name, + SloppyTNode descriptors, + SloppyTNode bitfield3, Label* if_found, + TVariable* var_name_index, Label* if_not_found); - void DescriptorLookupLinear(Node* unique_name, Node* descriptors, Node* nof, - Label* if_found, Variable* var_name_index, - Label* if_not_found); - void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof, - Label* if_found, Variable* var_name_index, - Label* if_not_found); - Node* DescriptorNumberToIndex(SloppyTNode descriptor_number); - // Implements DescriptorArray::ToKeyIndex. - // Returns an untagged IntPtr. - Node* DescriptorArrayToKeyIndex(Node* descriptor_number); - // Implements DescriptorArray::GetKey. - Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number); - // Implements DescriptorArray::GetKey. + + // Implements generic search procedure like i::Search(). + template + void Lookup(TNode unique_name, TNode array, + TNode number_of_valid_entries, Label* if_found, + TVariable* var_name_index, Label* if_not_found); + + // Implements generic linear search procedure like i::LinearSearch(). + template + void LookupLinear(TNode unique_name, TNode array, + TNode number_of_valid_entries, Label* if_found, + TVariable* var_name_index, Label* if_not_found); + + // Implements generic binary search procedure like i::BinarySearch(). + template + void LookupBinary(TNode unique_name, TNode array, + TNode number_of_valid_entries, Label* if_found, + TVariable* var_name_index, Label* if_not_found); + + // Converts [Descriptor/Transition]Array entry number to a fixed array index. + template + TNode EntryIndexToIndex(TNode entry_index); + + // Implements [Descriptor/Transition]Array::ToKeyIndex. + template + TNode ToKeyIndex(TNode entry_index); + + // Implements [Descriptor/Transition]Array::GetKey. + template + TNode GetKey(TNode array, TNode entry_index); + + // Implements DescriptorArray::GetDetails. TNode DescriptorArrayGetDetails(TNode descriptors, TNode descriptor_number); @@ -2079,13 +2102,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* SelectImpl(TNode condition, const NodeGenerator& true_body, const NodeGenerator& false_body, MachineRepresentation rep); - // Implements DescriptorArray::number_of_entries. - // Returns an untagged int32. - Node* DescriptorArrayNumberOfEntries(Node* descriptors); - // Implements DescriptorArray::GetSortedKeyIndex. - // Returns an untagged int32. - Node* DescriptorArrayGetSortedKeyIndex(Node* descriptors, - Node* descriptor_number); + // Implements [Descriptor/Transition]Array::number_of_entries. + template + TNode NumberOfEntries(TNode array); + + // Implements [Descriptor/Transition]Array::GetSortedKeyIndex. + template + TNode GetSortedKeyIndex(TNode descriptors, + TNode entry_index); Node* CollectFeedbackForString(Node* instance_type); void GenerateEqual_Same(Node* value, Label* if_equal, Label* if_notequal, diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc index 225b15ee17..4a1ea6af4b 100644 --- a/src/ic/accessor-assembler.cc +++ b/src/ic/accessor-assembler.cc @@ -2060,7 +2060,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, Node* descriptors = LoadMapDescriptors(receiver_map); Label if_descriptor_found(this), stub_cache(this); - VARIABLE(var_name_index, MachineType::PointerRepresentation()); + TVARIABLE(IntPtrT, var_name_index); Label* notfound = use_stub_cache == kUseStubCache ? &stub_cache : &lookup_prototype_chain; DescriptorLookup(p->name, descriptors, bitfield3, &if_descriptor_found, diff --git a/src/ic/keyed-store-generic.cc b/src/ic/keyed-store-generic.cc index 2cea46a2d8..51d8a01f99 100644 --- a/src/ic/keyed-store-generic.cc +++ b/src/ic/keyed-store-generic.cc @@ -541,8 +541,8 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( Label next_proto(this); { Label found(this), found_fast(this), found_dict(this), found_global(this); - VARIABLE(var_meta_storage, MachineRepresentation::kTagged); - VARIABLE(var_entry, MachineType::PointerRepresentation()); + TVARIABLE(HeapObject, var_meta_storage); + TVARIABLE(IntPtrT, var_entry); TryLookupProperty(holder, holder_map, instance_type, name, &found_fast, &found_dict, &found_global, &var_meta_storage, &var_entry, &next_proto, bailout); @@ -626,7 +626,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( Comment("fast property store"); Node* descriptors = LoadMapDescriptors(receiver_map); 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; DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found, &var_name_index, &lookup_transition);