| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index f327b5008543bdfa4f541badfc04e0ababdf4f26..1149348e09ce86c4ecac7ea32a32b67b09b9e86e 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -4621,14 +4621,17 @@ 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 -------------
|
| // -- rax : callee
|
| // -- rbx : call_data
|
| // -- rcx : holder
|
| // -- rdx : api_function_address
|
| // -- rsi : context
|
| - // --
|
| + // -- rdi : number of arguments if argc is a register
|
| // -- rsp[0] : return address
|
| // -- rsp[8] : last argument
|
| // -- ...
|
| @@ -4640,13 +4643,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
| Register call_data = rbx;
|
| Register holder = rcx;
|
| Register api_function_address = rdx;
|
| - Register return_address = rdi;
|
| Register context = rsi;
|
|
|
| - 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);
|
| @@ -4658,12 +4656,17 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
| STATIC_ASSERT(FCA::kHolderIndex == 0);
|
| STATIC_ASSERT(FCA::kArgsLength == 7);
|
|
|
| - __ PopReturnAddressTo(return_address);
|
| + DCHECK(argc.is_immediate() || rdi.is(argc.reg()));
|
|
|
| - // context save
|
| - __ Push(context);
|
| - // load context from callee
|
| - __ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
|
| + if (kPointerSize == kInt64Size) {
|
| + // pop return address and save context
|
| + __ xchgq(context, Operand(rsp, 0));
|
| + } else {
|
| + // x32 handling.
|
| + __ PopReturnAddressTo(kScratchRegister);
|
| + __ Push(context);
|
| + __ movq(context, kScratchRegister);
|
| + }
|
|
|
| // callee
|
| __ Push(callee);
|
| @@ -4679,15 +4682,17 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
| // return value default
|
| __ Push(scratch);
|
| // isolate
|
| - __ Move(scratch,
|
| - ExternalReference::isolate_address(isolate()));
|
| + __ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
|
| __ Push(scratch);
|
| // holder
|
| __ Push(holder);
|
|
|
| __ movp(scratch, rsp);
|
| // Push return address back on stack.
|
| - __ PushReturnAddressFrom(return_address);
|
| + __ PushReturnAddressFrom(context);
|
| +
|
| + // load context from callee
|
| + __ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
|
|
|
| // Allocate the v8::Arguments structure in the arguments' space since
|
| // it's not controlled by GC.
|
| @@ -4697,11 +4702,27 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
|
|
| // FunctionCallbackInfo::implicit_args_.
|
| __ movp(StackSpaceOperand(0), scratch);
|
| - __ addp(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize));
|
| - __ movp(StackSpaceOperand(1), scratch); // FunctionCallbackInfo::values_.
|
| - __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_.
|
| - // FunctionCallbackInfo::is_construct_call_.
|
| - __ Set(StackSpaceOperand(3), 0);
|
| + if (argc.is_immediate()) {
|
| + __ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) *
|
| + kPointerSize));
|
| + // FunctionCallbackInfo::values_.
|
| + __ movp(StackSpaceOperand(1), scratch);
|
| + // FunctionCallbackInfo::length_.
|
| + __ Set(StackSpaceOperand(2), argc.immediate());
|
| + // FunctionCallbackInfo::is_construct_call_.
|
| + __ Set(StackSpaceOperand(3), 0);
|
| + } else {
|
| + __ leap(scratch, Operand(scratch, argc.reg(), times_pointer_size,
|
| + (FCA::kArgsLength - 1) * kPointerSize));
|
| + // FunctionCallbackInfo::values_.
|
| + __ movp(StackSpaceOperand(1), scratch);
|
| + // FunctionCallbackInfo::length_.
|
| + __ movp(StackSpaceOperand(2), argc.reg());
|
| + // FunctionCallbackInfo::is_construct_call_.
|
| + __ leap(argc.reg(), Operand(argc.reg(), times_pointer_size,
|
| + (FCA::kArgsLength + 1) * kPointerSize));
|
| + __ movp(StackSpaceOperand(3), argc.reg());
|
| + }
|
|
|
| #if defined(__MINGW64__) || defined(_WIN64)
|
| Register arguments_arg = rcx;
|
| @@ -4719,23 +4740,42 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
| __ leap(arguments_arg, StackSpaceOperand(0));
|
|
|
| ExternalReference thunk_ref =
|
| - ExternalReference::invoke_function_callback(isolate());
|
| + ExternalReference::invoke_function_callback(masm->isolate());
|
|
|
| // Accessor for FunctionCallbackInfo and first js arg.
|
| StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1,
|
| ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| Operand context_restore_operand = args_from_rbp.GetArgumentOperand(
|
| FCA::kArgsLength - FCA::kContextSaveIndex);
|
| - // Stores return the first js argument
|
| + Operand is_construct_call_operand = StackSpaceOperand(3);
|
| Operand return_value_operand = args_from_rbp.GetArgumentOperand(
|
| - is_store ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
|
| - __ CallApiFunctionAndReturn(
|
| - api_function_address,
|
| - thunk_ref,
|
| - callback_arg,
|
| - argc + FCA::kArgsLength + 1,
|
| - return_value_operand,
|
| - &context_restore_operand);
|
| + return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
|
| + int stack_space = 0;
|
| + Operand* stack_space_operand = &is_construct_call_operand;
|
| + if (argc.is_immediate()) {
|
| + stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
| + stack_space_operand = nullptr;
|
| + }
|
| + __ CallApiFunctionAndReturn(api_function_address, thunk_ref, callback_arg,
|
| + stack_space, stack_space_operand,
|
| + return_value_operand, &context_restore_operand);
|
| +}
|
| +
|
| +
|
| +void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
| + // TODO(dcarney): make rax contain the function address.
|
| + bool call_data_undefined = this->call_data_undefined();
|
| + CallApiFunctionStubHelper(masm, ParameterCount(rdi), 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);
|
| }
|
|
|
|
|
| @@ -4792,12 +4832,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
| Operand return_value_operand = args.GetArgumentOperand(
|
| PropertyCallbackArguments::kArgsLength - 1 -
|
| PropertyCallbackArguments::kReturnValueOffset);
|
| - __ CallApiFunctionAndReturn(api_function_address,
|
| - thunk_ref,
|
| - getter_arg,
|
| - kStackSpace,
|
| - return_value_operand,
|
| - NULL);
|
| + __ CallApiFunctionAndReturn(api_function_address, thunk_ref, getter_arg,
|
| + kStackSpace, nullptr, return_value_operand, NULL);
|
| }
|
|
|
|
|
|
|