swap in global proxy on accessors
authordcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Feb 2014 10:50:07 +0000 (10:50 +0000)
committerdcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Feb 2014 10:50:07 +0000 (10:50 +0000)
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
src/builtins.cc
src/ia32/stub-cache-ia32.cc
src/stub-cache.cc
src/stub-cache.h
src/x64/stub-cache-x64.cc
test/cctest/test-accessors.cc

index ca63052..694a4ed 100644 (file)
@@ -1284,6 +1284,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
 
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
+    Handle<HeapType> type,
     Handle<JSFunction> 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<HeapType> type,
                                              Register receiver,
                                              Handle<JSFunction> 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);
index a690b31..e68890f 100644 (file)
@@ -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<JSFunction>());
+      masm, Handle<HeapType>::null(),
+      LoadStubCompiler::registers()[0], Handle<JSFunction>());
 }
 
 
@@ -1386,7 +1387,8 @@ static void Generate_StoreIC_Normal(MacroAssembler* masm) {
 
 
 static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
-  StoreStubCompiler::GenerateStoreViaSetter(masm, Handle<JSFunction>());
+  StoreStubCompiler::GenerateStoreViaSetter(
+      masm, Handle<HeapType>::null(), Handle<JSFunction>());
 }
 
 
index f91cee2..a5b93b9 100644 (file)
@@ -1287,6 +1287,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
 
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
+    Handle<HeapType> type,
     Handle<JSFunction> 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<HeapType> type,
                                              Register receiver,
                                              Handle<JSFunction> 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);
index 4cf85c3..5dfce55 100644 (file)
@@ -1030,7 +1030,7 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
     Handle<Name> name,
     Handle<JSFunction> 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<Code> StoreStubCompiler::CompileStoreViaSetter(
     Handle<JSObject> holder,
     Handle<Name> name,
     Handle<JSFunction> setter) {
-  HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
-                  receiver(), holder, name);
-  GenerateStoreViaSetter(masm(), setter);
+  Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
+  HandlerFrontend(type, receiver(), holder, name);
+  GenerateStoreViaSetter(masm(), type, setter);
 
   return GetCode(kind(), Code::FAST, name);
 }
index d893349..f55c440 100644 (file)
@@ -567,6 +567,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
                                     Handle<JSFunction> getter);
 
   static void GenerateLoadViaGetter(MacroAssembler* masm,
+                                    Handle<HeapType> type,
                                     Register receiver,
                                     Handle<JSFunction> getter);
 
@@ -712,6 +713,7 @@ class StoreStubCompiler: public BaseLoadStoreStubCompiler {
                                     const CallOptimization& call_optimization);
 
   static void GenerateStoreViaSetter(MacroAssembler* masm,
+                                     Handle<HeapType> type,
                                      Handle<JSFunction> setter);
 
   Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
index 3e06865..a43d709 100644 (file)
@@ -1182,6 +1182,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
 
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
+    Handle<HeapType> type,
     Handle<JSFunction> 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<HeapType> type,
                                              Register receiver,
                                              Handle<JSFunction> 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);
index a3ce5c3..bda09f0 100644 (file)
@@ -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());
+}