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); |