Revision: 3750
Author: [email protected]
Date: Mon Feb  1 00:35:38 2010
Log: StoreIC interface changed on ia32 to take receiver in edx, not on stack.
Review URL: http://codereview.chromium.org/555162
http://code.google.com/p/v8/source/detail?r=3750

Modified:
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/ic-ia32.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Fri Jan 29 04:41:11 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Feb 1 00:35:38 2010
@@ -4472,8 +4472,6 @@
           Load(property->value());
           frame_->Push(key);
           Result ignored = frame_->CallStoreIC();
-          // Drop the duplicated receiver and ignore the result.
-          frame_->Drop();
           break;
         }
         // Fall through
@@ -6715,7 +6713,7 @@
       cgen_->frame()->Push(GetName());
       Result answer = cgen_->frame()->CallStoreIC();
       cgen_->frame()->Push(&answer);
-      cgen_->UnloadReference(this);
+      set_unloaded();
       break;
     }

=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Jan 28 01:08:01 2010 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Feb 1 00:35:38 2010
@@ -917,10 +917,10 @@
         if (key->handle()->IsSymbol()) {
           VisitForValue(value, kAccumulator);
           __ mov(ecx, Immediate(key->handle()));
+          __ mov(edx, Operand(esp, 0));
           Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
           __ call(ic, RelocInfo::CODE_TARGET);
           __ nop();
-          // StoreIC leaves the receiver on the stack.
           break;
         }
         // Fall through.
@@ -1046,12 +1046,11 @@
// assignment. Right-hand-side value is passed in eax, variable name in
     // ecx, and the global object on the stack.
     __ mov(ecx, var->name());
-    __ push(CodeGenerator::GlobalObject());
+    __ mov(edx, CodeGenerator::GlobalObject());
     Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
     __ call(ic, RelocInfo::CODE_TARGET);
     __ nop();
-    // Overwrite the receiver on the stack with the result if needed.
-    DropAndApply(1, context, eax);
+    Apply(context, eax);

   } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
     __ push(result_register());  // Value.
@@ -1111,6 +1110,11 @@
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
   __ mov(ecx, prop->key()->AsLiteral()->handle());
+  if (expr->ends_initialization_block()) {
+    __ mov(edx, Operand(esp, 0));
+  } else {
+    __ pop(edx);
+  }
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
   __ nop();
@@ -1121,9 +1125,10 @@
     __ push(Operand(esp, kPointerSize));  // Receiver is under value.
     __ CallRuntime(Runtime::kToFastProperties, 1);
     __ pop(eax);
-  }
-
-  DropAndApply(1, context_, eax);
+    DropAndApply(1, context_, eax);
+  } else {
+    Apply(context_, eax);
+  }
 }


@@ -1642,18 +1647,18 @@
       break;
     case NAMED_PROPERTY: {
       __ mov(ecx, prop->key()->AsLiteral()->handle());
+      __ pop(edx);
       Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
       __ call(ic, RelocInfo::CODE_TARGET);
// This nop signals to the IC that there is no inlined code at the call
       // site for it to patch.
       __ nop();
       if (expr->is_postfix()) {
-        __ Drop(1);  // Result is on the stack under the receiver.
         if (context_ != Expression::kEffect) {
           ApplyTOS(context_);
         }
       } else {
-        DropAndApply(1, context_, eax);
+        Apply(context_, eax);
       }
       break;
     }
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Thu Jan 28 04:41:27 2010
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Mon Feb  1 00:35:38 2010
@@ -1379,12 +1379,10 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------

-  // Get the receiver from the stack and probe the stub cache.
-  __ mov(edx, Operand(esp, 4));
   Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
                                          NOT_IN_LOOP,
                                          MONOMORPHIC);
@@ -1399,12 +1397,12 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : transition map
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------

   __ pop(ebx);
-  __ push(Operand(esp, 0));  // receiver
+  __ push(edx);  // receiver
   __ push(ecx);  // transition map
   __ push(eax);  // value
   __ push(ebx);  // return address
@@ -1419,12 +1417,12 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------

   __ pop(ebx);
-  __ push(Operand(esp, 0));
+  __ push(edx);
   __ push(ecx);
   __ push(eax);
   __ push(ebx);
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Jan 28 06:01:14 2010 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon Feb 1 00:35:38 2010
@@ -1255,21 +1255,18 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;

-  // Get the object from the stack.
-  __ mov(ebx, Operand(esp, 1 * kPointerSize));
-
   // Generate store field code.  Trashes the name register.
   GenerateStoreField(masm(),
                      Builtins::StoreIC_ExtendStorage,
                      object,
                      index,
                      transition,
-                     ebx, ecx, edx,
+                     edx, ecx, ebx,
                      &miss);

   // Handle store cache miss.
@@ -1289,26 +1286,23 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;

-  // Get the object from the stack.
-  __ mov(ebx, Operand(esp, 1 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ test(ebx, Immediate(kSmiTagMask));
+  __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &miss, not_taken);

   // Check that the map of the object hasn't changed.
-  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
+  __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
          Immediate(Handle<Map>(object->map())));
   __ j(not_equal, &miss, not_taken);

   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(ebx, edx, &miss);
+    __ CheckAccessGlobalProxy(edx, ebx, &miss);
   }

   // Stub never generated for non-global objects that require access
@@ -1316,7 +1310,7 @@
   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());

   __ pop(ebx);  // remove the return address
-  __ push(Operand(esp, 0));  // receiver
+  __ push(edx);  // receiver
   __ push(Immediate(Handle<AccessorInfo>(callback)));  // callback info
   __ push(ecx);  // name
   __ push(eax);  // value
@@ -1342,26 +1336,23 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;

-  // Get the object from the stack.
-  __ mov(ebx, Operand(esp, 1 * kPointerSize));
-
   // Check that the object isn't a smi.
-  __ test(ebx, Immediate(kSmiTagMask));
+  __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &miss, not_taken);

   // Check that the map of the object hasn't changed.
-  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
+  __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
          Immediate(Handle<Map>(receiver->map())));
   __ j(not_equal, &miss, not_taken);

   // Perform global security token check if needed.
   if (receiver->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(ebx, edx, &miss);
+    __ CheckAccessGlobalProxy(edx, ebx, &miss);
   }

   // Stub never generated for non-global objects that require access
@@ -1369,7 +1360,7 @@
   ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());

   __ pop(ebx);  // remove the return address
-  __ push(Operand(esp, 0));  // receiver
+  __ push(edx);  // receiver
   __ push(ecx);  // name
   __ push(eax);  // value
   __ push(ebx);  // restore return address
@@ -1395,14 +1386,13 @@
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
+  //  -- edx    : receiver
   //  -- esp[0] : return address
-  //  -- esp[4] : receiver
   // -----------------------------------
   Label miss;

   // Check that the map of the global has not changed.
-  __ mov(ebx, Operand(esp, kPointerSize));
-  __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
+  __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
          Immediate(Handle<Map>(object->map())));
   __ j(not_equal, &miss, not_taken);

=======================================
--- /branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc Wed Dec 23 07:06:21 2009 +++ /branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc Mon Feb 1 00:35:38 2010
@@ -899,31 +899,45 @@

 Result VirtualFrame::CallStoreIC() {
   // Name, value, and receiver are on top of the frame.  The IC
-  // expects name in ecx, value in eax, and receiver on the stack.  It
-  // does not drop the receiver.
+  // expects name in ecx, value in eax, and receiver in edx.
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   Result name = Pop();
   Result value = Pop();
-  PrepareForCall(1, 0);  // One stack arg, not callee-dropped.
-
-  if (value.is_register() && value.reg().is(ecx)) {
-    if (name.is_register() && name.reg().is(eax)) {
+  Result receiver = Pop();
+  PrepareForCall(0, 0);
+
+  // Optimized for case in which name is a constant value.
+  if (name.is_register() && (name.reg().is(edx) || name.reg().is(eax))) {
+    if (!is_used(ecx)) {
+      name.ToRegister(ecx);
+    } else if (!is_used(ebx)) {
+      name.ToRegister(ebx);
+    } else {
+ ASSERT(!is_used(edi)); // Only three results are live, so edi is free.
+      name.ToRegister(edi);
+    }
+  }
+ // Now name is not in edx or eax, so we can fix them, then move name to ecx.
+  if (value.is_register() && value.reg().is(edx)) {
+    if (receiver.is_register() && receiver.reg().is(eax)) {
       // Wrong registers.
-      __ xchg(eax, ecx);
+      __ xchg(eax, edx);
     } else {
-      // Register eax is free for value, which frees ecx for name.
+      // Register eax is free for value, which frees edx for receiver.
       value.ToRegister(eax);
-      name.ToRegister(ecx);
+      receiver.ToRegister(edx);
     }
   } else {
-    // Register ecx is free for name, which guarantees eax is free for
+    // Register edx is free for receiver, which guarantees eax is free for
     // value.
-    name.ToRegister(ecx);
+    receiver.ToRegister(edx);
     value.ToRegister(eax);
   }
-
+  // Receiver and value are in the right place, so ecx is free for name.
+  name.ToRegister(ecx);
   name.Unuse();
   value.Unuse();
+  receiver.Unuse();
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to