Chromium Code Reviews| Index: src/x64/stub-cache-x64.cc |
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc |
| index 31f60be565e2de24697de08cca2a78ded9ec27c2..5eece66da97880193fde2457e6bc12f731899315 100644 |
| --- a/src/x64/stub-cache-x64.cc |
| +++ b/src/x64/stub-cache-x64.cc |
| @@ -443,7 +443,8 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { |
| // Generates call to API function. |
| static void GenerateFastApiCall(MacroAssembler* masm, |
| const CallOptimization& optimization, |
| - int argc) { |
| + int argc, |
| + bool restore_context) { |
| // ----------- S t a t e ------------- |
| // -- rsp[0] : return address |
| // -- rsp[8] : object passing the type check |
| @@ -452,20 +453,16 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
| // -- rsp[16] : api function |
| // (first fast api call extra argument) |
| // -- rsp[24] : api call data |
| - // -- rsp[32] : isolate |
| - // -- rsp[40] : ReturnValue default value |
| - // -- rsp[48] : ReturnValue |
| + // -- rsp[32] : context save |
| + // -- rsp[40] : isolate |
| + // -- rsp[48] : ReturnValue default value |
| + // -- rsp[56] : ReturnValue |
| // |
| - // -- rsp[56] : last argument |
| + // -- rsp[64] : last argument |
| // -- ... |
| - // -- rsp[(argc + 6) * 8] : first argument |
| - // -- rsp[(argc + 7) * 8] : receiver |
| + // -- rsp[(argc + 7) * 8] : first argument |
| + // -- rsp[(argc + 8) * 8] : receiver |
| // ----------------------------------- |
| - // Get the function and setup the context. |
| - Handle<JSFunction> function = optimization.constant_function(); |
| - __ LoadHeapObject(rdi, function); |
| - __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| - |
| int api_call_argc = argc + kFastApiCallArguments; |
| StackArgumentsAccessor args(rsp, api_call_argc); |
| @@ -480,32 +477,31 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
| } else { |
| __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data); |
| } |
| + // Context save |
|
Michael Starzinger
2013/09/12 18:38:51
nit: s/Context save/Save calling context./
|
| + __ movq(args.GetArgumentOperand(api_call_argc - 3), rsi); |
| __ movq(kScratchRegister, |
| ExternalReference::isolate_address(masm->isolate())); |
| - __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister); |
| - __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
| __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister); |
| + __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
| __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister); |
| + __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister); |
| // Prepare arguments. |
| - STATIC_ASSERT(kFastApiCallArguments == 6); |
| + STATIC_ASSERT(kFastApiCallArguments == 7); |
| __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); |
| // Function address is a foreign pointer outside V8's heap. |
| Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| -#if defined(__MINGW64__) || defined(_WIN64) |
| - Register arguments_arg = rcx; |
| - Register callback_arg = rdx; |
| -#else |
| - Register arguments_arg = rdi; |
| - Register callback_arg = rsi; |
| -#endif |
| - |
| // Allocate the v8::Arguments structure in the arguments' space since |
| // it's not controlled by GC. |
| const int kApiStackSpace = 4; |
| + // Get the function and setup the context. |
| + Handle<JSFunction> function = optimization.constant_function(); |
| + __ LoadHeapObject(rdi, function); |
| + __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| + |
| __ PrepareCallApiFunction(kApiStackSpace); |
| __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. |
| @@ -515,16 +511,26 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
| // v8::Arguments::is_construct_call_. |
| __ Set(StackSpaceOperand(3), 0); |
| +#if defined(__MINGW64__) || defined(_WIN64) |
| + Register arguments_arg = rcx; |
| + Register callback_arg = rdx; |
| +#else |
| + Register arguments_arg = rdi; |
| + Register callback_arg = rsi; |
| +#endif |
| + |
| // v8::InvocationCallback's argument. |
| __ lea(arguments_arg, StackSpaceOperand(0)); |
| Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |
| + int context_restore_slot = restore_context ? kFastApiCallArguments - 2 : 0; |
| __ CallApiFunctionAndReturn(function_address, |
| thunk_address, |
| callback_arg, |
| api_call_argc + 1, |
| - kFastApiCallArguments + 1); |
| + kFastApiCallArguments + 1, |
| + context_restore_slot); |
| } |
| @@ -557,7 +563,7 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
| __ movq(Operand(rsp, index-- * kPointerSize), values[i]); |
| } |
| - GenerateFastApiCall(masm, optimization, argc); |
| + GenerateFastApiCall(masm, optimization, argc, true); |
| } |
| @@ -671,7 +677,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { |
| // Invoke function. |
| if (can_do_fast_api_call) { |
| - GenerateFastApiCall(masm, optimization, arguments_.immediate()); |
| + GenerateFastApiCall(masm, optimization, arguments_.immediate(), false); |
| } else { |
| CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
| ? CALL_AS_FUNCTION |
| @@ -2503,7 +2509,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( |
| StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); |
| __ movq(StackOperandForReturnAddress(0), rax); |
| - GenerateFastApiCall(masm(), optimization, argc); |
| + GenerateFastApiCall(masm(), optimization, argc, false); |
| __ bind(&miss); |
| __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |