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)); |