Commit 03644ab8 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: cleanup api callbacks now that handles are never returned directly

Port r16360 (72401868)

BUG=

Review URL: https://codereview.chromium.org/23604004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16373 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 42b63dcb
...@@ -3963,7 +3963,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, ...@@ -3963,7 +3963,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
ExternalReference thunk_ref, ExternalReference thunk_ref,
Register thunk_last_arg, Register thunk_last_arg,
int stack_space, int stack_space,
bool returns_handle,
int return_value_offset_from_fp) { int return_value_offset_from_fp) {
ExternalReference next_address = ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate()); ExternalReference::handle_scope_next_address(isolate());
...@@ -3992,14 +3991,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, ...@@ -3992,14 +3991,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
PopSafepointRegisters(); PopSafepointRegisters();
} }
// The O32 ABI requires us to pass a pointer in a0 where the returned struct
// (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.
if (returns_handle) {
addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
}
Label profiler_disabled; Label profiler_disabled;
Label end_profiler_check; Label end_profiler_check;
bool* is_profiling_flag = bool* is_profiling_flag =
...@@ -4039,19 +4030,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, ...@@ -4039,19 +4030,6 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
Label leave_exit_frame; Label leave_exit_frame;
Label return_value_loaded; Label return_value_loaded;
if (returns_handle) {
Label load_return_value;
// As mentioned above, on MIPS a pointer is returned - we need to
// dereference it to get the actual return value (which is also a pointer).
lw(v0, MemOperand(v0));
Branch(&load_return_value, eq, v0, Operand(zero_reg));
// Dereference returned value.
lw(v0, MemOperand(v0));
Branch(&return_value_loaded);
bind(&load_return_value);
}
// Load value from ReturnValue. // Load value from ReturnValue.
lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize)); lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
bind(&return_value_loaded); bind(&return_value_loaded);
......
...@@ -1233,7 +1233,6 @@ class MacroAssembler: public Assembler { ...@@ -1233,7 +1233,6 @@ class MacroAssembler: public Assembler {
ExternalReference thunk_ref, ExternalReference thunk_ref,
Register thunk_last_arg, Register thunk_last_arg,
int stack_space, int stack_space,
bool returns_handle,
int return_value_offset_from_fp); int return_value_offset_from_fp);
// Jump to the builtin routine. // Jump to the builtin routine.
......
...@@ -1387,27 +1387,12 @@ typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0); ...@@ -1387,27 +1387,12 @@ typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
// This signature supports direct call in to API function native callback // This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h). // (refer to InvocationCallback in v8.h).
// NOTE: the O32 abi requires a0 to hold a special pointer when returning a typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
// struct from the function (which is currently the case). This means we pass typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
// 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);
typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
int32_t arg0, int32_t arg1);
typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback. // This signature supports direct call to accessor getter callback.
// See comment at SimulatorRuntimeDirectApiCall. typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, typedef void (*SimulatorRuntimeProfilingGetterCall)(
int32_t arg1);
// See comment at SimulatorRuntimeDirectApiCallNew.
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
int32_t arg1);
typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
int32_t arg0, int32_t arg1, int32_t arg2);
typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
int32_t arg0, int32_t arg1, int32_t arg2); int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the // Software interrupt instructions are used by the simulator to call into the
...@@ -1553,102 +1538,41 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { ...@@ -1553,102 +1538,41 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
break; break;
} }
} }
} else if ( } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
redirection->type() == ExternalReference::DIRECT_API_CALL || if (::v8::internal::FLAG_trace_sim) {
redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) { PrintF("Call to host function at %p args %08x\n",
if (redirection->type() == ExternalReference::DIRECT_API_CALL) { reinterpret_cast<void*>(external), arg0);
// 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(arg0);
} }
SimulatorRuntimeDirectApiCall target =
reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
target(arg0);
} else if ( } else if (
redirection->type() == ExternalReference::PROFILING_API_CALL || redirection->type() == ExternalReference::PROFILING_API_CALL) {
redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) { if (::v8::internal::FLAG_trace_sim) {
if (redirection->type() == ExternalReference::PROFILING_API_CALL) { PrintF("Call to host function at %p args %08x %08x\n",
// See comment at type definition of SimulatorRuntimeDirectApiCall reinterpret_cast<void*>(external), arg0, arg1);
// 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);
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(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);
}
SimulatorRuntimeProfilingApiCallNew target =
reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
target(arg0, arg1);
} }
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg0, arg1);
} else if ( } else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL || redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) { if (::v8::internal::FLAG_trace_sim) {
if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { PrintF("Call to host function at %p args %08x %08x\n",
// See comment at type definition of SimulatorRuntimeDirectGetterCall reinterpret_cast<void*>(external), arg0, arg1);
// 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(arg0, arg1);
} }
SimulatorRuntimeDirectGetterCall target =
reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
target(arg0, arg1);
} else if ( } else if (
redirection->type() == ExternalReference::PROFILING_GETTER_CALL || redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) { if (::v8::internal::FLAG_trace_sim) {
if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) { PrintF("Call to host function at %p args %08x %08x %08x\n",
// See comment at type definition of SimulatorRuntimeProfilingGetterCall reinterpret_cast<void*>(external), arg0, arg1, arg2);
// for explanation of register usage.
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08x %08x %08x\n",
reinterpret_cast<void*>(external), arg1, arg2, arg3);
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
v8::Handle<v8::Value> result = target(arg1, arg2, arg3);
*(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 %08x\n",
reinterpret_cast<void*>(external), arg0, arg1, arg2);
}
SimulatorRuntimeProfilingGetterCallNew target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(external);
target(arg0, arg1, arg2);
} }
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, arg2);
} else { } else {
SimulatorRuntimeCall target = SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external); reinterpret_cast<SimulatorRuntimeCall>(external);
......
...@@ -879,49 +879,31 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, ...@@ -879,49 +879,31 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
FrameScope frame_scope(masm, StackFrame::MANUAL); FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace); __ EnterExitFrame(false, kApiStackSpace);
// NOTE: the O32 abi requires a0 to hold a special pointer when returning a // a0 = v8::Arguments&
// struct from the function (which is currently the case). This means we pass
// the first argument in a1 instead of a0, if returns_handle is true.
// CallApiFunctionAndReturn will set up a0.
Address function_address = v8::ToCData<Address>(api_call_info->callback());
// TODO(dcarney): fix signatures using returns_handle
const bool returns_handle = false;
Register first_arg = returns_handle ? a1 : a0;
Register second_arg = returns_handle ? a2 : a1;
// first_arg = v8::Arguments&
// Arguments is built at sp + 1 (sp is a reserved spot for ra). // Arguments is built at sp + 1 (sp is a reserved spot for ra).
__ Addu(first_arg, sp, kPointerSize); __ Addu(a0, sp, kPointerSize);
// v8::Arguments::implicit_args_ // v8::Arguments::implicit_args_
__ sw(a2, MemOperand(first_arg, 0 * kPointerSize)); __ sw(a2, MemOperand(a0, 0 * kPointerSize));
// v8::Arguments::values_ // v8::Arguments::values_
__ Addu(t0, a2, Operand(argc * kPointerSize)); __ Addu(t0, a2, Operand(argc * kPointerSize));
__ sw(t0, MemOperand(first_arg, 1 * kPointerSize)); __ sw(t0, MemOperand(a0, 1 * kPointerSize));
// v8::Arguments::length_ = argc // v8::Arguments::length_ = argc
__ li(t0, Operand(argc)); __ li(t0, Operand(argc));
__ sw(t0, MemOperand(first_arg, 2 * kPointerSize)); __ sw(t0, MemOperand(a0, 2 * kPointerSize));
// v8::Arguments::is_construct_call = 0 // v8::Arguments::is_construct_call = 0
__ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize)); __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
Address function_address = v8::ToCData<Address>(api_call_info->callback());
ApiFunction fun(function_address); ApiFunction fun(function_address);
ExternalReference::Type type = ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
returns_handle ?
ExternalReference::DIRECT_API_CALL :
ExternalReference::DIRECT_API_CALL_NEW;
ExternalReference ref = ExternalReference ref =
ExternalReference(&fun, ExternalReference(&fun,
type, type,
masm->isolate()); masm->isolate());
Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
ExternalReference::Type thunk_type = ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
returns_handle ?
ExternalReference::PROFILING_API_CALL :
ExternalReference::PROFILING_API_CALL_NEW;
ApiFunction thunk_fun(thunk_address); ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
masm->isolate()); masm->isolate());
...@@ -930,9 +912,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, ...@@ -930,9 +912,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
__ CallApiFunctionAndReturn(ref, __ CallApiFunctionAndReturn(ref,
function_address, function_address,
thunk_ref, thunk_ref,
second_arg, a1,
kStackUnwindSpace, kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1); kFastApiCallArguments + 1);
} }
...@@ -1417,21 +1398,8 @@ void BaseLoadStubCompiler::GenerateLoadCallback( ...@@ -1417,21 +1398,8 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
__ sw(scratch4(), MemOperand(sp, 1 * kPointerSize)); __ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
__ sw(name(), MemOperand(sp, 0 * kPointerSize)); __ sw(name(), MemOperand(sp, 0 * kPointerSize));
Address getter_address = v8::ToCData<Address>(callback->getter());
// TODO(dcarney): fix signatures using returns_handle
const bool returns_handle = false;
Register first_arg = returns_handle ? a1 : a0;
Register second_arg = returns_handle ? a2 : a1;
Register third_arg = returns_handle ? a3 : a2;
__ mov(a2, scratch2()); // Saved in case scratch2 == a1. __ mov(a2, scratch2()); // Saved in case scratch2 == a1.
__ mov(first_arg, sp); // (first argument - see note below) = Handle<Name> __ mov(a0, sp); // (first argument - a0) = 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, if returns_handle is true.
// CallApiFunctionAndReturn will set up a0.
const int kApiStackSpace = 1; const int kApiStackSpace = 1;
FrameScope frame_scope(masm(), StackFrame::MANUAL); FrameScope frame_scope(masm(), StackFrame::MANUAL);
...@@ -1440,30 +1408,26 @@ void BaseLoadStubCompiler::GenerateLoadCallback( ...@@ -1440,30 +1408,26 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
// Create AccessorInfo instance on the stack above the exit frame with // Create AccessorInfo instance on the stack above the exit frame with
// scratch2 (internal::Object** args_) as the data. // scratch2 (internal::Object** args_) as the data.
__ sw(a2, MemOperand(sp, kPointerSize)); __ sw(a2, MemOperand(sp, kPointerSize));
// (second argument - see note above) = AccessorInfo& // (second argument - a1) = AccessorInfo&
__ Addu(second_arg, sp, kPointerSize); __ Addu(a1, sp, kPointerSize);
const int kStackUnwindSpace = kFastApiCallArguments + 1; const int kStackUnwindSpace = kFastApiCallArguments + 1;
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address); ApiFunction fun(getter_address);
ExternalReference::Type type = ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
returns_handle ?
ExternalReference::DIRECT_GETTER_CALL :
ExternalReference::DIRECT_GETTER_CALL_NEW;
ExternalReference ref = ExternalReference(&fun, type, isolate()); ExternalReference ref = ExternalReference(&fun, type, isolate());
Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
ExternalReference::Type thunk_type = ExternalReference::Type thunk_type =
ExternalReference::PROFILING_GETTER_CALL_NEW; ExternalReference::PROFILING_GETTER_CALL;
ApiFunction thunk_fun(thunk_address); ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
isolate()); isolate());
__ CallApiFunctionAndReturn(ref, __ CallApiFunctionAndReturn(ref,
getter_address, getter_address,
thunk_ref, thunk_ref,
third_arg, a2,
kStackUnwindSpace, kStackUnwindSpace,
returns_handle,
5); 5);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment