Reviewers: Paul Lind, dcarney, danno, kisg, kilvadyb,
Description:
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=
Please review this at https://codereview.chromium.org/15813005/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/mips/macro-assembler-mips.cc
M src/mips/simulator-mips.cc
M src/mips/stub-cache-mips.cc
Index: src/mips/macro-assembler-mips.cc
diff --git a/src/mips/macro-assembler-mips.cc
b/src/mips/macro-assembler-mips.cc
index
e3c8b33a95d2607c34be590e8af67574a24d600b..2e1dea8f043fad7011fdb6b917d3d31f5a7bccb5
100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3944,7 +3944,9 @@ void
MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
// (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).
Index: src/mips/simulator-mips.cc
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index
18e78a5abda9921a281763a1d4899281c7b1ecfc..baf042c3b2191d0db70fd7e22b25228ff120f26f
100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1387,12 +1387,19 @@ typedef double (*SimulatorRuntimeFPIntCall)(double
darg0, int32_t arg0);
// 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 @@ void Simulator::SoftwareInterrupt(Instruction*
instr) {
} 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 =
Index: src/mips/stub-cache-mips.cc
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index
d95f3becb6559db0479c7b6049dd9bb8ceb431de..7e7a3f77e6fe4948e441d4a73490fea612e2a262
100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -924,28 +924,31 @@ static void GenerateFastApiDirectCall(MacroAssembler*
masm,
// 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 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
__ 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 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
// 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.