Revision: 18847
Author: [email protected]
Date: Mon Jan 27 09:57:54 2014 UTC
Log: stub fast api calls
[email protected], [email protected]
BUG=
Review URL: https://codereview.chromium.org/140613004
http://code.google.com/p/v8/source/detail?r=18847
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Fri Jan 24 11:47:53
2014 UTC
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Mon Jan 27 09:57:54
2014 UTC
@@ -5513,6 +5513,120 @@
__ bind(&fast_elements_case);
GenerateCase(masm, FAST_ELEMENTS);
}
+
+
+void CallApiFunctionStub::Generate(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- r0 : callee
+ // -- r4 : call_data
+ // -- r2 : holder
+ // -- r3 : api_function_address
+ // -- r1 : thunk_arg
+ // -- cp : context
+ // --
+ // -- esp[0] : last argument
+ // -- ...
+ // -- esp[(argc - 1)* 4] : first argument
+ // -- esp[argc * 4] : receiver
+ // -----------------------------------
+
+ Register callee = r0;
+ Register call_data = r4;
+ Register holder = r2;
+ Register api_function_address = r3;
+ Register thunk_arg = r1;
+ Register context = cp;
+
+ int argc = ArgumentBits::decode(bit_field_);
+ bool restore_context = RestoreContextBits::decode(bit_field_);
+ bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_);
+
+ typedef FunctionCallbackArguments FCA;
+
+ STATIC_ASSERT(FCA::kContextSaveIndex == 6);
+ STATIC_ASSERT(FCA::kCalleeIndex == 5);
+ STATIC_ASSERT(FCA::kDataIndex == 4);
+ STATIC_ASSERT(FCA::kReturnValueOffset == 3);
+ STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
+ STATIC_ASSERT(FCA::kIsolateIndex == 1);
+ STATIC_ASSERT(FCA::kHolderIndex == 0);
+ STATIC_ASSERT(FCA::kArgsLength == 7);
+
+ Isolate* isolate = masm->isolate();
+
+ // context save
+ __ push(context);
+ // load context from callee
+ __ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
+
+ // callee
+ __ push(callee);
+
+ // call data
+ __ push(call_data);
+
+ Register scratch = call_data;
+ if (!call_data_undefined) {
+ __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+ }
+ // return value
+ __ push(scratch);
+ // return value default
+ __ push(scratch);
+ // isolate
+ __ mov(scratch,
+ Operand(ExternalReference::isolate_address(isolate)));
+ __ push(scratch);
+ // holder
+ __ push(holder);
+
+ // Prepare arguments.
+ __ mov(scratch, sp);
+
+ // Allocate the v8::Arguments structure in the arguments' space since
+ // it's not controlled by GC.
+ const int kApiStackSpace = 4;
+
+ FrameScope frame_scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(false, kApiStackSpace);
+
+ ASSERT(!thunk_arg.is(r0) && !api_function_address.is(r0)
&& !scratch.is(r0));
+ // r0 = FunctionCallbackInfo&
+ // Arguments is after the return address.
+ __ add(r0, sp, Operand(1 * kPointerSize));
+ // FunctionCallbackInfo::implicit_args_
+ __ str(scratch, MemOperand(r0, 0 * 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;
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type =
ExternalReference::PROFILING_API_CALL;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ masm->isolate());
+
+ AllowExternalCallThatCantCauseGC scope(masm);
+ MemOperand context_restore_operand(
+ fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
+ MemOperand return_value_operand(fp,
+ (2 + FCA::kReturnValueOffset) *
kPointerSize);
+
+ __ CallApiFunctionAndReturn(api_function_address,
+ thunk_ref,
+ thunk_arg,
+ kStackUnwindSpace,
+ return_value_operand,
+ restore_context ?
+ &context_restore_operand : NULL);
+}
#undef __
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Jan 23
13:02:27 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Jan 27
09:57:54 2014 UTC
@@ -2298,8 +2298,7 @@
void MacroAssembler::CallApiFunctionAndReturn(
- ExternalReference function,
- Address function_address,
+ Register function_address,
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
@@ -2315,7 +2314,26 @@
ExternalReference::handle_scope_level_address(isolate()),
next_address);
- ASSERT(!thunk_last_arg.is(r3));
+ ASSERT(function_address.is(r3));
+ ASSERT(thunk_last_arg.is(r1) || thunk_last_arg.is(r2));
+
+ Label profiler_disabled;
+ Label end_profiler_check;
+ bool* is_profiling_flag =
+ isolate()->cpu_profiler()->is_profiling_address();
+ STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
+ mov(r9, Operand(reinterpret_cast<int32_t>(is_profiling_flag)));
+ ldrb(r9, MemOperand(r9, 0));
+ cmp(r9, Operand(0));
+ b(eq, &profiler_disabled);
+
+ // Additional parameter is the address of the actual callback.
+ mov(r3, Operand(thunk_ref));
+ jmp(&end_profiler_check);
+
+ bind(&profiler_disabled);
+ Move(r3, function_address);
+ bind(&end_profiler_check);
// Allocate HandleScope in callee-save registers.
mov(r9, Operand(next_address));
@@ -2333,25 +2351,6 @@
CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
PopSafepointRegisters();
}
-
- Label profiler_disabled;
- Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- mov(r3, Operand(reinterpret_cast<int32_t>(is_profiling_flag)));
- ldrb(r3, MemOperand(r3, 0));
- cmp(r3, Operand(0));
- b(eq, &profiler_disabled);
-
- // Additional parameter is the address of the actual callback.
- mov(thunk_last_arg,
Operand(reinterpret_cast<int32_t>(function_address)));
- mov(r3, Operand(thunk_ref));
- jmp(&end_profiler_check);
-
- bind(&profiler_disabled);
- mov(r3, Operand(function));
- bind(&end_profiler_check);
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Jan 15
17:00:35 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Jan 27
09:57:54 2014 UTC
@@ -1134,8 +1134,7 @@
// from handle and propagates exceptions. Restores context. stack_space
// - space to be unwound on exit (includes the call JS arguments space
and
// the additional space allocated for the fast call).
- void CallApiFunctionAndReturn(ExternalReference function,
- Address function_address,
+ void CallApiFunctionAndReturn(Register function_address,
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Jan 24 11:47:53
2014 UTC
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon Jan 27 09:57:54
2014 UTC
@@ -775,129 +775,58 @@
ExternalReference(IC_Utility(id), masm->isolate()),
StubCache::kInterceptorArgsLength);
}
-
-
-static const int kFastApiCallArguments =
FunctionCallbackArguments::kArgsLength;
static void GenerateFastApiCallBody(MacroAssembler* masm,
const CallOptimization& optimization,
int argc,
- Register holder,
- Register scratch1,
- Register scratch2,
- Register scratch3,
+ Register holder_in,
bool restore_context) {
- // ----------- S t a t e -------------
- // -- sp[0] : last JS argument
- // -- ...
- // -- sp[(argc - 1) * 4] : first JS argument
- // -- sp[argc * 4] : receiver
- // -----------------------------------
ASSERT(optimization.is_simple_api_call());
- typedef FunctionCallbackArguments FCA;
+ // Abi for CallApiFunctionStub.
+ Register callee = r0;
+ Register call_data = r4;
+ Register holder = r2;
+ Register api_function_address = r3;
+ Register thunk_arg = r1;
- 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);
+ // Put holder in place.
+ __ Move(holder, holder_in);
- ASSERT(!holder.is(cp));
-
- // Save calling context.
- __ push(cp);
- // Get the function and setup the context.
+ Isolate* isolate = masm->isolate();
Handle<JSFunction> function = optimization.constant_function();
- __ Move(scratch1, function);
- __ ldr(cp, FieldMemOperand(scratch1, JSFunction::kContextOffset));
- __ push(scratch1);
-
- // Construct the FunctionCallbackInfo.
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
- Handle<Object> call_data(api_call_info->data(), masm->isolate());
+ Handle<Object> call_data_obj(api_call_info->data(), isolate);
+
+ // Put callee in place.
+ __ Move(callee, function);
+
bool call_data_undefined = false;
- if (masm->isolate()->heap()->InNewSpace(*call_data)) {
- __ Move(scratch1, api_call_info);
- __ ldr(scratch1, FieldMemOperand(scratch1,
CallHandlerInfo::kDataOffset));
- } else if (call_data->IsUndefined()) {
+ // Put call_data in place.
+ if (isolate->heap()->InNewSpace(*call_data_obj)) {
+ __ Move(call_data, api_call_info);
+ __ ldr(call_data, FieldMemOperand(call_data,
CallHandlerInfo::kDataOffset));
+ } else if (call_data_obj->IsUndefined()) {
call_data_undefined = true;
- __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex);
+ __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
} else {
- __ Move(scratch1, call_data);
+ __ Move(call_data, call_data_obj);
}
- // Store call data.
- __ push(scratch1);
- if (!call_data_undefined) {
- __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
- }
- // Store ReturnValue default and ReturnValue.
- __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
- __ push(scratch1);
- __ push(scratch1);
- // Store isolate.
- __ mov(scratch1,
- Operand(ExternalReference::isolate_address(masm->isolate())));
- __ push(scratch1);
- // holder
- __ push(holder);
- // Prepare arguments.
- __ mov(r2, sp);
-
- // Allocate the v8::Arguments structure in the arguments' space since
- // it's not controlled by GC.
- const int kApiStackSpace = 4;
-
- FrameScope frame_scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(false, kApiStackSpace);
-
- // r0 = FunctionCallbackInfo&
- // Arguments is after the return address.
- __ add(r0, sp, Operand(1 * kPointerSize));
- // FunctionCallbackInfo::implicit_args_
- __ str(r2, MemOperand(r0, 0 * kPointerSize));
- // FunctionCallbackInfo::values_
- __ add(ip, r2, Operand((kFastApiCallArguments - 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 + kFastApiCallArguments + 1;
+ // Put api_function_address in place.
Address function_address =
v8::ToCData<Address>(api_call_info->callback());
ApiFunction fun(function_address);
ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
ExternalReference ref = ExternalReference(&fun,
type,
masm->isolate());
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type =
ExternalReference::PROFILING_API_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ __ mov(api_function_address, Operand(ref));
+ __ mov(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
- AllowExternalCallThatCantCauseGC scope(masm);
- MemOperand context_restore_operand(
- fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
- MemOperand return_value_operand(fp,
- (2 + FCA::kReturnValueOffset) *
kPointerSize);
-
- __ CallApiFunctionAndReturn(ref,
- function_address,
- thunk_ref,
- r1,
- kStackUnwindSpace,
- return_value_operand,
- restore_context ?
- &context_restore_operand : NULL);
+ // Jump to stub.
+ CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
+ __ TailCallStub(&stub);
}
@@ -911,7 +840,7 @@
__ IncrementCounter(counters->call_const_fast_api(), 1, r0, r1);
// Move holder to a register
- Register holder_reg = r0;
+ Register holder_reg = r2;
switch (holder_lookup) {
case CallOptimization::kHolderIsReceiver:
{
@@ -938,9 +867,6 @@
optimization,
argc,
holder_reg,
- r1,
- r2,
- r3,
false);
}
@@ -961,21 +887,11 @@
ASSERT(!scratch.is(arg));
__ push(arg);
}
- Register scratch1 = r0;
- Register scratch2 = r1;
- Register scratch3 = r2;
- if (!r3.is(receiver)) {
- __ mov(r3, receiver);
- receiver = r3;
- }
// Stack now matches JSFunction abi.
GenerateFastApiCallBody(masm,
optimization,
argc,
receiver,
- scratch1,
- scratch2,
- scratch3,
true);
}
@@ -1423,6 +1339,10 @@
ApiFunction fun(getter_address);
ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
ExternalReference ref = ExternalReference(&fun, type, isolate());
+ Register getter_address_reg = r3;
+ Register thunk_last_arg = r2;
+ __ mov(getter_address_reg, Operand(ref));
+ __ mov(thunk_last_arg,
Operand(reinterpret_cast<int32_t>(getter_address)));
Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
ExternalReference::Type thunk_type =
@@ -1430,10 +1350,9 @@
ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
isolate());
- __ CallApiFunctionAndReturn(ref,
- getter_address,
+ __ CallApiFunctionAndReturn(getter_address_reg,
thunk_ref,
- r2,
+ thunk_last_arg,
kStackUnwindSpace,
MemOperand(fp, 6 * kPointerSize),
NULL);
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Thu Jan 23 08:36:22 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Mon Jan 27 09:57:54 2014 UTC
@@ -96,6 +96,7 @@
V(InternalArrayConstructor) \
V(ProfileEntryHook) \
V(StoreGlobal) \
+ V(CallApiFunction) \
/* IC Handler stubs */ \
V(LoadField) \
V(KeyedLoadField) \
@@ -1035,6 +1036,32 @@
};
+class CallApiFunctionStub : public PlatformCodeStub {
+ public:
+ CallApiFunctionStub(bool restore_context,
+ bool call_data_undefined,
+ int argc) {
+ bit_field_ =
+ RestoreContextBits::encode(restore_context) |
+ CallDataUndefinedBits::encode(call_data_undefined) |
+ ArgumentBits::encode(argc);
+ }
+
+ private:
+ virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
+ virtual Major MajorKey() V8_OVERRIDE { return CallApiFunction; }
+ virtual int MinorKey() V8_OVERRIDE { return bit_field_; }
+
+ class RestoreContextBits: public BitField<bool, 0, 1> {};
+ class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
+ class ArgumentBits: public BitField<int, 2, Code::kArgumentsBits> {};
+
+ int bit_field_;
+
+ DISALLOW_COPY_AND_ASSIGN(CallApiFunctionStub);
+};
+
+
class KeyedLoadFieldStub: public LoadFieldStub {
public:
KeyedLoadFieldStub(bool inobject, int index, Representation
representation)
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Fri Jan 24 11:47:53
2014 UTC
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Jan 27 09:57:54
2014 UTC
@@ -5380,6 +5380,122 @@
__ bind(&fast_elements_case);
GenerateCase(masm, FAST_ELEMENTS);
}
+
+
+void CallApiFunctionStub::Generate(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- eax : callee
+ // -- ebx : call_data
+ // -- ecx : holder
+ // -- edx : api_function_address
+ // -- esi : context
+ // --
+ // -- esp[0] : return address
+ // -- esp[4] : last argument
+ // -- ...
+ // -- esp[argc * 4] : first argument
+ // -- esp[(argc + 1) * 4] : receiver
+ // -----------------------------------
+
+ Register callee = eax;
+ Register call_data = ebx;
+ Register holder = ecx;
+ Register api_function_address = edx;
+ Register return_address = edi;
+ Register context = esi;
+
+ int argc = ArgumentBits::decode(bit_field_);
+ bool restore_context = RestoreContextBits::decode(bit_field_);
+ bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_);
+
+ typedef FunctionCallbackArguments FCA;
+
+ STATIC_ASSERT(FCA::kContextSaveIndex == 6);
+ STATIC_ASSERT(FCA::kCalleeIndex == 5);
+ STATIC_ASSERT(FCA::kDataIndex == 4);
+ STATIC_ASSERT(FCA::kReturnValueOffset == 3);
+ STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
+ STATIC_ASSERT(FCA::kIsolateIndex == 1);
+ STATIC_ASSERT(FCA::kHolderIndex == 0);
+ STATIC_ASSERT(FCA::kArgsLength == 7);
+
+ Isolate* isolate = masm->isolate();
+
+ __ pop(return_address);
+
+ // context save
+ __ push(context);
+ // load context from callee
+ __ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
+
+ // callee
+ __ push(callee);
+
+ // call data
+ __ push(call_data);
+
+ Register scratch = call_data;
+ if (!call_data_undefined) {
+ // return value
+ __ push(Immediate(isolate->factory()->undefined_value()));
+ // return value default
+ __ push(Immediate(isolate->factory()->undefined_value()));
+ } else {
+ // return value
+ __ push(scratch);
+ // return value default
+ __ push(scratch);
+ }
+ // isolate
+ __ push(Immediate(reinterpret_cast<int>(isolate)));
+ // holder
+ __ push(holder);
+
+ __ mov(scratch, esp);
+
+ // return address
+ __ push(return_address);
+
+ // API function gets reference to the v8::Arguments. If CPU profiler
+ // is enabled wrapper function will be called and we need to pass
+ // address of the callback as additional parameter, always allocate
+ // space for it.
+ const int kApiArgc = 1 + 1;
+
+ // Allocate the v8::Arguments structure in the arguments' space since
+ // it's not controlled by GC.
+ const int kApiStackSpace = 4;
+
+ __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
+
+ // FunctionCallbackInfo::implicit_args_.
+ __ mov(ApiParameterOperand(2), scratch);
+ __ add(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize));
+ // FunctionCallbackInfo::values_.
+ __ mov(ApiParameterOperand(3), scratch);
+ // FunctionCallbackInfo::length_.
+ __ Set(ApiParameterOperand(4), Immediate(argc));
+ // FunctionCallbackInfo::is_construct_call_.
+ __ Set(ApiParameterOperand(5), Immediate(0));
+
+ // v8::InvocationCallback's argument.
+ __ lea(scratch, ApiParameterOperand(2));
+ __ mov(ApiParameterOperand(0), scratch);
+
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+
+ Operand context_restore_operand(ebp,
+ (2 + FCA::kContextSaveIndex) *
kPointerSize);
+ Operand return_value_operand(ebp,
+ (2 + FCA::kReturnValueOffset) *
kPointerSize);
+ __ CallApiFunctionAndReturn(api_function_address,
+ thunk_address,
+ ApiParameterOperand(1),
+ argc + FCA::kArgsLength + 1,
+ return_value_operand,
+ restore_context ?
+ &context_restore_operand : NULL);
+}
#undef __
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Thu Jan 23
13:02:27 2014 UTC
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon Jan 27
09:57:54 2014 UTC
@@ -2297,7 +2297,7 @@
void MacroAssembler::CallApiFunctionAndReturn(
- Address function_address,
+ Register function_address,
Address thunk_address,
Operand thunk_last_arg,
int stack_space,
@@ -2310,6 +2310,7 @@
ExternalReference level_address =
ExternalReference::handle_scope_level_address(isolate());
+ ASSERT(edx.is(function_address));
// Allocate HandleScope in callee-save registers.
mov(ebx, Operand::StaticVariable(next_address));
mov(edi, Operand::StaticVariable(limit_address));
@@ -2336,14 +2337,14 @@
j(zero, &profiler_disabled);
// Additional parameter is the address of the actual getter function.
- mov(thunk_last_arg, Immediate(function_address));
+ mov(thunk_last_arg, function_address);
// Call the api function.
call(thunk_address, RelocInfo::RUNTIME_ENTRY);
jmp(&end_profiler_check);
bind(&profiler_disabled);
// Call the api function.
- call(function_address, RelocInfo::RUNTIME_ENTRY);
+ call(function_address);
bind(&end_profiler_check);
if (FLAG_log_timer_events) {
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Wed Jan 15
17:00:35 2014 UTC
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Mon Jan 27
09:57:54 2014 UTC
@@ -815,7 +815,7 @@
// from handle and propagates exceptions. Clobbers ebx, edi and
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
- void CallApiFunctionAndReturn(Address function_address,
+ void CallApiFunctionAndReturn(Register function_address,
Address thunk_address,
Operand thunk_last_arg,
int stack_space,
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri Jan 24 11:47:53
2014 UTC
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon Jan 27 09:57:54
2014 UTC
@@ -412,20 +412,55 @@
ExternalReference(IC_Utility(id), masm->isolate()),
StubCache::kInterceptorArgsLength);
}
-
-
-// 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 = eax;
+ Register call_data = ebx;
+ Register holder = ecx;
+ Register api_function_address = edx;
+
+ // Put holder in place.
+ __ Move(holder, holder_in);
+
+ Register scratch = edi;
+
+ 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.
+ __ LoadHeapObject(callee, function);
+
+ bool call_data_undefined = false;
+ // Put call_data in place.
+ if (isolate->heap()->InNewSpace(*call_data_obj)) {
+ __ mov(scratch, api_call_info);
+ __ mov(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset));
+ } else if (call_data_obj->IsUndefined()) {
+ call_data_undefined = true;
+ __ mov(call_data, Immediate(isolate->factory()->undefined_value()));
+ } else {
+ __ mov(call_data, call_data_obj);
+ }
+
+ // Put api_function_address in place.
+ Address function_address =
v8::ToCData<Address>(api_call_info->callback());
+ __ mov(api_function_address, Immediate(function_address));
+
+ // Jump to stub.
+ CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
+ __ TailCallStub(&stub);
+}
+
// Generates call to API function.
static void GenerateFastApiCall(MacroAssembler* masm,
@@ -437,7 +472,7 @@
__ IncrementCounter(counters->call_const_fast_api(), 1);
// Move holder to a register
- Register holder_reg = eax;
+ Register holder_reg = ecx;
switch (holder_lookup) {
case CallOptimization::kHolderIsReceiver:
{
@@ -463,9 +498,6 @@
optimization,
argc,
holder_reg,
- ebx,
- ecx,
- edx,
false);
}
@@ -478,8 +510,6 @@
const CallOptimization& optimization,
Register receiver,
Register scratch1,
- Register scratch2,
- Register scratch3,
int argc,
Register* values) {
// Copy return value.
@@ -491,8 +521,6 @@
Register arg = values[argc-1-i];
ASSERT(!receiver.is(arg));
ASSERT(!scratch1.is(arg));
- ASSERT(!scratch2.is(arg));
- ASSERT(!scratch3.is(arg));
__ push(arg);
}
__ push(scratch1);
@@ -501,123 +529,9 @@
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 -------------
- // -- esp[0] : return address
- // -- esp[4] : last argument
- // -- ...
- // -- esp[argc * 4] : first argument
- // -- esp[(argc + 1) * 4] : 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);
-
- __ pop(scratch1);
-
- ASSERT(!holder.is(esi));
- // context save
- __ push(esi);
-
- // Get the function and setup the context.
- Handle<JSFunction> function = optimization.constant_function();
- __ LoadHeapObject(scratch2, function);
- __ mov(esi, FieldOperand(scratch2, JSFunction::kContextOffset));
- // callee
- __ push(scratch2);
-
- 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.
- if (isolate->heap()->InNewSpace(*call_data)) {
- __ mov(scratch2, api_call_info);
- __ mov(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset));
- __ push(scratch3);
- } else {
- __ push(Immediate(call_data));
- }
- // return value
- __ push(Immediate(isolate->factory()->undefined_value()));
- // return value default
- __ push(Immediate(isolate->factory()->undefined_value()));
- // isolate
- __ push(Immediate(reinterpret_cast<int>(isolate)));
- // holder
- __ push(holder);
-
- // store receiver address for GenerateFastApiCallBody
- ASSERT(!scratch1.is(eax));
- __ mov(eax, esp);
-
- // return address
- __ push(scratch1);
-
- // API function gets reference to the v8::Arguments. If CPU profiler
- // is enabled wrapper function will be called and we need to pass
- // address of the callback as additional parameter, always allocate
- // space for it.
- const int kApiArgc = 1 + 1;
-
- // Allocate the v8::Arguments structure in the arguments' space since
- // it's not controlled by GC.
- const int kApiStackSpace = 4;
-
- // Function address is a foreign pointer outside V8's heap.
- Address function_address =
v8::ToCData<Address>(api_call_info->callback());
- __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
-
- // FunctionCallbackInfo::implicit_args_.
- __ mov(ApiParameterOperand(2), eax);
- __ add(eax, Immediate((argc + kFastApiCallArguments - 1) *
kPointerSize));
- // FunctionCallbackInfo::values_.
- __ mov(ApiParameterOperand(3), eax);
- // FunctionCallbackInfo::length_.
- __ Set(ApiParameterOperand(4), Immediate(argc));
- // FunctionCallbackInfo::is_construct_call_.
- __ Set(ApiParameterOperand(5), Immediate(0));
-
- // v8::InvocationCallback's argument.
- __ lea(eax, ApiParameterOperand(2));
- __ mov(ApiParameterOperand(0), eax);
-
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
-
- Operand context_restore_operand(ebp,
- (2 + FCA::kContextSaveIndex) *
kPointerSize);
- Operand return_value_operand(ebp,
- (2 + FCA::kReturnValueOffset) *
kPointerSize);
- __ CallApiFunctionAndReturn(function_address,
- thunk_address,
- ApiParameterOperand(1),
- argc + kFastApiCallArguments + 1,
- return_value_operand,
- restore_context ?
- &context_restore_operand : NULL);
-}
-
class CallInterceptorCompiler BASE_EMBEDDED {
public:
@@ -1361,8 +1275,8 @@
void LoadStubCompiler::GenerateLoadCallback(
const CallOptimization& call_optimization) {
GenerateFastApiCall(
- masm(), call_optimization, receiver(), scratch1(),
- scratch2(), name(), 0, NULL);
+ masm(), call_optimization, receiver(),
+ scratch1(), 0, NULL);
}
@@ -1410,7 +1324,6 @@
// CPU profiler is active.
const int kApiArgc = 2 + 1;
- Address getter_address = v8::ToCData<Address>(callback->getter());
__ PrepareCallApiFunction(kApiArgc);
__ mov(ApiParameterOperand(0), ebx); // name.
__ add(ebx, Immediate(kPointerSize));
@@ -1421,6 +1334,10 @@
// garbage collection but instead return the allocation failure
// object.
+ Register getter_address = edx;
+ Address function_address = v8::ToCData<Address>(callback->getter());
+ __ mov(getter_address, Immediate(function_address));
+
Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
__ CallApiFunctionAndReturn(getter_address,
@@ -1876,8 +1793,8 @@
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);
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Fri Jan 24 11:47:53
2014 UTC
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Mon Jan 27 09:57:54
2014 UTC
@@ -5220,6 +5220,121 @@
__ bind(&fast_elements_case);
GenerateCase(masm, FAST_ELEMENTS);
}
+
+
+void CallApiFunctionStub::Generate(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : callee
+ // -- rbx : call_data
+ // -- rcx : holder
+ // -- rdx : api_function_address
+ // -- rsi : context
+ // --
+ // -- rsp[0] : return address
+ // -- rsp[8] : last argument
+ // -- ...
+ // -- rsp[argc * 8] : first argument
+ // -- rsp[(argc + 1) * 8] : receiver
+ // -----------------------------------
+
+ Register callee = rax;
+ Register call_data = rbx;
+ Register holder = rcx;
+ Register api_function_address = rdx;
+ Register return_address = rdi;
+ Register context = rsi;
+
+ int argc = ArgumentBits::decode(bit_field_);
+ bool restore_context = RestoreContextBits::decode(bit_field_);
+ bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_);
+
+ typedef FunctionCallbackArguments FCA;
+
+ STATIC_ASSERT(FCA::kContextSaveIndex == 6);
+ STATIC_ASSERT(FCA::kCalleeIndex == 5);
+ STATIC_ASSERT(FCA::kDataIndex == 4);
+ STATIC_ASSERT(FCA::kReturnValueOffset == 3);
+ STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
+ STATIC_ASSERT(FCA::kIsolateIndex == 1);
+ STATIC_ASSERT(FCA::kHolderIndex == 0);
+ STATIC_ASSERT(FCA::kArgsLength == 7);
+
+ __ PopReturnAddressTo(return_address);
+
+ // context save
+ __ push(context);
+ // load context from callee
+ __ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
+
+ // callee
+ __ push(callee);
+
+ // call data
+ __ push(call_data);
+ Register scratch = call_data;
+ if (!call_data_undefined) {
+ __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+ }
+ // return value
+ __ push(scratch);
+ // return value default
+ __ push(scratch);
+ // 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);
+
+ // Allocate the v8::Arguments structure in the arguments' space since
+ // it's not controlled by GC.
+ const int kApiStackSpace = 4;
+
+ __ PrepareCallApiFunction(kApiStackSpace);
+
+ // FunctionCallbackInfo::implicit_args_.
+ __ movp(StackSpaceOperand(0), scratch);
+ __ addq(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 defined(__MINGW64__) || defined(_WIN64)
+ Register arguments_arg = rcx;
+ Register callback_arg = rdx;
+#else
+ Register arguments_arg = rdi;
+ Register callback_arg = rsi;
+#endif
+
+ // It's okay if callback_arg == api_function_address
+ // but not arguments_arg
+ ASSERT(!api_function_address.is(arguments_arg));
+
+ // v8::InvocationCallback's argument.
+ __ lea(arguments_arg, StackSpaceOperand(0));
+
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+
+ StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength,
+ ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ Operand context_restore_operand = args_from_rbp.GetArgumentOperand(
+ FCA::kArgsLength - 1 - FCA::kContextSaveIndex);
+ Operand return_value_operand = args_from_rbp.GetArgumentOperand(
+ FCA::kArgsLength - 1 - FCA::kReturnValueOffset);
+ __ CallApiFunctionAndReturn(
+ api_function_address,
+ thunk_address,
+ callback_arg,
+ argc + FCA::kArgsLength + 1,
+ return_value_operand,
+ restore_context ? &context_restore_operand : NULL);
+}
#undef __
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Jan 24
01:45:53 2014 UTC
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon Jan 27
09:57:54 2014 UTC
@@ -671,7 +671,7 @@
void MacroAssembler::CallApiFunctionAndReturn(
- Address function_address,
+ Register function_address,
Address thunk_address,
Register thunk_last_arg,
int stack_space,
@@ -697,6 +697,7 @@
ExternalReference scheduled_exception_address =
ExternalReference::scheduled_exception_address(isolate());
+ ASSERT(rdx.is(function_address));
// Allocate HandleScope in callee-save registers.
Register prev_next_address_reg = r14;
Register prev_limit_reg = rbx;
@@ -726,14 +727,13 @@
j(zero, &profiler_disabled);
// Third parameter is the address of the actual getter function.
- Move(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE);
+ Move(thunk_last_arg, function_address);
Move(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE);
jmp(&end_profiler_check);
bind(&profiler_disabled);
// Call the api function!
- Move(rax, reinterpret_cast<Address>(function_address),
- RelocInfo::EXTERNAL_REFERENCE);
+ Move(rax, function_address);
bind(&end_profiler_check);
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Fri Jan 24
01:45:53 2014 UTC
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon Jan 27
09:57:54 2014 UTC
@@ -1309,7 +1309,7 @@
// from handle and propagates exceptions. Clobbers r14, r15, rbx and
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
- void CallApiFunctionAndReturn(Address function_address,
+ void CallApiFunctionAndReturn(Register function_address,
Address thunk_address,
Register thunk_last_arg,
int stack_space,
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon Jan 27 08:12:59
2014 UTC
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon Jan 27 09:57:54
2014 UTC
@@ -386,20 +386,55 @@
ExternalReference(IC_Utility(id), masm->isolate()),
StubCache::kInterceptorArgsLength);
}
-
-
-// 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 @@
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 @@
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,132 +501,9 @@
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:
@@ -1279,7 +1181,7 @@
const CallOptimization& call_optimization) {
GenerateFastApiCall(
masm(), call_optimization, receiver(),
- scratch1(), scratch2(), name(), 0, NULL);
+ scratch1(), 0, NULL);
}
@@ -1350,12 +1252,15 @@
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 @@
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);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.