Chromium Code Reviews| Index: src/ic/accessor-assembler.cc |
| diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc |
| index 3f07b346490c541b9c95d99e58579ba6bee58592..25b4b70f3e129330a71475706de8ea0fcff609bf 100644 |
| --- a/src/ic/accessor-assembler.cc |
| +++ b/src/ic/accessor-assembler.cc |
| @@ -1403,7 +1403,8 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| 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_found_on_receiver(this); |
| + if_property_dictionary(this), if_found_on_receiver(this), |
| + lookup_prototype_chain(this); |
| Node* receiver = p->receiver; |
| GotoIf(TaggedIsSmi(receiver), &slow); |
| @@ -1528,7 +1529,8 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Variable var_name_index(this, MachineType::PointerRepresentation()); |
| Label dictionary_found(this, &var_name_index); |
| NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, |
| - &var_name_index, &slow); |
| + &var_name_index, |
| + &lookup_prototype_chain); |
| Bind(&dictionary_found); |
| { |
| LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| @@ -1545,6 +1547,48 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Return(value); |
| } |
| + Bind(&lookup_prototype_chain); |
| + { |
| + Variable var_holder_map(this, MachineRepresentation::kTagged); |
| + Variable var_holder_instance_type(this, MachineRepresentation::kWord32); |
| + Label return_undefined(this); |
| + Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; |
| + Label loop(this, arraysize(merged_variables), merged_variables); |
| + |
| + var_holder_map.Bind(receiver_map); |
| + var_holder_instance_type.Bind(instance_type); |
| + Goto(&loop); |
| + Bind(&loop); |
| + { |
| + // Bailout if it can be an integer indexed exotic case. |
| + GotoIf(Word32Equal(var_holder_instance_type.value(), |
|
Igor Sheludko
2017/01/27 08:58:08
I guess we can move this check to next_proto block
Jakob Kummerow
2017/01/28 01:41:29
No, we need it in the first iteration. "Integer in
|
| + Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| + &slow); |
| + Node* proto = LoadMapPrototype(var_holder_map.value()); |
| + GotoIf(WordEqual(proto, NullConstant()), &return_undefined); |
| + Node* proto_map = LoadMap(proto); |
| + Node* proto_instance_type = LoadMapInstanceType(proto_map); |
| + var_holder_map.Bind(proto_map); |
| + var_holder_instance_type.Bind(proto_instance_type); |
| + Label next_proto(this), return_value(this, &var_value), goto_slow(this); |
| + TryGetOwnProperty(p->context, receiver, proto, proto_map, |
| + proto_instance_type, var_unique.value(), &return_value, |
| + &var_value, &next_proto, &goto_slow); |
| + |
| + Bind(&next_proto); |
|
Jakob Kummerow
2017/01/25 16:40:06
This trampoline and the next are needed to appease
Igor Sheludko
2017/01/27 08:58:08
Maybe add this as a comment to the code.
Jakob Kummerow
2017/01/28 01:41:29
Done.
|
| + Goto(&loop); |
| + |
| + Bind(&goto_slow); |
| + Goto(&slow); |
| + |
| + Bind(&return_value); |
| + Return(var_value.value()); |
| + } |
| + |
| + Bind(&return_undefined); |
| + Return(UndefinedConstant()); |
| + } |
| + |
| Bind(&slow); |
| { |
| Comment("KeyedLoadGeneric_slow"); |