From b2729b1b8674f75755a03fab067dfc8c4b773d79 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Tue, 21 May 2013 21:09:58 +0000 Subject: [PATCH] MIPS: new style of property/function callbacks Port r14725 (d393d88) BUG= Review URL: https://codereview.chromium.org/15562007 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14736 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/macro-assembler-mips.cc | 25 ++++++++++++------- src/mips/macro-assembler-mips.h | 5 +++- src/mips/stub-cache-mips.cc | 42 +++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index 81e9ec980e..d9d511be02 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -3929,7 +3929,9 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, - int stack_space) { + int stack_space, + bool returns_handle, + int return_value_offset_from_fp) { ExternalReference next_address = ExternalReference::handle_scope_next_address(isolate()); const int kNextOffset = 0; @@ -3985,15 +3987,20 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, Label promote_scheduled_exception; Label delete_allocated_handles; Label leave_exit_frame; + Label return_value_loaded; - // If result is non-zero, dereference to get the result value - // otherwise set it to undefined. - Label skip; - LoadRoot(a0, Heap::kUndefinedValueRootIndex); - Branch(&skip, eq, v0, Operand(zero_reg)); - lw(a0, MemOperand(v0)); - bind(&skip); - mov(v0, a0); + if (returns_handle) { + Label load_return_value; + Branch(&load_return_value, eq, v0, Operand(zero_reg)); + // Dereference returned value. + lw(v0, MemOperand(v0)); + b(&return_value_loaded); + nop(); + 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 // previous handle scope. diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 248e5b4bca..6511223aae 100644 --- a/src/mips/macro-assembler-mips.h +++ b/src/mips/macro-assembler-mips.h @@ -1237,7 +1237,10 @@ class MacroAssembler: public Assembler { // from handle and propagates exceptions. Restores context. stack_space // - space to be unwound on exit (includes the call JS arguments space and // 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. void JumpToExternalReference(const ExternalReference& builtin, diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 90ae404d25..8df369e29b 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -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 // caller's frame. @@ -872,10 +871,11 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // -- sp[4] : callee JS function // -- sp[8] : call data // -- 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] : receiver + // -- sp[(argc + 4) * 4] : first JS argument + // -- sp[(argc + 5) * 4] : receiver // ----------------------------------- // Get the function and setup the context. Handle function = optimization.constant_function(); @@ -893,13 +893,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, } __ 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(t2, MemOperand(sp, 2 * kPointerSize)); __ sw(t3, MemOperand(sp, 3 * kPointerSize)); + __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); + __ sw(t1, MemOperand(sp, 4 * kPointerSize)); // Prepare arguments. - __ Addu(a2, sp, Operand(3 * kPointerSize)); + __ Addu(a2, sp, Operand(4 * kPointerSize)); // Allocate the v8::Arguments structure in the arguments' space since // it's not controlled by GC. @@ -930,13 +932,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; Address function_address = v8::ToCData
(api_call_info->callback()); + bool returns_handle = + !CallbackTable::ReturnsVoid(masm->isolate(), function_address); ApiFunction fun(function_address); ExternalReference ref = ExternalReference(&fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); AllowExternalCallThatCantCauseGC scope(masm); - __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); + __ CallApiFunctionAndReturn(ref, + kStackUnwindSpace, + returns_handle, + kFastApiCallArguments + 1); } class CallInterceptorCompiler BASE_EMBEDDED { @@ -1410,12 +1417,14 @@ void BaseLoadStubCompiler::GenerateLoadCallback( } else { __ li(scratch3(), Handle(callback->data(), isolate())); } - __ Subu(sp, sp, 4 * kPointerSize); - __ sw(reg, MemOperand(sp, 3 * kPointerSize)); - __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); + __ Subu(sp, sp, 5 * kPointerSize); + __ sw(reg, MemOperand(sp, 4 * kPointerSize)); + __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); __ li(scratch3(), 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)); __ mov(a2, scratch2()); // Saved in case scratch2 == a1. @@ -1436,12 +1445,17 @@ void BaseLoadStubCompiler::GenerateLoadCallback( // a2 (second argument - see note above) = AccessorInfo& __ Addu(a2, sp, kPointerSize); - const int kStackUnwindSpace = 5; + const int kStackUnwindSpace = kFastApiCallArguments + 1; Address getter_address = v8::ToCData
(callback->getter()); + bool returns_handle = + !CallbackTable::ReturnsVoid(isolate(), getter_address); ApiFunction fun(getter_address); ExternalReference ref = ExternalReference( &fun, ExternalReference::DIRECT_GETTER_CALL, isolate()); - __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); + __ CallApiFunctionAndReturn(ref, + kStackUnwindSpace, + returns_handle, + 3); }