Revision: 14813
Author:   [email protected]
Date:     Sat May 25 10:10:42 2013
Log:      MIPS: Fix DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW call.

This commit fixes the register usage of DIRECT_API_CALL_NEW
and DIRECT_GETTER_CALL_NEW:

* These functions expect arguments in a0-a1 and not in a1-a2
  as the and DIRECT_API_CALL and DIRECT_GETTER_CALL do.
* Fixes the simulator to expect *_NEW arguments in a0-a1.
* Adds more comment to simulator to better explain the
  register usage.

TEST=cctest/test-api/LoadICFastApi_DirectCall_GCMoveStub,cctest/test-api/SimpleCallback

BUG=

Review URL: https://codereview.chromium.org/15813005
http://code.google.com/p/v8/source/detail?r=14813

Modified:
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/mips/simulator-mips.cc
 /branches/bleeding_edge/src/mips/stub-cache-mips.cc

=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Thu May 23 18:05:42 2013 +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Sat May 25 10:10:42 2013
@@ -3944,7 +3944,9 @@
   // (4 bytes) will be placed. This is also built into the Simulator.
   // Set up the pointer to the returned value (a0). It was allocated in
   // EnterExitFrame.
-  addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
+  if (returns_handle) {
+    addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
+  }

   // Native call returns to the DirectCEntry stub which redirects to the
   // return address pushed on stack (could have moved after GC).
=======================================
--- /branches/bleeding_edge/src/mips/simulator-mips.cc Tue May 21 16:09:04 2013 +++ /branches/bleeding_edge/src/mips/simulator-mips.cc Sat May 25 10:10:42 2013
@@ -1387,12 +1387,19 @@

 // This signature supports direct call in to API function native callback
 // (refer to InvocationCallback in v8.h).
+// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
+// struct from the function (which is currently the case). This means we pass
+// the first argument in a1 instead of a0.
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
+// Here, we pass the first argument in a0, because this function
+// does not return a struct.
 typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);

 // This signature supports direct call to accessor getter callback.
+// See comment at SimulatorRuntimeDirectApiCall.
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
+// See comment at SimulatorRuntimeDirectApiCallNew.
 typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
                                                     int32_t arg1);

@@ -1542,40 +1549,50 @@
     } else if (
         redirection->type() == ExternalReference::DIRECT_API_CALL ||
         redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
- // See DirectCEntryStub::GenerateCall for explanation of register usage.
-      if (::v8::internal::FLAG_trace_sim) {
-        PrintF("Call to host function at %p args %08x\n",
-            reinterpret_cast<void*>(external), arg1);
-      }
       if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
+        // See comment at type definition of SimulatorRuntimeDirectApiCall
+        // for explanation of register usage.
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Call to host function at %p args %08x\n",
+              reinterpret_cast<void*>(external), arg1);
+        }
         SimulatorRuntimeDirectApiCall target =
             reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
         v8::Handle<v8::Value> result = target(arg1);
*(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
         set_register(v0, arg0);
       } else {
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Call to host function at %p args %08x\n",
+              reinterpret_cast<void*>(external), arg0);
+        }
         SimulatorRuntimeDirectApiCallNew target =
             reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
-        target(arg1);
+        target(arg0);
       }
     } else if (
         redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
         redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
- // See DirectCEntryStub::GenerateCall for explanation of register usage.
-      if (::v8::internal::FLAG_trace_sim) {
-        PrintF("Call to host function at %p args %08x %08x\n",
-            reinterpret_cast<void*>(external), arg1, arg2);
-      }
       if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
+ // See comment at type definition of SimulatorRuntimeDirectGetterCall
+        // for explanation of register usage.
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Call to host function at %p args %08x %08x\n",
+              reinterpret_cast<void*>(external), arg1, arg2);
+        }
         SimulatorRuntimeDirectGetterCall target =
             reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
         v8::Handle<v8::Value> result = target(arg1, arg2);
*(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
         set_register(v0, arg0);
       } else {
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Call to host function at %p args %08x %08x\n",
+              reinterpret_cast<void*>(external), arg0, arg1);
+        }
         SimulatorRuntimeDirectGetterCallNew target =
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
-        target(arg1, arg2);
+        target(arg0, arg1);
       }
     } else {
       SimulatorRuntimeCall target =
=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu May 23 18:05:42 2013 +++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Sat May 25 10:10:42 2013
@@ -924,28 +924,31 @@

// NOTE: the O32 abi requires a0 to hold a special pointer when returning a // struct from the function (which is currently the case). This means we pass
-  // the first argument in a1 instead of a0. TryCallApiFunctionAndReturn
-  // will handle setting up a0.
+  // the first argument in a1 instead of a0, if returns_handle is true.
+  // CallApiFunctionAndReturn will set up a0.

-  // a1 = v8::Arguments&
+ Address function_address = v8::ToCData<Address>(api_call_info->callback());
+  bool returns_handle =
+      !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
+
+  Register first_arg = returns_handle ? a1 : a0;
+
+  // first_arg = v8::Arguments&
   // Arguments is built at sp + 1 (sp is a reserved spot for ra).
-  __ Addu(a1, sp, kPointerSize);
+  __ Addu(first_arg, sp, kPointerSize);

   // v8::Arguments::implicit_args_
-  __ sw(a2, MemOperand(a1, 0 * kPointerSize));
+  __ sw(a2, MemOperand(first_arg, 0 * kPointerSize));
   // v8::Arguments::values_
   __ Addu(t0, a2, Operand(argc * kPointerSize));
-  __ sw(t0, MemOperand(a1, 1 * kPointerSize));
+  __ sw(t0, MemOperand(first_arg, 1 * kPointerSize));
   // v8::Arguments::length_ = argc
   __ li(t0, Operand(argc));
-  __ sw(t0, MemOperand(a1, 2 * kPointerSize));
+  __ sw(t0, MemOperand(first_arg, 2 * kPointerSize));
   // v8::Arguments::is_construct_call = 0
-  __ sw(zero_reg, MemOperand(a1, 3 * kPointerSize));
+  __ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize));

   const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
- Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
   ApiFunction fun(function_address);
   ExternalReference::Type type =
       returns_handle ?
@@ -1442,13 +1445,20 @@
   __ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
   __ sw(name(), MemOperand(sp, 0 * kPointerSize));

+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  bool returns_handle =
+      !CallbackTable::ReturnsVoid(isolate(), getter_address);
+
+  Register first_arg = returns_handle ? a1 : a0;
+  Register second_arg = returns_handle ? a2 : a1;
+
   __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
-  __ mov(a1, sp);  // a1 (first argument - see note below) = Handle<Name>
+ __ mov(first_arg, sp); // (first argument - see note below) = Handle<Name>

// NOTE: the O32 abi requires a0 to hold a special pointer when returning a // struct from the function (which is currently the case). This means we pass
-  // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn
-  // will handle setting up a0.
+  // the arguments in a1-a2 instead of a0-a1, if returns_handle is true.
+  // CallApiFunctionAndReturn will set up a0.

   const int kApiStackSpace = 1;
   FrameScope frame_scope(masm(), StackFrame::MANUAL);
@@ -1457,13 +1467,10 @@
   // Create AccessorInfo instance on the stack above the exit frame with
   // scratch2 (internal::Object** args_) as the data.
   __ sw(a2, MemOperand(sp, kPointerSize));
-  // a2 (second argument - see note above) = AccessorInfo&
-  __ Addu(a2, sp, kPointerSize);
+  // (second argument - see note above) = AccessorInfo&
+  __ Addu(second_arg, sp, kPointerSize);

   const int kStackUnwindSpace = kFastApiCallArguments + 1;
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  bool returns_handle =
-      !CallbackTable::ReturnsVoid(isolate(), getter_address);
   ApiFunction fun(getter_address);
   ExternalReference::Type type =
       returns_handle ?

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to