From de3c3c0198edfcd8899aba0e83810219860126e5 Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Wed, 29 Aug 2012 06:12:46 +0000 Subject: [PATCH] Added IC support for native setters on the prototype chain. Review URL: https://chromiumcodereview.appspot.com/10873057 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12402 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 24 +++++++++--------------- src/ia32/stub-cache-ia32.cc | 27 ++++++++++++--------------- src/ic.cc | 7 +++---- src/mips/stub-cache-mips.cc | 21 ++++++++------------- src/stub-cache.cc | 4 +++- src/stub-cache.h | 8 +++++--- src/x64/stub-cache-x64.cc | 24 +++++++++--------------- 7 files changed, 49 insertions(+), 66 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 86c247f..058c29b 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -2673,9 +2673,10 @@ Handle StoreStubCompiler::CompileStoreField(Handle object, Handle StoreStubCompiler::CompileStoreCallback( - Handle object, - Handle callback, - Handle name) { + Handle name, + Handle receiver, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- r0 : value // -- r1 : receiver @@ -2683,19 +2684,12 @@ Handle StoreStubCompiler::CompileStoreCallback( // -- lr : return address // ----------------------------------- Label miss; + // Check that the maps haven't changed. + __ JumpIfSmi(r1, &miss); + CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); - // Check that the map of the object hasn't changed. - __ CheckMap(r1, r3, Handle(object->map()), &miss, - DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); - - // Perform global security token check if needed. - if (object->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(r1, r3, &miss); - } - - // Stub never generated for non-global objects that require access - // checks. - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + // Stub never generated for non-global objects that require access checks. + ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); __ push(r1); // receiver __ mov(ip, Operand(callback)); // callback info diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index d205ccb..5f1e26b 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -2601,9 +2601,10 @@ Handle StoreStubCompiler::CompileStoreField(Handle object, Handle StoreStubCompiler::CompileStoreCallback( - Handle object, - Handle callback, - Handle name) { + Handle name, + Handle receiver, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- eax : value // -- ecx : name @@ -2611,19 +2612,14 @@ Handle StoreStubCompiler::CompileStoreCallback( // -- esp[0] : return address // ----------------------------------- Label miss; + // Check that the maps haven't changed, preserving the value register. + __ push(eax); + __ JumpIfSmi(edx, &miss); + CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss); + __ pop(eax); // restore value - // Check that the map of the object hasn't changed. - __ CheckMap(edx, Handle(object->map()), - &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); - - // Perform global security token check if needed. - if (object->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(edx, ebx, &miss); - } - - // Stub never generated for non-global objects that require access - // checks. - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + // Stub never generated for non-global objects that require access checks. + ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); __ pop(ebx); // remove the return address __ push(edx); // receiver @@ -2639,6 +2635,7 @@ Handle StoreStubCompiler::CompileStoreCallback( // Handle store cache miss. __ bind(&miss); + __ pop(eax); Handle ic = isolate()->builtins()->StoreIC_Miss(); __ jmp(ic, RelocInfo::CODE_TARGET); diff --git a/src/ic.cc b/src/ic.cc index 9d62a0c..a8d16d3 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1331,7 +1331,7 @@ static bool LookupForWrite(Handle receiver, return false; } Handle callback(lookup->GetCallbackObject()); - return callback->IsAccessorPair() && StoreICableLookup(lookup); + return StoreICableLookup(lookup); } if (lookup->IsInterceptor() && @@ -1491,13 +1491,12 @@ void StoreIC::UpdateCaches(LookupResult* lookup, case CALLBACKS: { Handle callback(lookup->GetCallbackObject()); if (callback->IsAccessorInfo()) { - ASSERT(*holder == *receiver); // LookupForWrite checks this. Handle info = Handle::cast(callback); if (v8::ToCData
(info->setter()) == 0) return; if (!holder->HasFastProperties()) return; - ASSERT(info->IsCompatibleReceiver(*receiver)); + if (!info->IsCompatibleReceiver(*receiver)) return; code = isolate()->stub_cache()->ComputeStoreCallback( - name, receiver, info, strict_mode); + name, receiver, holder, info, strict_mode); } else if (callback->IsAccessorPair()) { Handle setter(Handle::cast(callback)->setter()); if (!setter->IsJSFunction()) return; diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index afa2bfd..2594f49 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -2676,9 +2676,10 @@ Handle StoreStubCompiler::CompileStoreField(Handle object, Handle StoreStubCompiler::CompileStoreCallback( - Handle object, - Handle callback, - Handle name) { + Handle name, + Handle receiver, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- a0 : value // -- a1 : receiver @@ -2686,19 +2687,13 @@ Handle StoreStubCompiler::CompileStoreCallback( // -- ra : return address // ----------------------------------- Label miss; - - // Check that the map of the object hasn't changed. - __ CheckMap(a1, a3, Handle(object->map()), &miss, - DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); - - // Perform global security token check if needed. - if (object->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(a1, a3, &miss); - } + // Check that the maps haven't changed. + __ JumpIfSmi(a1, &miss, a3); + CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); // Stub never generated for non-global objects that require access // checks. - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); __ push(a1); // Receiver. __ li(a3, Operand(callback)); // Callback info. diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 5f24ede..82e2583 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -504,6 +504,7 @@ Handle StubCache::ComputeStoreGlobal(Handle name, Handle StubCache::ComputeStoreCallback(Handle name, Handle receiver, + Handle holder, Handle callback, StrictModeFlag strict_mode) { ASSERT(v8::ToCData
(callback->setter()) != 0); @@ -513,7 +514,8 @@ Handle StubCache::ComputeStoreCallback(Handle name, if (probe->IsCode()) return Handle::cast(probe); StoreStubCompiler compiler(isolate_, strict_mode); - Handle code = compiler.CompileStoreCallback(receiver, callback, name); + Handle code = + compiler.CompileStoreCallback(name, receiver, holder, callback); PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); JSObject::UpdateMapCodeCache(receiver, name, code); diff --git a/src/stub-cache.h b/src/stub-cache.h index 1c6c09b..418a1d2 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -159,6 +159,7 @@ class StubCache { Handle ComputeStoreCallback(Handle name, Handle receiver, + Handle holder, Handle callback, StrictModeFlag strict_mode); @@ -704,9 +705,10 @@ class StoreStubCompiler: public StubCompiler { Handle transition, Handle name); - Handle CompileStoreCallback(Handle object, - Handle callback, - Handle name); + Handle CompileStoreCallback(Handle name, + Handle receiver, + Handle holder, + Handle callback); static void GenerateStoreViaSetter(MacroAssembler* masm, Handle setter); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 02b4bbe..cb6198a 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -2429,9 +2429,10 @@ Handle StoreStubCompiler::CompileStoreField(Handle object, Handle StoreStubCompiler::CompileStoreCallback( - Handle object, - Handle callback, - Handle name) { + Handle name, + Handle receiver, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- rax : value // -- rcx : name @@ -2439,19 +2440,12 @@ Handle StoreStubCompiler::CompileStoreCallback( // -- rsp[0] : return address // ----------------------------------- Label miss; + // Check that the maps haven't changed. + __ JumpIfSmi(rdx, &miss); + CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); - // Check that the map of the object hasn't changed. - __ CheckMap(rdx, Handle(object->map()), &miss, - DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); - - // Perform global security token check if needed. - if (object->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(rdx, rbx, &miss); - } - - // Stub never generated for non-global objects that require access - // checks. - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + // Stub never generated for non-global objects that require access checks. + ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); __ pop(rbx); // remove the return address __ push(rdx); // receiver -- 2.7.4