Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index 80c4c77bf6f034f21cd12a2b7d90788aa2fec7d4..aa9303aaf13ffbca5e2476965ac875565c627e83 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -2873,6 +2873,32 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, |
| } |
| } |
| +void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, |
|
Jakob Kummerow
2016/09/22 22:28:55
This is pulled out from below, unchanged.
|
| + Node* descriptors, Node* nof, |
| + Label* if_found, |
| + Variable* var_name_index, |
| + Label* if_not_found) { |
| + Variable var_descriptor(this, MachineType::PointerRepresentation()); |
| + Label loop(this, &var_descriptor); |
| + var_descriptor.Bind(IntPtrConstant(0)); |
| + Goto(&loop); |
| + |
| + Bind(&loop); |
| + { |
| + Node* index = var_descriptor.value(); |
| + Node* name_offset = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); |
| + Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); |
| + GotoIf(WordEqual(index, nof), if_not_found); |
| + Node* name_index = IntPtrAdd(name_offset, IntPtrMul(index, factor)); |
| + Node* candidate_name = |
| + LoadFixedArrayElement(descriptors, name_index, 0, INTPTR_PARAMETERS); |
| + var_name_index->Bind(name_index); |
| + GotoIf(WordEqual(candidate_name, unique_name), if_found); |
| + var_descriptor.Bind(IntPtrAdd(index, IntPtrConstant(1))); |
| + Goto(&loop); |
| + } |
| +} |
| + |
| 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, |
| @@ -2909,27 +2935,8 @@ void CodeStubAssembler::TryLookupProperty( |
| Node* descriptors = LoadMapDescriptors(map); |
| var_meta_storage->Bind(descriptors); |
| - Variable var_descriptor(this, MachineType::PointerRepresentation()); |
| - Label loop(this, &var_descriptor); |
| - var_descriptor.Bind(IntPtrConstant(0)); |
| - Goto(&loop); |
| - Bind(&loop); |
| - { |
| - Node* index = var_descriptor.value(); |
| - Node* name_offset = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); |
| - Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); |
| - GotoIf(WordEqual(index, nof), if_not_found); |
| - |
| - Node* name_index = IntPtrAdd(name_offset, IntPtrMul(index, factor)); |
| - Node* name = |
| - LoadFixedArrayElement(descriptors, name_index, 0, INTPTR_PARAMETERS); |
| - |
| - var_name_index->Bind(name_index); |
| - GotoIf(WordEqual(name, unique_name), if_found_fast); |
| - |
| - var_descriptor.Bind(IntPtrAdd(index, IntPtrConstant(1))); |
| - Goto(&loop); |
| - } |
| + DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast, |
| + var_name_index, if_not_found); |
| } |
| Bind(&if_isslowmap); |
| { |
| @@ -4327,9 +4334,11 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) { |
| void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Variable var_index(this, MachineType::PointerRepresentation()); |
| + Variable var_details(this, MachineRepresentation::kWord32); |
| + Variable var_value(this, MachineRepresentation::kTagged); |
| Label if_index(this), if_unique_name(this), if_element_hole(this), |
| if_oob(this), slow(this), stub_cache_miss(this), |
| - if_property_dictionary(this); |
| + if_property_dictionary(this), if_found_on_receiver(this); |
| Node* receiver = p->receiver; |
| GotoIf(WordIsSmi(receiver), &slow); |
| @@ -4398,19 +4407,48 @@ void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
| &if_property_dictionary); |
| - Comment("stub cache probe for fast property load"); |
|
Jakob Kummerow
2016/09/22 22:28:55
All this has moved into the "Bind(&stub_cache)" bl
|
| - Variable var_handler(this, MachineRepresentation::kTagged); |
| - Label found_handler(this, &var_handler), stub_cache_miss(this); |
| - TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, |
| - &found_handler, &var_handler, &stub_cache_miss); |
| - Bind(&found_handler); |
| - { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } |
| + // Try looking up the property on the receiver; if unsuccessful, look |
| + // for a handler in the stub cache. |
| + Comment("DescriptorArray lookup"); |
| + |
| + // Skip linear search if there are too many descriptors. |
| + // TODO(jkummerow): Consider implementing binary search. |
| + // See also TryLookupProperty() which has the same limitation. |
| + const int32_t kMaxLinear = 210; |
| + Label stub_cache(this); |
| + Node* bitfield3 = LoadMapBitField3(receiver_map); |
| + Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bitfield3); |
| + GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), &stub_cache); |
| + Node* descriptors = LoadMapDescriptors(receiver_map); |
| + Variable var_name_index(this, MachineType::PointerRepresentation()); |
| + Label if_descriptor_found(this); |
| + DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found, |
| + &var_name_index, &slow); |
| - Bind(&stub_cache_miss); |
| + Bind(&if_descriptor_found); |
| { |
| - Comment("KeyedLoadGeneric_miss"); |
| - TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
| - p->name, p->slot, p->vector); |
| + LoadPropertyFromFastObject(receiver, receiver_map, descriptors, |
| + var_name_index.value(), &var_details, |
| + &var_value); |
| + Goto(&if_found_on_receiver); |
| + } |
| + |
| + Bind(&stub_cache); |
| + { |
| + Comment("stub cache probe for fast property load"); |
| + Variable var_handler(this, MachineRepresentation::kTagged); |
| + Label found_handler(this, &var_handler), stub_cache_miss(this); |
| + TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, |
| + &found_handler, &var_handler, &stub_cache_miss); |
| + Bind(&found_handler); |
| + { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } |
| + |
| + Bind(&stub_cache_miss); |
| + { |
| + Comment("KeyedLoadGeneric_miss"); |
| + TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
| + p->name, p->slot, p->vector); |
| + } |
| } |
| } |
| @@ -4426,20 +4464,22 @@ void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| &var_name_index, &slow); |
| Bind(&dictionary_found); |
| { |
| - Variable var_details(this, MachineRepresentation::kWord32); |
| - Variable var_value(this, MachineRepresentation::kTagged); |
| LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| &var_details, &var_value); |
| - Node* kind = |
| - BitFieldDecode<PropertyDetails::KindField>(var_details.value()); |
| - // TODO(jkummerow): Support accessors without missing? |
| - GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); |
| - IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), |
| - 1); |
| - Return(var_value.value()); |
| + Goto(&if_found_on_receiver); |
| } |
| } |
| + Bind(&if_found_on_receiver); |
| + { |
| + Node* kind = |
| + BitFieldDecode<PropertyDetails::KindField>(var_details.value()); |
| + // TODO(jkummerow): Support accessors without missing? |
| + GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); |
| + IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); |
| + Return(var_value.value()); |
| + } |
| + |
| Bind(&slow); |
| { |
| Comment("KeyedLoadGeneric_slow"); |