From 12039c97c6a913edbbea72ecf9af1fdd67b441c0 Mon Sep 17 00:00:00 2001 From: "dcarney@chromium.org" Date: Thu, 6 Feb 2014 10:50:07 +0000 Subject: [PATCH] swap in global proxy on accessors R=verwaest@chromium.org BUG= Review URL: https://codereview.chromium.org/156623002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19142 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 20 ++++++++++++++++++-- src/builtins.cc | 6 ++++-- src/ia32/stub-cache-ia32.cc | 20 +++++++++++++++++--- src/stub-cache.cc | 8 ++++---- src/stub-cache.h | 2 ++ src/x64/stub-cache-x64.cc | 20 +++++++++++++++++--- test/cctest/test-accessors.cc | 18 ++++++++++++++++++ 7 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index ca63052..694a4ed 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -1284,6 +1284,7 @@ Handle StoreStubCompiler::CompileStoreCallback( void StoreStubCompiler::GenerateStoreViaSetter( MacroAssembler* masm, + Handle type, Handle setter) { // ----------- S t a t e ------------- // -- r0 : value @@ -1293,13 +1294,21 @@ void StoreStubCompiler::GenerateStoreViaSetter( // ----------------------------------- { FrameScope scope(masm, StackFrame::INTERNAL); + Register receiver = r1; + Register value = r0; // Save value register, so we can restore it later. - __ push(r0); + __ push(value); if (!setter.is_null()) { // Call the JavaScript setter with receiver and value on the stack. - __ Push(r1, r0); + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ ldr(receiver, + FieldMemOperand( + receiver, JSGlobalObject::kGlobalReceiverOffset)); + } + __ Push(receiver, value); ParameterCount actual(1); ParameterCount expected(setter); __ InvokeFunction(setter, expected, actual, @@ -1406,6 +1415,7 @@ Register* KeyedStoreStubCompiler::registers() { void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, + Handle type, Register receiver, Handle getter) { // ----------- S t a t e ------------- @@ -1418,6 +1428,12 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, if (!getter.is_null()) { // Call the JavaScript getter with the receiver on the stack. + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ ldr(receiver, + FieldMemOperand( + receiver, JSGlobalObject::kGlobalReceiverOffset)); + } __ push(receiver); ParameterCount actual(0); ParameterCount expected(getter); diff --git a/src/builtins.cc b/src/builtins.cc index a690b31..e68890f 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1321,7 +1321,8 @@ static void Generate_LoadIC_Normal(MacroAssembler* masm) { static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) { LoadStubCompiler::GenerateLoadViaGetter( - masm, LoadStubCompiler::registers()[0], Handle()); + masm, Handle::null(), + LoadStubCompiler::registers()[0], Handle()); } @@ -1386,7 +1387,8 @@ static void Generate_StoreIC_Normal(MacroAssembler* masm) { static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { - StoreStubCompiler::GenerateStoreViaSetter(masm, Handle()); + StoreStubCompiler::GenerateStoreViaSetter( + masm, Handle::null(), Handle()); } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index f91cee2..a5b93b9 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -1287,6 +1287,7 @@ Handle StoreStubCompiler::CompileStoreCallback( void StoreStubCompiler::GenerateStoreViaSetter( MacroAssembler* masm, + Handle type, Handle setter) { // ----------- S t a t e ------------- // -- eax : value @@ -1296,14 +1297,21 @@ void StoreStubCompiler::GenerateStoreViaSetter( // ----------------------------------- { FrameScope scope(masm, StackFrame::INTERNAL); + Register receiver = edx; + Register value = eax; // Save value register, so we can restore it later. - __ push(eax); + __ push(value); if (!setter.is_null()) { // Call the JavaScript setter with receiver and value on the stack. - __ push(edx); - __ push(eax); + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ mov(receiver, + FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); + } + __ push(receiver); + __ push(value); ParameterCount actual(1); ParameterCount expected(setter); __ InvokeFunction(setter, expected, actual, @@ -1423,6 +1431,7 @@ Register* KeyedStoreStubCompiler::registers() { void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, + Handle type, Register receiver, Handle getter) { { @@ -1430,6 +1439,11 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, if (!getter.is_null()) { // Call the JavaScript getter with the receiver on the stack. + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ mov(receiver, + FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); + } __ push(receiver); ParameterCount actual(0); ParameterCount expected(getter); diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 4cf85c3..5dfce55 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -1030,7 +1030,7 @@ Handle LoadStubCompiler::CompileLoadViaGetter( Handle name, Handle getter) { HandlerFrontend(type, receiver(), holder, name); - GenerateLoadViaGetter(masm(), receiver(), getter); + GenerateLoadViaGetter(masm(), type, receiver(), getter); // Return the generated code. return GetCode(kind(), Code::FAST, name); @@ -1123,9 +1123,9 @@ Handle StoreStubCompiler::CompileStoreViaSetter( Handle holder, Handle name, Handle setter) { - HandlerFrontend(IC::CurrentTypeOf(object, isolate()), - receiver(), holder, name); - GenerateStoreViaSetter(masm(), setter); + Handle type = IC::CurrentTypeOf(object, isolate()); + HandlerFrontend(type, receiver(), holder, name); + GenerateStoreViaSetter(masm(), type, setter); return GetCode(kind(), Code::FAST, name); } diff --git a/src/stub-cache.h b/src/stub-cache.h index d893349..f55c440 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -567,6 +567,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { Handle getter); static void GenerateLoadViaGetter(MacroAssembler* masm, + Handle type, Register receiver, Handle getter); @@ -712,6 +713,7 @@ class StoreStubCompiler: public BaseLoadStoreStubCompiler { const CallOptimization& call_optimization); static void GenerateStoreViaSetter(MacroAssembler* masm, + Handle type, Handle setter); Handle CompileStoreViaSetter(Handle object, diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 3e06865..a43d709 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1182,6 +1182,7 @@ Handle StoreStubCompiler::CompileStoreCallback( void StoreStubCompiler::GenerateStoreViaSetter( MacroAssembler* masm, + Handle type, Handle setter) { // ----------- S t a t e ------------- // -- rax : value @@ -1191,14 +1192,21 @@ void StoreStubCompiler::GenerateStoreViaSetter( // ----------------------------------- { FrameScope scope(masm, StackFrame::INTERNAL); + Register receiver = rdx; + Register value = rax; // Save value register, so we can restore it later. - __ push(rax); + __ push(value); if (!setter.is_null()) { // Call the JavaScript setter with receiver and value on the stack. - __ push(rdx); - __ push(rax); + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ movp(receiver, + FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); + } + __ push(receiver); + __ push(value); ParameterCount actual(1); ParameterCount expected(setter); __ InvokeFunction(setter, expected, actual, @@ -1325,6 +1333,7 @@ Register* KeyedStoreStubCompiler::registers() { void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, + Handle type, Register receiver, Handle getter) { // ----------- S t a t e ------------- @@ -1337,6 +1346,11 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, if (!getter.is_null()) { // Call the JavaScript getter with the receiver on the stack. + if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + // Swap in the global receiver. + __ movp(receiver, + FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); + } __ push(receiver); ParameterCount actual(0); ParameterCount expected(getter); diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc index a3ce5c3..bda09f0 100644 --- a/test/cctest/test-accessors.cc +++ b/test/cctest/test-accessors.cc @@ -606,3 +606,21 @@ THREADED_TEST(AccessorPropertyCrossContext) { "for (var i = 0; i < 10; i++) o.n;"); CHECK(!try_catch.HasCaught()); } + + +THREADED_TEST(GlobalObjectAccessor) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + CompileRun( + "var set_value = 1;" + "Object.defineProperty(this.__proto__, 'x', {" + " get : function() { return this; }," + " set : function() { set_value = this; }" + "});" + "function getter() { return x; }" + "function setter() { x = 1; }" + "for (var i = 0; i < 4; i++) { getter(); setter(); }"); + CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy()); + CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy()); +} -- 2.7.4