Commit ec52f8df authored by akos.palfi's avatar akos.palfi Committed by Commit bot

MIPS: split api call stubs into accessor and function call stubs

Port 6950ead0

Note: This port has known issues, there are about 40 test failures. The purpose of this commit is to unbreak the MIPS build.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#26116}
parent e9e77212
...@@ -222,20 +222,17 @@ static void CompileCallLoadPropertyWithInterceptor( ...@@ -222,20 +222,17 @@ static void CompileCallLoadPropertyWithInterceptor(
// Generate call to api function. // Generate call to api function.
void PropertyHandlerCompiler::GenerateFastApiCall( void PropertyHandlerCompiler::GenerateApiAccessorCall(
MacroAssembler* masm, const CallOptimization& optimization, MacroAssembler* masm, const CallOptimization& optimization,
Handle<Map> receiver_map, Register receiver, Register scratch_in, Handle<Map> receiver_map, Register receiver, Register scratch_in,
bool is_store, int argc, Register* values) { bool is_store, Register store_parameter) {
DCHECK(!receiver.is(scratch_in)); DCHECK(!receiver.is(scratch_in));
// Preparing to push, adjust sp. __ push(receiver);
__ Subu(sp, sp, Operand((argc + 1) * kPointerSize));
__ sw(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver.
// Write the arguments to stack frame. // Write the arguments to stack frame.
for (int i = 0; i < argc; i++) { if (is_store) {
Register arg = values[argc - 1 - i]; DCHECK(!receiver.is(store_parameter));
DCHECK(!receiver.is(arg)); DCHECK(!scratch_in.is(store_parameter));
DCHECK(!scratch_in.is(arg)); __ push(store_parameter);
__ sw(arg, MemOperand(sp, (argc - 1 - i) * kPointerSize)); // Push arg.
} }
DCHECK(optimization.is_simple_api_call()); DCHECK(optimization.is_simple_api_call());
...@@ -288,7 +285,7 @@ void PropertyHandlerCompiler::GenerateFastApiCall( ...@@ -288,7 +285,7 @@ void PropertyHandlerCompiler::GenerateFastApiCall(
__ li(api_function_address, Operand(ref)); __ li(api_function_address, Operand(ref));
// Jump to stub. // Jump to stub.
CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
__ TailCallStub(&stub); __ TailCallStub(&stub);
} }
......
...@@ -223,20 +223,17 @@ static void CompileCallLoadPropertyWithInterceptor( ...@@ -223,20 +223,17 @@ static void CompileCallLoadPropertyWithInterceptor(
// Generate call to api function. // Generate call to api function.
void PropertyHandlerCompiler::GenerateFastApiCall( void PropertyHandlerCompiler::GenerateApiAccessorCall(
MacroAssembler* masm, const CallOptimization& optimization, MacroAssembler* masm, const CallOptimization& optimization,
Handle<Map> receiver_map, Register receiver, Register scratch_in, Handle<Map> receiver_map, Register receiver, Register scratch_in,
bool is_store, int argc, Register* values) { bool is_store, Register store_parameter) {
DCHECK(!receiver.is(scratch_in)); DCHECK(!receiver.is(scratch_in));
// Preparing to push, adjust sp. __ push(receiver);
__ Dsubu(sp, sp, Operand((argc + 1) * kPointerSize));
__ sd(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver.
// Write the arguments to stack frame. // Write the arguments to stack frame.
for (int i = 0; i < argc; i++) { if (is_store) {
Register arg = values[argc - 1 - i]; DCHECK(!receiver.is(store_parameter));
DCHECK(!receiver.is(arg)); DCHECK(!scratch_in.is(store_parameter));
DCHECK(!scratch_in.is(arg)); __ push(store_parameter);
__ sd(arg, MemOperand(sp, (argc - 1 - i) * kPointerSize)); // Push arg.
} }
DCHECK(optimization.is_simple_api_call()); DCHECK(optimization.is_simple_api_call());
...@@ -289,7 +286,7 @@ void PropertyHandlerCompiler::GenerateFastApiCall( ...@@ -289,7 +286,7 @@ void PropertyHandlerCompiler::GenerateFastApiCall(
__ li(api_function_address, Operand(ref)); __ li(api_function_address, Operand(ref));
// Jump to stub. // Jump to stub.
CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
__ TailCallStub(&stub); __ TailCallStub(&stub);
} }
......
...@@ -4833,12 +4833,16 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { ...@@ -4833,12 +4833,16 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
} }
void CallApiFunctionStub::Generate(MacroAssembler* masm) { static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- a0 : callee // -- a0 : callee
// -- t0 : call_data // -- t0 : call_data
// -- a2 : holder // -- a2 : holder
// -- a1 : api_function_address // -- a1 : api_function_address
// -- a3 : number of arguments if argc is a register
// -- cp : context // -- cp : context
// -- // --
// -- sp[0] : last argument // -- sp[0] : last argument
...@@ -4853,10 +4857,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4853,10 +4857,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
Register api_function_address = a1; Register api_function_address = a1;
Register context = cp; Register context = cp;
int argc = this->argc();
bool is_store = this->is_store();
bool call_data_undefined = this->call_data_undefined();
typedef FunctionCallbackArguments FCA; typedef FunctionCallbackArguments FCA;
STATIC_ASSERT(FCA::kContextSaveIndex == 6); STATIC_ASSERT(FCA::kContextSaveIndex == 6);
...@@ -4868,6 +4868,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4868,6 +4868,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0); STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7); STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
// Save context, callee and call data. // Save context, callee and call data.
__ Push(context, callee, call_data); __ Push(context, callee, call_data);
// Load context from callee. // Load context from callee.
...@@ -4879,8 +4881,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4879,8 +4881,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
} }
// Push return value and default return value. // Push return value and default return value.
__ Push(scratch, scratch); __ Push(scratch, scratch);
__ li(scratch, __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate())));
Operand(ExternalReference::isolate_address(isolate())));
// Push isolate and holder. // Push isolate and holder.
__ Push(scratch, holder); __ Push(scratch, holder);
...@@ -4900,39 +4901,73 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4900,39 +4901,73 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ Addu(a0, sp, Operand(1 * kPointerSize)); __ Addu(a0, sp, Operand(1 * kPointerSize));
// FunctionCallbackInfo::implicit_args_ // FunctionCallbackInfo::implicit_args_
__ sw(scratch, MemOperand(a0, 0 * kPointerSize)); __ sw(scratch, MemOperand(a0, 0 * kPointerSize));
// FunctionCallbackInfo::values_ if (argc.is_immediate()) {
__ Addu(at, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); // FunctionCallbackInfo::values_
__ sw(at, MemOperand(a0, 1 * kPointerSize)); __ Addu(at, scratch,
// FunctionCallbackInfo::length_ = argc Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ li(at, Operand(argc)); __ sw(at, MemOperand(a0, 1 * kPointerSize));
__ sw(at, MemOperand(a0, 2 * kPointerSize)); // FunctionCallbackInfo::length_ = argc
// FunctionCallbackInfo::is_construct_call = 0 __ li(at, Operand(argc.immediate()));
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); __ sw(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
} else {
// FunctionCallbackInfo::values_
__ sll(at, argc.reg(), kPointerSizeLog2);
__ Addu(at, at, scratch);
__ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
__ sw(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ Addu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
__ sll(at, argc.reg(), kPointerSizeLog2);
__ sw(at, MemOperand(a0, 3 * kPointerSize));
}
ExternalReference thunk_ref = ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(isolate()); ExternalReference::invoke_function_callback(masm->isolate());
AllowExternalCallThatCantCauseGC scope(masm); AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand( MemOperand context_restore_operand(
fp, (2 + FCA::kContextSaveIndex) * kPointerSize); fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument. // Stores return the first js argument.
int return_value_offset = 0; int return_value_offset = 0;
if (is_store) { if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength; return_value_offset = 2 + FCA::kArgsLength;
} else { } else {
return_value_offset = 2 + FCA::kReturnValueOffset; return_value_offset = 2 + FCA::kReturnValueOffset;
} }
MemOperand return_value_operand(fp, return_value_offset * kPointerSize); MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
int stack_space = 0;
__ CallApiFunctionAndReturn(api_function_address, MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize);
thunk_ref, MemOperand* stack_space_operand = &is_construct_call_operand;
kStackUnwindSpace, if (argc.is_immediate()) {
return_value_operand, stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
__ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,
&context_restore_operand); &context_restore_operand);
} }
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
call_data_undefined);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = is_store ? 1 : 0;
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) { void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- sp[0] : name // -- sp[0] : name
...@@ -4960,11 +4995,9 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { ...@@ -4960,11 +4995,9 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
ExternalReference thunk_ref = ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate()); ExternalReference::invoke_accessor_getter_callback(isolate());
__ CallApiFunctionAndReturn(api_function_address, __ CallApiFunctionAndReturn(api_function_address, thunk_ref,
thunk_ref, kStackUnwindSpace, NULL,
kStackUnwindSpace, MemOperand(fp, 6 * kPointerSize), NULL);
MemOperand(fp, 6 * kPointerSize),
NULL);
} }
......
...@@ -293,6 +293,27 @@ void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) { ...@@ -293,6 +293,27 @@ void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
Register registers[] = {
cp, // context
a0, // callee
t0, // call_data
a2, // holder
a1, // api_function_address
a3, // actual number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
Representation::Integer32(), // actual number of arguments
};
data->Initialize(arraysize(registers), registers, representations);
}
void ApiAccessorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
cp, // context cp, // context
a0, // callee a0, // callee
......
...@@ -4419,10 +4419,8 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { ...@@ -4419,10 +4419,8 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
void MacroAssembler::CallApiFunctionAndReturn( void MacroAssembler::CallApiFunctionAndReturn(
Register function_address, Register function_address, ExternalReference thunk_ref, int stack_space,
ExternalReference thunk_ref, MemOperand* stack_space_operand, MemOperand return_value_operand,
int stack_space,
MemOperand return_value_operand,
MemOperand* context_restore_operand) { MemOperand* context_restore_operand) {
ExternalReference next_address = ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate()); ExternalReference::handle_scope_next_address(isolate());
...@@ -4516,8 +4514,13 @@ void MacroAssembler::CallApiFunctionAndReturn( ...@@ -4516,8 +4514,13 @@ void MacroAssembler::CallApiFunctionAndReturn(
if (restore_context) { if (restore_context) {
lw(cp, *context_restore_operand); lw(cp, *context_restore_operand);
} }
li(s0, Operand(stack_space)); if (stack_space_operand != NULL) {
LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN); lw(s0, *stack_space_operand);
} else {
li(s0, Operand(stack_space));
}
LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN,
stack_space_operand != NULL);
bind(&promote_scheduled_exception); bind(&promote_scheduled_exception);
{ {
...@@ -5166,10 +5169,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, ...@@ -5166,10 +5169,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
} }
void MacroAssembler::LeaveExitFrame(bool save_doubles, void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
Register argument_count, bool restore_context, bool do_return,
bool restore_context, bool argument_count_is_length) {
bool do_return) {
// Optionally restore all double registers. // Optionally restore all double registers.
if (save_doubles) { if (save_doubles) {
// Remember: we only need to restore every 2nd double FPU value. // Remember: we only need to restore every 2nd double FPU value.
...@@ -5200,8 +5202,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, ...@@ -5200,8 +5202,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset));
if (argument_count.is_valid()) { if (argument_count.is_valid()) {
sll(t8, argument_count, kPointerSizeLog2); if (argument_count_is_length) {
addu(sp, sp, t8); addu(sp, sp, argument_count);
} else {
sll(t8, argument_count, kPointerSizeLog2);
addu(sp, sp, t8);
}
} }
if (do_return) { if (do_return) {
......
...@@ -871,10 +871,9 @@ class MacroAssembler: public Assembler { ...@@ -871,10 +871,9 @@ class MacroAssembler: public Assembler {
int stack_space = 0); int stack_space = 0);
// Leave the current exit frame. // Leave the current exit frame.
void LeaveExitFrame(bool save_doubles, void LeaveExitFrame(bool save_doubles, Register arg_count,
Register arg_count, bool restore_context, bool do_return = NO_EMIT_RETURN,
bool restore_context, bool argument_count_is_length = false);
bool do_return = NO_EMIT_RETURN);
// Get the actual activation frame alignment for target environment. // Get the actual activation frame alignment for target environment.
static int ActivationFrameAlignment(); static int ActivationFrameAlignment();
...@@ -1291,8 +1290,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT ...@@ -1291,8 +1290,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
// - 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(Register function_address, void CallApiFunctionAndReturn(Register function_address,
ExternalReference thunk_ref, ExternalReference thunk_ref, int stack_space,
int stack_space, MemOperand* stack_space_operand,
MemOperand return_value_operand, MemOperand return_value_operand,
MemOperand* context_restore_operand); MemOperand* context_restore_operand);
......
...@@ -4873,12 +4873,16 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { ...@@ -4873,12 +4873,16 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
} }
void CallApiFunctionStub::Generate(MacroAssembler* masm) { static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- a0 : callee // -- a0 : callee
// -- a4 : call_data // -- a4 : call_data
// -- a2 : holder // -- a2 : holder
// -- a1 : api_function_address // -- a1 : api_function_address
// -- a3 : number of arguments if argc is a register
// -- cp : context // -- cp : context
// -- // --
// -- sp[0] : last argument // -- sp[0] : last argument
...@@ -4893,10 +4897,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4893,10 +4897,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
Register api_function_address = a1; Register api_function_address = a1;
Register context = cp; Register context = cp;
int argc = this->argc();
bool is_store = this->is_store();
bool call_data_undefined = this->call_data_undefined();
typedef FunctionCallbackArguments FCA; typedef FunctionCallbackArguments FCA;
STATIC_ASSERT(FCA::kContextSaveIndex == 6); STATIC_ASSERT(FCA::kContextSaveIndex == 6);
...@@ -4908,6 +4908,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4908,6 +4908,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0); STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7); STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
// Save context, callee and call data. // Save context, callee and call data.
__ Push(context, callee, call_data); __ Push(context, callee, call_data);
// Load context from callee. // Load context from callee.
...@@ -4919,8 +4921,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4919,8 +4921,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
} }
// Push return value and default return value. // Push return value and default return value.
__ Push(scratch, scratch); __ Push(scratch, scratch);
__ li(scratch, __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate())));
Operand(ExternalReference::isolate_address(isolate())));
// Push isolate and holder. // Push isolate and holder.
__ Push(scratch, holder); __ Push(scratch, holder);
...@@ -4940,39 +4941,73 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4940,39 +4941,73 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ Daddu(a0, sp, Operand(1 * kPointerSize)); __ Daddu(a0, sp, Operand(1 * kPointerSize));
// FunctionCallbackInfo::implicit_args_ // FunctionCallbackInfo::implicit_args_
__ sd(scratch, MemOperand(a0, 0 * kPointerSize)); __ sd(scratch, MemOperand(a0, 0 * kPointerSize));
// FunctionCallbackInfo::values_ if (argc.is_immediate()) {
__ Daddu(at, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); // FunctionCallbackInfo::values_
__ sd(at, MemOperand(a0, 1 * kPointerSize)); __ Daddu(at, scratch,
// FunctionCallbackInfo::length_ = argc Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ li(at, Operand(argc)); __ sd(at, MemOperand(a0, 1 * kPointerSize));
__ sd(at, MemOperand(a0, 2 * kPointerSize)); // FunctionCallbackInfo::length_ = argc
// FunctionCallbackInfo::is_construct_call = 0 __ li(at, Operand(argc.immediate()));
__ sd(zero_reg, MemOperand(a0, 3 * kPointerSize)); __ sd(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; __ sd(zero_reg, MemOperand(a0, 3 * kPointerSize));
} else {
// FunctionCallbackInfo::values_
__ dsll(at, argc.reg(), kPointerSizeLog2);
__ Daddu(at, at, scratch);
__ Daddu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
__ sd(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ sd(argc.reg(), MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ Daddu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
__ dsll(at, argc.reg(), kPointerSizeLog2);
__ sd(at, MemOperand(a0, 3 * kPointerSize));
}
ExternalReference thunk_ref = ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(isolate()); ExternalReference::invoke_function_callback(masm->isolate());
AllowExternalCallThatCantCauseGC scope(masm); AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand( MemOperand context_restore_operand(
fp, (2 + FCA::kContextSaveIndex) * kPointerSize); fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument. // Stores return the first js argument.
int return_value_offset = 0; int return_value_offset = 0;
if (is_store) { if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength; return_value_offset = 2 + FCA::kArgsLength;
} else { } else {
return_value_offset = 2 + FCA::kReturnValueOffset; return_value_offset = 2 + FCA::kReturnValueOffset;
} }
MemOperand return_value_operand(fp, return_value_offset * kPointerSize); MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
int stack_space = 0;
__ CallApiFunctionAndReturn(api_function_address, MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize);
thunk_ref, MemOperand* stack_space_operand = &is_construct_call_operand;
kStackUnwindSpace, if (argc.is_immediate()) {
return_value_operand, stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
__ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,
&context_restore_operand); &context_restore_operand);
} }
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
call_data_undefined);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = is_store ? 1 : 0;
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) { void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- sp[0] : name // -- sp[0] : name
...@@ -5000,11 +5035,9 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { ...@@ -5000,11 +5035,9 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
ExternalReference thunk_ref = ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate()); ExternalReference::invoke_accessor_getter_callback(isolate());
__ CallApiFunctionAndReturn(api_function_address, __ CallApiFunctionAndReturn(api_function_address, thunk_ref,
thunk_ref, kStackUnwindSpace, NULL,
kStackUnwindSpace, MemOperand(fp, 6 * kPointerSize), NULL);
MemOperand(fp, 6 * kPointerSize),
NULL);
} }
......
...@@ -293,6 +293,27 @@ void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) { ...@@ -293,6 +293,27 @@ void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
Register registers[] = {
cp, // context
a0, // callee
a4, // call_data
a2, // holder
a1, // api_function_address
a3, // actual number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
Representation::Integer32(), // actual number of arguments
};
data->Initialize(arraysize(registers), registers, representations);
}
void ApiAccessorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
cp, // context cp, // context
a0, // callee a0, // callee
......
...@@ -4367,10 +4367,8 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { ...@@ -4367,10 +4367,8 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
void MacroAssembler::CallApiFunctionAndReturn( void MacroAssembler::CallApiFunctionAndReturn(
Register function_address, Register function_address, ExternalReference thunk_ref, int stack_space,
ExternalReference thunk_ref, MemOperand* stack_space_operand, MemOperand return_value_operand,
int stack_space,
MemOperand return_value_operand,
MemOperand* context_restore_operand) { MemOperand* context_restore_operand) {
ExternalReference next_address = ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate()); ExternalReference::handle_scope_next_address(isolate());
...@@ -4464,9 +4462,13 @@ void MacroAssembler::CallApiFunctionAndReturn( ...@@ -4464,9 +4462,13 @@ void MacroAssembler::CallApiFunctionAndReturn(
if (restore_context) { if (restore_context) {
ld(cp, *context_restore_operand); ld(cp, *context_restore_operand);
} }
li(s0, Operand(stack_space)); if (stack_space_operand != NULL) {
LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN); lw(s0, *stack_space_operand);
} else {
li(s0, Operand(stack_space));
}
LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN,
stack_space_operand != NULL);
bind(&promote_scheduled_exception); bind(&promote_scheduled_exception);
{ {
FrameScope frame(this, StackFrame::INTERNAL); FrameScope frame(this, StackFrame::INTERNAL);
...@@ -5116,10 +5118,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, ...@@ -5116,10 +5118,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
} }
void MacroAssembler::LeaveExitFrame(bool save_doubles, void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
Register argument_count, bool restore_context, bool do_return,
bool restore_context, bool argument_count_is_length) {
bool do_return) {
// Optionally restore all double registers. // Optionally restore all double registers.
if (save_doubles) { if (save_doubles) {
// Remember: we only need to restore every 2nd double FPU value. // Remember: we only need to restore every 2nd double FPU value.
...@@ -5152,8 +5153,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, ...@@ -5152,8 +5153,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
ld(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); ld(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset));
if (argument_count.is_valid()) { if (argument_count.is_valid()) {
dsll(t8, argument_count, kPointerSizeLog2); if (argument_count_is_length) {
daddu(sp, sp, t8); daddu(sp, sp, argument_count);
} else {
dsll(t8, argument_count, kPointerSizeLog2);
daddu(sp, sp, t8);
}
} }
if (do_return) { if (do_return) {
......
...@@ -901,10 +901,9 @@ class MacroAssembler: public Assembler { ...@@ -901,10 +901,9 @@ class MacroAssembler: public Assembler {
int stack_space = 0); int stack_space = 0);
// Leave the current exit frame. // Leave the current exit frame.
void LeaveExitFrame(bool save_doubles, void LeaveExitFrame(bool save_doubles, Register arg_count,
Register arg_count, bool restore_context, bool do_return = NO_EMIT_RETURN,
bool restore_context, bool argument_count_is_length = false);
bool do_return = NO_EMIT_RETURN);
// Get the actual activation frame alignment for target environment. // Get the actual activation frame alignment for target environment.
static int ActivationFrameAlignment(); static int ActivationFrameAlignment();
...@@ -1321,8 +1320,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT ...@@ -1321,8 +1320,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
// - 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(Register function_address, void CallApiFunctionAndReturn(Register function_address,
ExternalReference thunk_ref, ExternalReference thunk_ref, int stack_space,
int stack_space, MemOperand* stack_space_operand,
MemOperand return_value_operand, MemOperand return_value_operand,
MemOperand* context_restore_operand); MemOperand* context_restore_operand);
......
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