Chromium Code Reviews| Index: src/arm/code-stubs-arm.cc |
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
| index ef286bbe01585a7a1ad56d3e71c0b5fdc278233f..656d2816b0b843489118e7437284895ba4270a7c 100644 |
| --- a/src/arm/code-stubs-arm.cc |
| +++ b/src/arm/code-stubs-arm.cc |
| @@ -4610,12 +4610,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 ------------- |
| // -- r0 : callee |
| // -- r4 : call_data |
| // -- r2 : holder |
| // -- r1 : api_function_address |
| + // -- r3 : number of arguments if argc is a register |
| // -- cp : context |
| // -- |
| // -- sp[0] : last argument |
| @@ -4630,10 +4634,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| Register api_function_address = r1; |
| Register context = cp; |
| - int argc = this->argc(); |
| - bool is_store = this->is_store(); |
| - bool call_data_undefined = this->call_data_undefined(); |
| - |
| typedef FunctionCallbackArguments FCA; |
| STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| @@ -4645,6 +4645,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| STATIC_ASSERT(FCA::kHolderIndex == 0); |
| STATIC_ASSERT(FCA::kArgsLength == 7); |
| + DCHECK(argc.is_immediate() || r3.is(argc.reg())); |
| + |
| // context save |
| __ push(context); |
| // load context from callee |
| @@ -4665,8 +4667,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| // return value default |
| __ push(scratch); |
| // isolate |
| - __ mov(scratch, |
| - Operand(ExternalReference::isolate_address(isolate()))); |
| + __ mov(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| __ push(scratch); |
| // holder |
| __ push(holder); |
| @@ -4687,40 +4688,76 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| __ add(r0, sp, Operand(1 * kPointerSize)); |
| // FunctionCallbackInfo::implicit_args_ |
| __ str(scratch, MemOperand(r0, 0 * kPointerSize)); |
| + Register length_value = r3; |
| + if (argc.is_immediate()) { |
| + __ add(scratch, scratch, |
| + Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize)); |
| + // FunctionCallbackInfo::length_ |
| + __ mov(ip, Operand(argc.immediate())); |
| + __ str(ip, MemOperand(r0, 2 * kPointerSize)); |
| + } else { |
| + __ add(scratch, scratch, Operand(length_value, LSL, 2)); |
|
dcarney
2015/01/15 10:11:36
2 should be kPointerSizeLog2
|
| + __ add(scratch, scratch, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
|
dcarney
2015/01/15 10:11:37
should be able to do this with fused add multiply,
|
| + // FunctionCallbackInfo::length_ |
| + __ mov(ip, length_value); |
| + __ str(ip, MemOperand(r0, 2 * kPointerSize)); |
| + } |
| // FunctionCallbackInfo::values_ |
| - __ add(ip, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); |
| - __ str(ip, MemOperand(r0, 1 * kPointerSize)); |
| - // FunctionCallbackInfo::length_ = argc |
| - __ mov(ip, Operand(argc)); |
| - __ str(ip, MemOperand(r0, 2 * kPointerSize)); |
| - // FunctionCallbackInfo::is_construct_call = 0 |
| - __ mov(ip, Operand::Zero()); |
| - __ str(ip, MemOperand(r0, 3 * kPointerSize)); |
| - |
| - const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; |
| + __ str(scratch, MemOperand(r0, 1 * kPointerSize)); |
| + if (argc.is_immediate()) { |
| + // FunctionCallbackInfo::is_construct_call |
| + __ mov(ip, Operand::Zero()); |
| + __ str(ip, MemOperand(r0, 3 * kPointerSize)); |
| + } else { |
| + // FunctionCallbackInfo::is_conetruct_call |
| + __ add(length_value, length_value, Operand(FCA::kArgsLength + 1)); |
| + __ mov(ip, Operand(length_value, LSL, 3)); |
|
dcarney
2015/01/15 10:11:36
3 should be kPointerSizeLog2 + 1 to make it clear
|
| + __ str(ip, MemOperand(r0, 3 * kPointerSize)); |
| + } |
| + |
| ExternalReference thunk_ref = |
| - ExternalReference::invoke_function_callback(isolate()); |
| + ExternalReference::invoke_function_callback(masm->isolate()); |
| AllowExternalCallThatCantCauseGC scope(masm); |
| MemOperand context_restore_operand( |
| fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
| // Stores return the first js argument |
| int return_value_offset = 0; |
| - if (is_store) { |
| + if (return_first_arg) { |
| return_value_offset = 2 + FCA::kArgsLength; |
| } else { |
| return_value_offset = 2 + FCA::kReturnValueOffset; |
| } |
| MemOperand return_value_operand(fp, return_value_offset * kPointerSize); |
| - |
| - __ CallApiFunctionAndReturn(api_function_address, |
| - thunk_ref, |
| - kStackUnwindSpace, |
| - return_value_operand, |
| + int stack_space = 0; |
| + MemOperand is_construct_call_operand = MemOperand(r0, 3 * kPointerSize); |
| + MemOperand* stack_space_operand = &is_construct_call_operand; |
| + if (argc.is_immediate()) { |
| + stack_space = argc.immediate() + FCA::kArgsLength; |
| + stack_space_operand = NULL; |
| + } |
| + __ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space, |
| + stack_space_operand, return_value_operand, |
| &context_restore_operand); |
| } |
| +void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| + bool call_data_undefined = this->call_data_undefined(); |
| + CallApiFunctionStubHelper(masm, ParameterCount(r3), 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) { |
| // ----------- S t a t e ------------- |
| // -- sp[0] : name |
| @@ -4748,11 +4785,9 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { |
| ExternalReference thunk_ref = |
| ExternalReference::invoke_accessor_getter_callback(isolate()); |
| - __ CallApiFunctionAndReturn(api_function_address, |
| - thunk_ref, |
| - kStackUnwindSpace, |
| - MemOperand(fp, 6 * kPointerSize), |
| - NULL); |
| + __ CallApiFunctionAndReturn(api_function_address, thunk_ref, |
| + kStackUnwindSpace, NULL, |
| + MemOperand(fp, 6 * kPointerSize), NULL); |
| } |