MIPS: new style of property/function callbacks

Port r14725 (d393d88)

BUG=

Review URL: https://codereview.chromium.org/15562007
Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14736 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
palfia@homejinni.com 2013-05-21 21:09:58 +00:00
parent f74a85f3b7
commit b2729b1b86
3 changed files with 48 additions and 24 deletions

View File

@ -3929,7 +3929,9 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
int stack_space) { int stack_space,
bool returns_handle,
int return_value_offset_from_fp) {
ExternalReference next_address = ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate()); ExternalReference::handle_scope_next_address(isolate());
const int kNextOffset = 0; const int kNextOffset = 0;
@ -3985,15 +3987,20 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
Label promote_scheduled_exception; Label promote_scheduled_exception;
Label delete_allocated_handles; Label delete_allocated_handles;
Label leave_exit_frame; Label leave_exit_frame;
Label return_value_loaded;
// If result is non-zero, dereference to get the result value if (returns_handle) {
// otherwise set it to undefined. Label load_return_value;
Label skip; Branch(&load_return_value, eq, v0, Operand(zero_reg));
LoadRoot(a0, Heap::kUndefinedValueRootIndex); // Dereference returned value.
Branch(&skip, eq, v0, Operand(zero_reg)); lw(v0, MemOperand(v0));
lw(a0, MemOperand(v0)); b(&return_value_loaded);
bind(&skip); nop();
mov(v0, a0); bind(&load_return_value);
}
// Load value from ReturnValue.
lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
bind(&return_value_loaded);
// No more valid handles (the result handle was the last one). Restore // No more valid handles (the result handle was the last one). Restore
// previous handle scope. // previous handle scope.

View File

@ -1237,7 +1237,10 @@ class MacroAssembler: public Assembler {
// from handle and propagates exceptions. Restores context. stack_space // from handle and propagates exceptions. Restores context. stack_space
// - space to be unwound on exit (includes the call JS arguments space and // - space to be unwound on exit (includes the call JS arguments space and
// the additional space allocated for the fast call). // the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function, int stack_space); void CallApiFunctionAndReturn(ExternalReference function,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp);
// Jump to the builtin routine. // Jump to the builtin routine.
void JumpToExternalReference(const ExternalReference& builtin, void JumpToExternalReference(const ExternalReference& builtin,

View File

@ -842,8 +842,7 @@ static void CompileCallLoadPropertyWithInterceptor(
} }
static const int kFastApiCallArguments = 4; static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
// Reserves space for the extra arguments to API function in the // Reserves space for the extra arguments to API function in the
// caller's frame. // caller's frame.
@ -872,10 +871,11 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// -- sp[4] : callee JS function // -- sp[4] : callee JS function
// -- sp[8] : call data // -- sp[8] : call data
// -- sp[12] : isolate // -- sp[12] : isolate
// -- sp[16] : last JS argument // -- sp[16] : ReturnValue
// -- sp[20] : last JS argument
// -- ... // -- ...
// -- sp[(argc + 3) * 4] : first JS argument // -- sp[(argc + 4) * 4] : first JS argument
// -- sp[(argc + 4) * 4] : receiver // -- sp[(argc + 5) * 4] : receiver
// ----------------------------------- // -----------------------------------
// Get the function and setup the context. // Get the function and setup the context.
Handle<JSFunction> function = optimization.constant_function(); Handle<JSFunction> function = optimization.constant_function();
@ -893,13 +893,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
} }
__ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate())));
// Store JS function, call data and isolate. // Store JS function, call data, isolate and ReturnValue.
__ sw(t1, MemOperand(sp, 1 * kPointerSize)); __ sw(t1, MemOperand(sp, 1 * kPointerSize));
__ sw(t2, MemOperand(sp, 2 * kPointerSize)); __ sw(t2, MemOperand(sp, 2 * kPointerSize));
__ sw(t3, MemOperand(sp, 3 * kPointerSize)); __ sw(t3, MemOperand(sp, 3 * kPointerSize));
__ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
__ sw(t1, MemOperand(sp, 4 * kPointerSize));
// Prepare arguments. // Prepare arguments.
__ Addu(a2, sp, Operand(3 * kPointerSize)); __ Addu(a2, sp, Operand(4 * kPointerSize));
// Allocate the v8::Arguments structure in the arguments' space since // Allocate the v8::Arguments structure in the arguments' space since
// it's not controlled by GC. // it's not controlled by GC.
@ -930,13 +932,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
Address function_address = v8::ToCData<Address>(api_call_info->callback()); Address function_address = v8::ToCData<Address>(api_call_info->callback());
bool returns_handle =
!CallbackTable::ReturnsVoid(masm->isolate(), function_address);
ApiFunction fun(function_address); ApiFunction fun(function_address);
ExternalReference ref = ExternalReference ref =
ExternalReference(&fun, ExternalReference(&fun,
ExternalReference::DIRECT_API_CALL, ExternalReference::DIRECT_API_CALL,
masm->isolate()); masm->isolate());
AllowExternalCallThatCantCauseGC scope(masm); AllowExternalCallThatCantCauseGC scope(masm);
__ CallApiFunctionAndReturn(ref, kStackUnwindSpace); __ CallApiFunctionAndReturn(ref,
kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1);
} }
class CallInterceptorCompiler BASE_EMBEDDED { class CallInterceptorCompiler BASE_EMBEDDED {
@ -1410,12 +1417,14 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
} else { } else {
__ li(scratch3(), Handle<Object>(callback->data(), isolate())); __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
} }
__ Subu(sp, sp, 4 * kPointerSize); __ Subu(sp, sp, 5 * kPointerSize);
__ sw(reg, MemOperand(sp, 3 * kPointerSize)); __ sw(reg, MemOperand(sp, 4 * kPointerSize));
__ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
__ li(scratch3(), __ li(scratch3(),
Operand(ExternalReference::isolate_address(isolate()))); Operand(ExternalReference::isolate_address(isolate())));
__ sw(scratch3(), MemOperand(sp, 1 * kPointerSize)); __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex);
__ sw(scratch3(), MemOperand(sp, 2 * kPointerSize));
__ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
__ sw(name(), MemOperand(sp, 0 * kPointerSize)); __ sw(name(), MemOperand(sp, 0 * kPointerSize));
__ mov(a2, scratch2()); // Saved in case scratch2 == a1. __ mov(a2, scratch2()); // Saved in case scratch2 == a1.
@ -1436,12 +1445,17 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
// a2 (second argument - see note above) = AccessorInfo& // a2 (second argument - see note above) = AccessorInfo&
__ Addu(a2, sp, kPointerSize); __ Addu(a2, sp, kPointerSize);
const int kStackUnwindSpace = 5; const int kStackUnwindSpace = kFastApiCallArguments + 1;
Address getter_address = v8::ToCData<Address>(callback->getter()); Address getter_address = v8::ToCData<Address>(callback->getter());
bool returns_handle =
!CallbackTable::ReturnsVoid(isolate(), getter_address);
ApiFunction fun(getter_address); ApiFunction fun(getter_address);
ExternalReference ref = ExternalReference( ExternalReference ref = ExternalReference(
&fun, ExternalReference::DIRECT_GETTER_CALL, isolate()); &fun, ExternalReference::DIRECT_GETTER_CALL, isolate());
__ CallApiFunctionAndReturn(ref, kStackUnwindSpace); __ CallApiFunctionAndReturn(ref,
kStackUnwindSpace,
returns_handle,
3);
} }