Revision: 5113
Author: [email protected]
Date: Wed Jul 21 08:16:01 2010
Log: Remove VirtualFrame::CallStoreIC(void) and CallCommonStoreIC from virtual-frame-x64.cc. Make implementations of CallStoreIC(key, is_contextual) and CallKeyedStoreIC() the same on x64 and ia32. Make ia32 and x64 implementations more alike by moving some functions and changing comments.
Review URL: http://codereview.chromium.org/3060002
http://code.google.com/p/v8/source/detail?r=5113

Modified:
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/virtual-frame-x64.cc
 /branches/bleeding_edge/src/x64/virtual-frame-x64.h

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Jul 21 04:52:57 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Jul 21 08:16:01 2010
@@ -4840,8 +4840,13 @@
           // Duplicate the object as the IC receiver.
           frame_->Dup();
           Load(property->value());
-          frame_->Push(key);
-          Result ignored = frame_->CallStoreIC();
+ Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
+          // A test eax instruction following the store IC call would
+          // indicate the presence of an inlined version of the
+          // store. Add a nop to indicate that there is no such
+          // inlined version.
+          __ nop();
+          dummy.Unuse();
           break;
         }
         // Fall through
=======================================
--- /branches/bleeding_edge/src/x64/virtual-frame-x64.cc Wed Jul 21 03:31:52 2010 +++ /branches/bleeding_edge/src/x64/virtual-frame-x64.cc Wed Jul 21 08:16:01 2010
@@ -997,60 +997,60 @@
 }


-Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
-                                   InvokeFlag flag,
-                                   int arg_count) {
+//------------------------------------------------------------------------------
+// Virtual frame stub and IC calling functions.
+
+Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
   PrepareForCall(arg_count, arg_count);
   ASSERT(cgen()->HasValidEntryRegisters());
-  __ InvokeBuiltin(id, flag);
+  __ CallRuntime(f, arg_count);
   Result result = cgen()->allocator()->Allocate(rax);
   ASSERT(result.is_valid());
   return result;
 }


-//------------------------------------------------------------------------------
-// Virtual frame stub and IC calling functions.
-
-Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
-                                       RelocInfo::Mode rmode) {
+Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
+  PrepareForCall(arg_count, arg_count);
   ASSERT(cgen()->HasValidEntryRegisters());
-  __ Call(code, rmode);
+  __ CallRuntime(id, arg_count);
   Result result = cgen()->allocator()->Allocate(rax);
   ASSERT(result.is_valid());
   return result;
 }


-Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
-  PrepareForCall(arg_count, arg_count);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+  PrepareForCall(0, 0);
   ASSERT(cgen()->HasValidEntryRegisters());
-  __ CallRuntime(f, arg_count);
+  __ DebugBreak();
   Result result = cgen()->allocator()->Allocate(rax);
   ASSERT(result.is_valid());
-  return result;
-}
+}
+#endif


-Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
+Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
+                                   InvokeFlag flag,
+                                   int arg_count) {
   PrepareForCall(arg_count, arg_count);
   ASSERT(cgen()->HasValidEntryRegisters());
-  __ CallRuntime(id, arg_count);
+  __ InvokeBuiltin(id, flag);
   Result result = cgen()->allocator()->Allocate(rax);
   ASSERT(result.is_valid());
   return result;
 }


-#ifdef ENABLE_DEBUGGER_SUPPORT
-void VirtualFrame::DebugBreak() {
-  PrepareForCall(0, 0);
+Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
+                                       RelocInfo::Mode rmode) {
   ASSERT(cgen()->HasValidEntryRegisters());
-  __ DebugBreak();
+  __ Call(code, rmode);
   Result result = cgen()->allocator()->Allocate(rax);
   ASSERT(result.is_valid());
-}
-#endif
+  return result;
+}


// This function assumes that the only results that could be in a_reg or b_reg
@@ -1107,83 +1107,82 @@


 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
-  // Key and receiver are on top of the frame.  The IC expects them on
-  // the stack.  It does not drop them.
-  Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
-  Result name = Pop();
+  // Key and receiver are on top of the frame. Put them in rax and rdx.
+  Result key = Pop();
   Result receiver = Pop();
   PrepareForCall(0, 0);
-  MoveResultsToRegisters(&name, &receiver, rax, rdx);
+  MoveResultsToRegisters(&key, &receiver, rax, rdx);
+
+  Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
   return RawCallCodeObject(ic, mode);
 }


-Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic,
-                                       Result* value,
-                                       Result* key,
-                                       Result* receiver) {
-  // The IC expects value in rax, key in rcx, and receiver in rdx.
+Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
+  // Value and (if not contextual) receiver are on top of the frame.
+  // The IC expects name in rcx, value in rax, and receiver in rdx.
+  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+  Result value = Pop();
+  if (is_contextual) {
+    PrepareForCall(0, 0);
+    value.ToRegister(rax);
+    __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+    value.Unuse();
+  } else {
+    Result receiver = Pop();
+    PrepareForCall(0, 0);
+    MoveResultsToRegisters(&value, &receiver, rax, rdx);
+  }
+  __ Move(rcx, name);
+  return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
+}
+
+
+Result VirtualFrame::CallKeyedStoreIC() {
+  // Value, key, and receiver are on the top of the frame.  The IC
+  // expects value in rax, key in rcx, and receiver in rdx.
+  Result value = Pop();
+  Result key = Pop();
+  Result receiver = Pop();
   PrepareForCall(0, 0);
-  // If one of the three registers is free, or a value is already
-  // in the correct register, move the remaining two values using
-  // MoveResultsToRegisters().
   if (!cgen()->allocator()->is_used(rax) ||
-      (value->is_register() && value->reg().is(rax))) {
+      (value.is_register() && value.reg().is(rax))) {
     if (!cgen()->allocator()->is_used(rax)) {
-      value->ToRegister(rax);
-    }
-    MoveResultsToRegisters(key, receiver, rcx, rdx);
-    value->Unuse();
+      value.ToRegister(rax);
+    }
+    MoveResultsToRegisters(&key, &receiver, rcx, rdx);
+    value.Unuse();
   } else if (!cgen()->allocator()->is_used(rcx) ||
-             (key->is_register() && key->reg().is(rcx))) {
+             (key.is_register() && key.reg().is(rcx))) {
     if (!cgen()->allocator()->is_used(rcx)) {
-      key->ToRegister(rcx);
-    }
-    MoveResultsToRegisters(value, receiver, rax, rdx);
-    key->Unuse();
+      key.ToRegister(rcx);
+    }
+    MoveResultsToRegisters(&value, &receiver, rax, rdx);
+    key.Unuse();
   } else if (!cgen()->allocator()->is_used(rdx) ||
-             (receiver->is_register() && receiver->reg().is(rdx))) {
+             (receiver.is_register() && receiver.reg().is(rdx))) {
     if (!cgen()->allocator()->is_used(rdx)) {
-      receiver->ToRegister(rdx);
-    }
-    MoveResultsToRegisters(key, value, rcx, rax);
-    receiver->Unuse();
+      receiver.ToRegister(rdx);
+    }
+    MoveResultsToRegisters(&key, &value, rcx, rax);
+    receiver.Unuse();
   } else {
- // Otherwise, no register is free, and no value is in the correct place.
-    // We have one of the two circular permutations of eax, ecx, edx.
-    ASSERT(value->is_register());
-    if (value->reg().is(rcx)) {
+    // All three registers are used, and no value is in the correct place.
+    // We have one of the two circular permutations of rax, rcx, rdx.
+    ASSERT(value.is_register());
+    if (value.reg().is(rcx)) {
       __ xchg(rax, rdx);
       __ xchg(rax, rcx);
     } else {
       __ xchg(rax, rcx);
       __ xchg(rax, rdx);
     }
-    value->Unuse();
-    key->Unuse();
-    receiver->Unuse();
-  }
-
-  return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
-}
-
-
-Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
-  // Value and (if not contextual) receiver are on top of the frame.
-  // The IC expects name in rcx, value in rax, and receiver in rdx.
-  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-  Result value = Pop();
-  if (is_contextual) {
-    PrepareForCall(0, 0);
-    value.ToRegister(rax);
-    __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
     value.Unuse();
-  } else {
-    Result receiver = Pop();
-    PrepareForCall(0, 0);
-    MoveResultsToRegisters(&value, &receiver, rax, rdx);
-  }
-  __ Move(rcx, name);
+    key.Unuse();
+    receiver.Unuse();
+  }
+
+  Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }

=======================================
--- /branches/bleeding_edge/src/x64/virtual-frame-x64.h Wed Jul 21 03:31:52 2010 +++ /branches/bleeding_edge/src/x64/virtual-frame-x64.h Wed Jul 21 08:16:01 2010
@@ -329,50 +329,27 @@
                        int arg_count);

   // Call load IC.  Name and receiver are found on top of the frame.
-  // Receiver is not dropped.
+  // Both are dropped.
   Result CallLoadIC(RelocInfo::Mode mode);

   // Call keyed load IC.  Key and receiver are found on top of the
-  // frame.  They are not dropped.
+  // frame.  Both are dropped.
   Result CallKeyedLoadIC(RelocInfo::Mode mode);
-
-
- // Calling a store IC and a keyed store IC differ only by which ic is called
-  // and by the order of the three arguments on the frame.
-  Result CallCommonStoreIC(Handle<Code> ic,
-                           Result* value,
-                           Result* key,
-                           Result* receiver);
-
-  // Call store IC.  Name, value, and receiver are found on top
-  // of the frame.  All are dropped.
-  Result CallStoreIC() {
-    Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-    Result name = Pop();
-    Result value = Pop();
-    Result receiver = Pop();
-    return CallCommonStoreIC(ic, &value, &name, &receiver);
-  }

// Call store IC. If the load is contextual, value is found on top of the // frame. If not, value and receiver are on the frame. Both are dropped.
   Result CallStoreIC(Handle<String> name, bool is_contextual);

   // Call keyed store IC.  Value, key, and receiver are found on top
-  // of the frame.  All are dropped.
-  Result CallKeyedStoreIC() {
-    Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
-    Result value = Pop();
-    Result key = Pop();
-    Result receiver = Pop();
-    return CallCommonStoreIC(ic, &value, &key, &receiver);
-  }
+  // of the frame.  All three are dropped.
+  Result CallKeyedStoreIC();

   // Call call IC.  Function name, arguments, and receiver are found on top
   // of the frame and dropped by the call.
   // The argument count does not include the receiver.
   Result CallCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);

+  // Call keyed call IC.  Same calling convention as CallCallIC.
Result CallKeyedCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);

   // Allocate and call JS function as constructor.  Arguments,

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

Reply via email to