diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/arm/handler-compiler-arm.cc index b990a94b93..d0db7904c8 100644 --- a/src/ic/arm/handler-compiler-arm.cc +++ b/src/ic/arm/handler-compiler-arm.cc @@ -266,14 +266,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ Move(holder, api_holder); + __ ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); + __ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/arm64/handler-compiler-arm64.cc b/src/ic/arm64/handler-compiler-arm64.cc index 87edcd269a..3a6d156943 100644 --- a/src/ic/arm64/handler-compiler-arm64.cc +++ b/src/ic/arm64/handler-compiler-arm64.cc @@ -178,14 +178,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Mov(holder, receiver); break; case CallOptimization::kHolderFound: - __ LoadObject(holder, api_holder); + __ Ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ Ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); + __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/call-optimization.cc b/src/ic/call-optimization.cc index 065b1472eb..5377988d11 100644 --- a/src/ic/call-optimization.cc +++ b/src/ic/call-optimization.cc @@ -16,7 +16,8 @@ CallOptimization::CallOptimization(Handle function) { Handle CallOptimization::LookupHolderOfExpectedType( - Handle object_map, HolderLookup* holder_lookup) const { + Handle object_map, HolderLookup* holder_lookup, + int* holder_depth_in_prototype_chain) const { DCHECK(is_simple_api_call()); if (!object_map->IsJSObjectMap()) { *holder_lookup = kHolderNotFound; @@ -27,13 +28,16 @@ Handle CallOptimization::LookupHolderOfExpectedType( *holder_lookup = kHolderIsReceiver; return Handle::null(); } - while (true) { + for (int depth = 1; true; depth++) { if (!object_map->prototype()->IsJSObject()) break; Handle prototype(JSObject::cast(object_map->prototype())); if (!prototype->map()->is_hidden_prototype()) break; object_map = handle(prototype->map()); if (expected_receiver_type_->IsTemplateFor(*object_map)) { *holder_lookup = kHolderFound; + if (holder_depth_in_prototype_chain != NULL) { + *holder_depth_in_prototype_chain = depth; + } return prototype; } } diff --git a/src/ic/call-optimization.h b/src/ic/call-optimization.h index 99494fa3ba..b6435d25a3 100644 --- a/src/ic/call-optimization.h +++ b/src/ic/call-optimization.h @@ -38,7 +38,8 @@ class CallOptimization BASE_EMBEDDED { enum HolderLookup { kHolderNotFound, kHolderIsReceiver, kHolderFound }; Handle LookupHolderOfExpectedType( - Handle receiver_map, HolderLookup* holder_lookup) const; + Handle receiver_map, HolderLookup* holder_lookup, + int* holder_depth_in_prototype_chain = NULL) const; // Check if the api holder is between the receiver and the holder. bool IsCompatibleReceiver(Handle receiver, diff --git a/src/ic/ia32/handler-compiler-ia32.cc b/src/ic/ia32/handler-compiler-ia32.cc index c7f683fd5b..65adbff48e 100644 --- a/src/ic/ia32/handler-compiler-ia32.cc +++ b/src/ic/ia32/handler-compiler-ia32.cc @@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ LoadHeapObject(holder, api_holder); + __ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset)); + __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ mov(holder, FieldOperand(holder, HeapObject::kMapOffset)); + __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/mips/handler-compiler-mips.cc b/src/ic/mips/handler-compiler-mips.cc index 1a8aadcf80..b02179b4a3 100644 --- a/src/ic/mips/handler-compiler-mips.cc +++ b/src/ic/mips/handler-compiler-mips.cc @@ -259,14 +259,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ li(holder, api_holder); + __ lw(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ lw(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); + __ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/mips64/handler-compiler-mips64.cc b/src/ic/mips64/handler-compiler-mips64.cc index e82073fe76..5e7814c815 100644 --- a/src/ic/mips64/handler-compiler-mips64.cc +++ b/src/ic/mips64/handler-compiler-mips64.cc @@ -260,14 +260,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ li(holder, api_holder); + __ ld(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ ld(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); + __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/x64/handler-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc index ce621777ea..cdc5b5e38c 100644 --- a/src/ic/x64/handler-compiler-x64.cc +++ b/src/ic/x64/handler-compiler-x64.cc @@ -161,14 +161,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ Move(holder, api_holder); + __ movp(holder, FieldOperand(receiver, HeapObject::kMapOffset)); + __ movp(holder, FieldOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ movp(holder, FieldOperand(holder, HeapObject::kMapOffset)); + __ movp(holder, FieldOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE(); diff --git a/src/ic/x87/handler-compiler-x87.cc b/src/ic/x87/handler-compiler-x87.cc index 11e727c081..1110410771 100644 --- a/src/ic/x87/handler-compiler-x87.cc +++ b/src/ic/x87/handler-compiler-x87.cc @@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( // Put holder in place. CallOptimization::HolderLookup holder_lookup; - Handle api_holder = - optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); + int holder_depth = 0; + optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, + &holder_depth); switch (holder_lookup) { case CallOptimization::kHolderIsReceiver: __ Move(holder, receiver); break; case CallOptimization::kHolderFound: - __ LoadHeapObject(holder, api_holder); + __ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset)); + __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset)); + for (int i = 1; i < holder_depth; i++) { + __ mov(holder, FieldOperand(holder, HeapObject::kMapOffset)); + __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset)); + } break; case CallOptimization::kHolderNotFound: UNREACHABLE();