From: svenpanne@chromium.org Date: Fri, 8 Jun 2012 08:48:05 +0000 (+0000) Subject: Added LoadIC stub for getters. X-Git-Tag: upstream/4.7.83~16592 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=40dbd13e2e40f07d1e6ff50bfb09a7f2602a994a;p=platform%2Fupstream%2Fv8.git Added LoadIC stub for getters. Removed some dead constants on the way. Review URL: https://chromiumcodereview.appspot.com/10515008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11735 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index d6de0f5..91ef35b 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -2835,6 +2835,43 @@ Handle LoadStubCompiler::CompileLoadCallback( } +Handle LoadStubCompiler::CompileLoadViaGetter( + Handle name, + Handle receiver, + Handle holder, + Handle getter) { + // ----------- S t a t e ------------- + // -- r0 : receiver + // -- r2 : name + // -- lr : return address + // ----------------------------------- + Label miss; + + // Check that the maps haven't changed. + __ JumpIfSmi(r0, &miss); + CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss); + + { + FrameScope scope(masm(), StackFrame::INTERNAL); + + // Call the JavaScript getter with the receiver on the stack. + __ push(r0); + __ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION, + NullCallWrapper(), CALL_AS_METHOD); + + // Restore context register. + __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + } + __ Ret(); + + __ bind(&miss); + GenerateLoadMiss(masm(), Code::LOAD_IC); + + // Return the generated code. + return GetCode(CALLBACKS, name); +} + + Handle LoadStubCompiler::CompileLoadConstant(Handle object, Handle holder, Handle value, diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 2925ae1..b556b1c 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -2860,6 +2860,43 @@ Handle LoadStubCompiler::CompileLoadCallback( } +Handle LoadStubCompiler::CompileLoadViaGetter( + Handle name, + Handle receiver, + Handle holder, + Handle getter) { + // ----------- S t a t e ------------- + // -- ecx : name + // -- edx : receiver + // -- esp[0] : return address + // ----------------------------------- + Label miss; + + // Check that the maps haven't changed. + __ JumpIfSmi(edx, &miss); + CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss); + + { + FrameScope scope(masm(), StackFrame::INTERNAL); + + // Call the JavaScript getter with the receiver on the stack. + __ push(edx); + __ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION, + NullCallWrapper(), CALL_AS_METHOD); + + // Restore context register. + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + } + __ ret(0); + + __ bind(&miss); + GenerateLoadMiss(masm(), Code::LOAD_IC); + + // Return the generated code. + return GetCode(CALLBACKS, name); +} + + Handle LoadStubCompiler::CompileLoadConstant(Handle object, Handle holder, Handle value, diff --git a/src/ic.cc b/src/ic.cc index d6eec9d..0c6fb42 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -988,14 +988,25 @@ void LoadIC::UpdateCaches(LookupResult* lookup, } break; case CALLBACKS: { - Handle callback_object(lookup->GetCallbackObject()); - if (!callback_object->IsAccessorInfo()) return; - Handle callback = - Handle::cast(callback_object); - if (v8::ToCData
(callback->getter()) == 0) return; - if (!callback->IsCompatibleReceiver(*receiver)) return; - code = isolate()->stub_cache()->ComputeLoadCallback( - name, receiver, holder, callback); + Handle callback(lookup->GetCallbackObject()); + if (callback->IsAccessorInfo()) { + Handle info = Handle::cast(callback); + if (v8::ToCData
(info->getter()) == 0) return; + if (!info->IsCompatibleReceiver(*receiver)) return; + code = isolate()->stub_cache()->ComputeLoadCallback( + name, receiver, holder, info); + } else if (callback->IsAccessorPair()) { + Handle getter(Handle::cast(callback)->getter()); + if (!getter->IsJSFunction()) return; + if (holder->IsGlobalObject()) return; + if (!receiver->HasFastProperties()) return; + code = isolate()->stub_cache()->ComputeLoadViaGetter( + name, receiver, holder, Handle::cast(getter)); + } else { + ASSERT(callback->IsForeign()); + // No IC support for old-style native accessors. + return; + } break; } case INTERCEPTOR: diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 1ae59a2..64be4c1 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -2839,6 +2839,43 @@ Handle LoadStubCompiler::CompileLoadCallback( } +Handle LoadStubCompiler::CompileLoadViaGetter( + Handle name, + Handle receiver, + Handle holder, + Handle getter) { + // ----------- S t a t e ------------- + // -- a0 : receiver + // -- a2 : name + // -- ra : return address + // ----------------------------------- + Label miss; + + // Check that the maps haven't changed. + __ JumpIfSmi(a0, &miss); + CheckPrototypes(receiver, a0, holder, a3, t0, a1, name, &miss); + + { + FrameScope scope(masm(), StackFrame::INTERNAL); + + // Call the JavaScript getter with the receiver on the stack. + __ push(a0); + __ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION, + NullCallWrapper(), CALL_AS_METHOD); + + // Restore context register. + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + } + __ Ret(); + + __ bind(&miss); + GenerateLoadMiss(masm(), Code::LOAD_IC); + + // Return the generated code. + return GetCode(CALLBACKS, name); +} + + Handle LoadStubCompiler::CompileLoadConstant(Handle object, Handle holder, Handle value, diff --git a/src/objects.h b/src/objects.h index 5bda88e..5b06dac 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5010,11 +5010,6 @@ class Map: public HeapObject { static const int kFunctionWithPrototype = 1; static const int kUsedForPrototype = 2; - // Layout of the default cache. It holds alternating name and code objects. - static const int kCodeCacheEntrySize = 2; - static const int kCodeCacheEntryNameOffset = 0; - static const int kCodeCacheEntryCodeOffset = 1; - typedef FixedBodyDescriptor BodyDescriptor; diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 62e2377..da39554 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -171,6 +171,25 @@ Handle StubCache::ComputeLoadCallback(Handle name, } +Handle StubCache::ComputeLoadViaGetter(Handle name, + Handle receiver, + Handle holder, + Handle getter) { + ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); + Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); + Handle probe(receiver->map()->FindInCodeCache(*name, flags)); + if (probe->IsCode()) return Handle::cast(probe); + + LoadStubCompiler compiler(isolate_); + Handle code = + compiler.CompileLoadViaGetter(name, receiver, holder, getter); + PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); + GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); + JSObject::UpdateMapCodeCache(receiver, name, code); + return code; +} + + Handle StubCache::ComputeLoadConstant(Handle name, Handle receiver, Handle holder, diff --git a/src/stub-cache.h b/src/stub-cache.h index 105a46d..c415276 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -90,6 +90,11 @@ class StubCache { Handle holder, Handle callback); + Handle ComputeLoadViaGetter(Handle name, + Handle receiver, + Handle holder, + Handle getter); + Handle ComputeLoadConstant(Handle name, Handle receiver, Handle holder, @@ -596,6 +601,11 @@ class LoadStubCompiler: public StubCompiler { Handle holder, Handle callback); + Handle CompileLoadViaGetter(Handle name, + Handle receiver, + Handle holder, + Handle getter); + Handle CompileLoadConstant(Handle object, Handle holder, Handle value, diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index a0a5386..e899997 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -2698,6 +2698,43 @@ Handle LoadStubCompiler::CompileLoadCallback( } +Handle LoadStubCompiler::CompileLoadViaGetter( + Handle name, + Handle receiver, + Handle holder, + Handle getter) { + // ----------- S t a t e ------------- + // -- rax : receiver + // -- rcx : name + // -- rsp[0] : return address + // ----------------------------------- + Label miss; + + // Check that the maps haven't changed. + __ JumpIfSmi(rax, &miss); + CheckPrototypes(receiver, rax, holder, rbx, rdx, rdi, name, &miss); + + { + FrameScope scope(masm(), StackFrame::INTERNAL); + + // Call the JavaScript getter with the receiver on the stack. + __ push(rax); + __ InvokeFunction(getter, ParameterCount(0), CALL_FUNCTION, + NullCallWrapper(), CALL_AS_METHOD); + + // Restore context register. + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); + } + __ ret(0); + + __ bind(&miss); + GenerateLoadMiss(masm(), Code::LOAD_IC); + + // Return the generated code. + return GetCode(CALLBACKS, name); +} + + Handle LoadStubCompiler::CompileLoadConstant(Handle object, Handle holder, Handle value,