Remove VirtualFrame::CallStoreIC(void) and CallCommonStoreIC from virtual-frame-x64...
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 21 Jul 2010 15:16:01 +0000 (15:16 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 21 Jul 2010 15:16:01 +0000 (15:16 +0000)
Review URL: http://codereview.chromium.org/3060002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5113 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/x64/codegen-x64.cc
src/x64/virtual-frame-x64.cc
src/x64/virtual-frame-x64.h

index 4440354..c49ac89 100644 (file)
@@ -4840,8 +4840,13 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
           // 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
index bdff5a9..b8b008c 100644 (file)
@@ -997,60 +997,60 @@ void VirtualFrame::SyncRange(int begin, int end) {
 }
 
 
-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());
+  return result;
 }
-#endif
 
 
 // This function assumes that the only results that could be in a_reg or b_reg
@@ -1107,83 +1107,82 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
 
 
 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);
+      value.ToRegister(rax);
     }
-    MoveResultsToRegisters(key, receiver, rcx, rdx);
-    value->Unuse();
+    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);
+      key.ToRegister(rcx);
     }
-    MoveResultsToRegisters(value, receiver, rax, rdx);
-    key->Unuse();
+    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);
+      receiver.ToRegister(rdx);
     }
-    MoveResultsToRegisters(key, value, rcx, rax);
-    receiver->Unuse();
+    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);
+    key.Unuse();
+    receiver.Unuse();
   }
-  __ Move(rcx, name);
+
+  Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }
 
index 05af957..0479ff0 100644 (file)
@@ -329,50 +329,27 @@ class VirtualFrame : public ZoneObject {
                        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,