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..495c1d7cd3638573826d8901416ab153cb8698c8 100644 |
| --- a/src/ic/accessor-assembler.cc |
| +++ b/src/ic/accessor-assembler.cc |
| @@ -1409,11 +1409,6 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| GotoIf(TaggedIsSmi(receiver), &slow); |
| Node* receiver_map = LoadMap(receiver); |
| Node* instance_type = LoadMapInstanceType(receiver_map); |
| - // Receivers requiring non-standard element accesses (interceptors, access |
| - // checks, strings and string wrappers, proxies) are handled in the runtime. |
| - GotoIf(Int32LessThanOrEqual(instance_type, |
| - Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| - &slow); |
| TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, |
| &slow); |
| @@ -1421,6 +1416,11 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Bind(&if_index); |
| { |
| Comment("integer index"); |
| + // Receivers requiring non-standard element accesses (interceptors, access |
| + // checks, strings and string wrappers, proxies) are handled in the runtime. |
| + GotoIf(Int32LessThanOrEqual(instance_type, |
| + Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| + &slow); |
| Node* index = var_index.value(); |
| Node* elements = LoadElements(receiver); |
| Node* elements_kind = LoadMapElementsKind(receiver_map); |
| @@ -1465,6 +1465,31 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Bind(&if_unique_name); |
| { |
| Comment("key is unique name"); |
| + |
| + // Receivers requiring non-standard accesses (interceptors, access |
| + // checks, string wrappers, proxies) are handled in the runtime. |
| + // We special-case strings here, to support loading <Symbol.split> etc. |
| + Variable var_receiver(this, MachineRepresentation::kTagged); |
| + Label normal_receiver(this, &var_receiver); |
| + var_receiver.Bind(receiver); |
| + GotoIf(Int32GreaterThan(instance_type, |
| + Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
| + &normal_receiver); |
| + GotoIf(Int32GreaterThanOrEqual(instance_type, |
| + Int32Constant(FIRST_NONSTRING_TYPE)), |
| + &slow); |
| + CSA_ASSERT(this, WordEqual(LoadMapConstructorFunctionIndex(receiver_map), |
| + IntPtrConstant(Context::STRING_FUNCTION_INDEX))); |
| + Node* native_context = LoadNativeContext(p->context); |
| + Node* constructor_function = |
| + LoadContextElement(native_context, Context::STRING_FUNCTION_INDEX); |
| + Node* initial_map = LoadObjectField( |
| + constructor_function, JSFunction::kPrototypeOrInitialMapOffset); |
| + var_receiver.Bind(LoadMapPrototype(initial_map)); |
| + Goto(&normal_receiver); |
| + |
| + Bind(&normal_receiver); |
| + receiver = var_receiver.value(); |
|
Igor Sheludko
2017/01/27 08:04:07
Here we are potentially changing the receiver but
Jakob Kummerow
2017/01/28 04:30:12
Oops, good point. Done.
|
| Node* key = var_unique.value(); |
|
Igor Sheludko
2017/01/27 08:13:42
Moreover, we are lucky that the elements handling
Jakob Kummerow
2017/01/28 04:30:12
Done.
|
| // Check if the receiver has fast or slow properties. |
| properties = LoadProperties(receiver); |
| @@ -1511,6 +1536,8 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Bind(&stub_cache_miss); |
| { |
| + // TODO(jkummerow): Check if the property exists on the prototype |
| + // chain. If it doesn't, then there's no point in missing. |
| Comment("KeyedLoadGeneric_miss"); |
| TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
| p->name, p->slot, p->vector); |