Index: src/x64/stub-cache-x64.cc |
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc |
index b579e94e7b72e61a9b400c711542c49b790a95f1..fce9b92c94ad66ac74736ebef279e0d0f32e7183 100644 |
--- a/src/x64/stub-cache-x64.cc |
+++ b/src/x64/stub-cache-x64.cc |
@@ -388,18 +388,53 @@ static void CompileCallLoadPropertyWithInterceptor( |
} |
-// Number of pointers to be reserved on stack for fast API call. |
-static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; |
- |
- |
static void GenerateFastApiCallBody(MacroAssembler* masm, |
const CallOptimization& optimization, |
int argc, |
- Register holder, |
- Register scratch1, |
- Register scratch2, |
- Register scratch3, |
- bool restore_context); |
+ Register holder_in, |
+ bool restore_context) { |
+ ASSERT(optimization.is_simple_api_call()); |
+ |
+ // Abi for CallApiFunctionStub. |
+ Register callee = rax; |
+ Register call_data = rbx; |
+ Register holder = rcx; |
+ Register api_function_address = rdx; |
+ |
+ // Put holder in place. |
+ __ Move(holder, holder_in); |
+ |
+ Register scratch = rdi; |
+ |
+ Isolate* isolate = masm->isolate(); |
+ Handle<JSFunction> function = optimization.constant_function(); |
+ Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
+ Handle<Object> call_data_obj(api_call_info->data(), isolate); |
+ |
+ // Put callee in place. |
+ __ Move(callee, function); |
+ |
+ bool call_data_undefined = false; |
+ // Put call_data in place. |
+ if (isolate->heap()->InNewSpace(*call_data_obj)) { |
+ __ Move(scratch, api_call_info); |
+ __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); |
+ } else if (call_data_obj->IsUndefined()) { |
+ call_data_undefined = true; |
+ __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
+ } else { |
+ __ Move(call_data, call_data_obj); |
+ } |
+ |
+ // Put api_function_address in place. |
+ Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
+ __ Move( |
+ api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); |
+ |
+ // Jump to stub. |
+ CallApiFunctionStub stub(restore_context, call_data_undefined, argc); |
+ __ TailCallStub(&stub); |
+} |
// Generates call to API function. |
@@ -439,23 +474,15 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
optimization, |
argc, |
holder_reg, |
- rbx, |
- rcx, |
- rdx, |
false); |
} |
// Generate call to api function. |
-// This function uses push() to generate smaller, faster code than |
-// the version above. It is an optimization that should will be removed |
-// when api call ICs are generated in hydrogen. |
static void GenerateFastApiCall(MacroAssembler* masm, |
const CallOptimization& optimization, |
Register receiver, |
Register scratch1, |
- Register scratch2, |
- Register scratch3, |
int argc, |
Register* values) { |
__ PopReturnAddressTo(scratch1); |
@@ -466,8 +493,6 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
Register arg = values[argc-1-i]; |
ASSERT(!receiver.is(arg)); |
ASSERT(!scratch1.is(arg)); |
- ASSERT(!scratch2.is(arg)); |
- ASSERT(!scratch3.is(arg)); |
__ push(arg); |
} |
__ PushReturnAddressFrom(scratch1); |
@@ -476,133 +501,10 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
optimization, |
argc, |
receiver, |
- scratch1, |
- scratch2, |
- scratch3, |
true); |
} |
-static void GenerateFastApiCallBody(MacroAssembler* masm, |
- const CallOptimization& optimization, |
- int argc, |
- Register holder, |
- Register scratch1, |
- Register scratch2, |
- Register scratch3, |
- bool restore_context) { |
- // ----------- S t a t e ------------- |
- // -- rsp[0] : return address |
- // -- rsp[8] : last argument |
- // -- ... |
- // -- rsp[argc * 8] : first argument |
- // -- rsp[(argc + 1) * 8] : receiver |
- // ----------------------------------- |
- ASSERT(optimization.is_simple_api_call()); |
- |
- typedef FunctionCallbackArguments FCA; |
- |
- STATIC_ASSERT(FCA::kHolderIndex == 0); |
- STATIC_ASSERT(FCA::kIsolateIndex == 1); |
- STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
- STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
- STATIC_ASSERT(FCA::kDataIndex == 4); |
- STATIC_ASSERT(FCA::kCalleeIndex == 5); |
- STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
- STATIC_ASSERT(FCA::kArgsLength == 7); |
- |
- __ PopReturnAddressTo(scratch1); |
- |
- ASSERT(!holder.is(rsi)); |
- // context save |
- __ push(rsi); |
- |
- // Get the function and setup the context. |
- Handle<JSFunction> function = optimization.constant_function(); |
- __ Move(scratch2, function); |
- __ push(scratch2); |
- __ movp(rsi, FieldOperand(scratch2, JSFunction::kContextOffset)); |
- |
- Isolate* isolate = masm->isolate(); |
- Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
- Handle<Object> call_data(api_call_info->data(), isolate); |
- // Push data from ExecutableAccessorInfo. |
- bool call_data_undefined = false; |
- if (isolate->heap()->InNewSpace(*call_data)) { |
- __ Move(scratch2, api_call_info); |
- __ movp(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset)); |
- } else if (call_data->IsUndefined()) { |
- call_data_undefined = true; |
- __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); |
- } else { |
- __ Move(scratch3, call_data); |
- } |
- // call data |
- __ push(scratch3); |
- if (!call_data_undefined) { |
- __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); |
- } |
- // return value |
- __ push(scratch3); |
- // return value default |
- __ push(scratch3); |
- // isolate |
- __ Move(scratch3, |
- ExternalReference::isolate_address(masm->isolate())); |
- __ push(scratch3); |
- // holder |
- __ push(holder); |
- |
- ASSERT(!scratch1.is(rax)); |
- __ movp(rax, rsp); |
- // Push return address back on stack. |
- __ PushReturnAddressFrom(scratch1); |
- |
- // Function address is a foreign pointer outside V8's heap. |
- Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
- |
- // Allocate the v8::Arguments structure in the arguments' space since |
- // it's not controlled by GC. |
- const int kApiStackSpace = 4; |
- |
- __ PrepareCallApiFunction(kApiStackSpace); |
- |
- __ movp(StackSpaceOperand(0), rax); // FunctionCallbackInfo::implicit_args_. |
- __ addq(rax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize)); |
- __ movp(StackSpaceOperand(1), rax); // FunctionCallbackInfo::values_. |
- __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_. |
- // FunctionCallbackInfo::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); |
- |
- StackArgumentsAccessor args_from_rbp(rbp, kFastApiCallArguments, |
- ARGUMENTS_DONT_CONTAIN_RECEIVER); |
- Operand context_restore_operand = args_from_rbp.GetArgumentOperand( |
- kFastApiCallArguments - 1 - FCA::kContextSaveIndex); |
- Operand return_value_operand = args_from_rbp.GetArgumentOperand( |
- kFastApiCallArguments - 1 - FCA::kReturnValueOffset); |
- __ CallApiFunctionAndReturn( |
- function_address, |
- thunk_address, |
- callback_arg, |
- argc + kFastApiCallArguments + 1, |
- return_value_operand, |
- restore_context ? &context_restore_operand : NULL); |
-} |
- |
- |
class CallInterceptorCompiler BASE_EMBEDDED { |
public: |
CallInterceptorCompiler(CallStubCompiler* stub_compiler, |
@@ -1279,7 +1181,7 @@ void LoadStubCompiler::GenerateLoadCallback( |
const CallOptimization& call_optimization) { |
GenerateFastApiCall( |
masm(), call_optimization, receiver(), |
- scratch1(), scratch2(), name(), 0, NULL); |
+ scratch1(), 0, NULL); |
} |
@@ -1350,12 +1252,15 @@ void LoadStubCompiler::GenerateLoadCallback( |
Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
+ Register api_function_address = rdx; |
+ __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); |
+ |
// The name handler is counted as an argument. |
StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); |
Operand return_value_operand = args.GetArgumentOperand( |
PropertyCallbackArguments::kArgsLength - 1 - |
PropertyCallbackArguments::kReturnValueOffset); |
- __ CallApiFunctionAndReturn(getter_address, |
+ __ CallApiFunctionAndReturn(api_function_address, |
thunk_address, |
getter_arg, |
kStackSpace, |
@@ -1792,8 +1697,8 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback( |
Register values[] = { value() }; |
GenerateFastApiCall( |
- masm(), call_optimization, receiver(), scratch1(), |
- scratch2(), this->name(), 1, values); |
+ masm(), call_optimization, receiver(), |
+ scratch1(), 1, values); |
// Return the generated code. |
return GetCode(kind(), Code::FAST, name); |