Revert of Rework CallApi*Stubs. (patchset #5 id:100001 of https://codereview.chromium.org/1748123003/ )

Reason for revert:
Breaks Chromium.

Original issue's description:
> Rework CallApi*Stubs.
>
> - Eliminate stubs with a variable number of arguments.
>   (That only worked due to their very limited use. These
>    stubs' interface descriptors were basically lying
>    about their number of args, which will fail when used
>    generically.)
> - Fix all CallApi*Stubs' interface descriptors to no
>   longer lie about their arguments.
> - Unify CallApi*Stub, for * in Function, Accessor,
>   FunctionWithFixedArgs.
>   (Since these are now all doing the same thing.)
> - Rename the unified stub (and interface descriptors) to
>   *ApiCallback*, since that's really what they're doing.
> - Refuse inlining an API callback if its number of
>   parameters exceeds the supported number of args.
>
> BUG=
>
> Committed: https://crrev.com/d238b953a474272c0e3ea22ef6a9b63fa9729340
> Cr-Commit-Position: refs/heads/master@{#34614}

TBR=danno@chromium.org,jkummerow@chromium.org,mstarzinger@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

Review URL: https://codereview.chromium.org/1775933005

Cr-Commit-Position: refs/heads/master@{#34624}
This commit is contained in:
vogelheim 2016-03-09 06:58:43 -08:00 committed by Commit bot
parent 40a9b8d170
commit 52a741d18e
32 changed files with 767 additions and 336 deletions

View File

@ -5418,12 +5418,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- r0 : callee
// -- r4 : call_data
// -- r2 : holder
// -- r1 : api_function_address
// -- r3 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5449,9 +5453,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || r3.is(argc.reg()));
// context save
__ push(context);
if (!is_lazy()) {
if (!is_lazy) {
// load context from callee
__ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -5463,7 +5469,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(call_data);
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// return value
@ -5492,15 +5498,29 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ 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));
if (argc.is_immediate()) {
// FunctionCallbackInfo::values_
__ add(ip, scratch,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ str(ip, MemOperand(r0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ mov(ip, Operand(argc.immediate()));
__ str(ip, MemOperand(r0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ mov(ip, Operand::Zero());
__ str(ip, MemOperand(r0, 3 * kPointerSize));
} else {
// FunctionCallbackInfo::values_
__ add(ip, scratch, Operand(argc.reg(), LSL, kPointerSizeLog2));
__ add(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
__ str(ip, MemOperand(r0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ str(argc.reg(), MemOperand(r0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ add(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
__ mov(ip, Operand(argc.reg(), LSL, kPointerSizeLog2));
__ str(ip, MemOperand(r0, 3 * kPointerSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5510,7 +5530,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5519,15 +5539,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
int stack_space = 0;
MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize);
MemOperand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,
&context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(r3), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -401,7 +401,25 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
&default_descriptor);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
Register registers[] = {
r0, // callee
r4, // call_data
r2, // holder
r1, // api_function_address
r3, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers,
&default_descriptor);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);

View File

@ -5799,12 +5799,16 @@ static void CallApiFunctionAndReturn(
__ B(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- x0 : callee
// -- x4 : call_data
// -- x2 : holder
// -- x1 : api_function_address
// -- x3 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5830,15 +5834,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || x3.is(argc.reg()));
// FunctionCallbackArguments: context, callee and call data.
__ Push(context, callee, call_data);
if (!is_lazy()) {
if (!is_lazy) {
// Load context from callee
__ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
}
Register isolate_reg = x5;
@ -5867,13 +5873,26 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// x0 = FunctionCallbackInfo&
// Arguments is after the return address.
__ Add(x0, masm->StackPointer(), 1 * kPointerSize);
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
__ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
// FunctionCallbackInfo::length_ = argc and
// FunctionCallbackInfo::is_construct_call = 0
__ Mov(x10, argc());
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
if (argc.is_immediate()) {
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
__ Add(x10, args,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
// FunctionCallbackInfo::length_ = argc and
// FunctionCallbackInfo::is_construct_call = 0
__ Mov(x10, argc.immediate());
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
} else {
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
__ Add(x10, args, Operand(argc.reg(), LSL, kPointerSizeLog2));
__ Add(x10, x10, (FCA::kArgsLength - 1) * kPointerSize);
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
// FunctionCallbackInfo::length_ = argc and
// FunctionCallbackInfo::is_construct_call
__ Add(x10, argc.reg(), FCA::kArgsLength + 1);
__ Mov(x10, Operand(x10, LSL, kPointerSizeLog2));
__ Stp(argc.reg(), x10, MemOperand(x0, 2 * kPointerSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5883,7 +5902,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5893,8 +5912,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
MemOperand is_construct_call_operand =
MemOperand(masm->StackPointer(), 4 * kPointerSize);
MemOperand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
const int spill_offset = 1 + kApiStackSpace;
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
@ -5903,6 +5924,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(x3), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -436,7 +436,25 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
&default_descriptor);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
Register registers[] = {
x0, // callee
x4, // call_data
x2, // holder
x1, // api_function_address
x3, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers,
&default_descriptor);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);

View File

@ -23,7 +23,8 @@ namespace internal {
/* PlatformCodeStubs */ \
V(ArrayConstructor) \
V(BinaryOpICWithAllocationSite) \
V(CallApiCallback) \
V(CallApiFunction) \
V(CallApiAccessor) \
V(CallApiGetter) \
V(CallConstruct) \
V(CallIC) \
@ -1532,36 +1533,48 @@ class StoreGlobalViaContextStub final : public PlatformCodeStub {
DEFINE_PLATFORM_CODE_STUB(StoreGlobalViaContext, PlatformCodeStub);
};
class CallApiCallbackStub : public PlatformCodeStub {
class CallApiFunctionStub : public PlatformCodeStub {
public:
static const int kArgBits = 3;
static const int kArgMax = (1 << kArgBits) - 1;
// CallApiCallbackStub for regular setters and getters.
CallApiCallbackStub(Isolate* isolate, bool is_store, bool call_data_undefined,
bool is_lazy)
: CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store,
call_data_undefined, is_lazy) {}
// CallApiCallbackStub for callback functions.
CallApiCallbackStub(Isolate* isolate, int argc, bool call_data_undefined)
: CallApiCallbackStub(isolate, argc, false, call_data_undefined, false) {}
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
return ApiCallbackDescriptorBase::ForArgs(isolate(), argc());
explicit CallApiFunctionStub(Isolate* isolate, bool call_data_undefined)
: PlatformCodeStub(isolate) {
minor_key_ = CallDataUndefinedBits::encode(call_data_undefined);
}
private:
CallApiCallbackStub(Isolate* isolate, int argc, bool is_store,
bool call_data_undefined, bool is_lazy)
bool call_data_undefined() const {
return CallDataUndefinedBits::decode(minor_key_);
}
class CallDataUndefinedBits : public BitField<bool, 0, 1> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction);
DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub);
};
class CallApiAccessorStub : public PlatformCodeStub {
public:
CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined,
bool is_lazy)
: PlatformCodeStub(isolate) {
CHECK(0 <= argc && argc <= kArgMax);
minor_key_ = IsStoreBits::encode(is_store) |
CallDataUndefinedBits::encode(call_data_undefined) |
ArgumentBits::encode(argc) |
ArgumentBits::encode(is_store ? 1 : 0) |
IsLazyAccessorBits::encode(is_lazy);
}
protected:
// For CallApiFunctionWithFixedArgsStub, see below.
static const int kArgBits = 3;
CallApiAccessorStub(Isolate* isolate, int argc, bool call_data_undefined)
: PlatformCodeStub(isolate) {
minor_key_ = IsStoreBits::encode(false) |
CallDataUndefinedBits::encode(call_data_undefined) |
ArgumentBits::encode(argc);
}
private:
bool is_store() const { return IsStoreBits::decode(minor_key_); }
bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
bool call_data_undefined() const {
@ -1574,10 +1587,29 @@ class CallApiCallbackStub : public PlatformCodeStub {
class ArgumentBits : public BitField<int, 2, kArgBits> {};
class IsLazyAccessorBits : public BitField<bool, 3 + kArgBits, 1> {};
DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiAccessor);
DEFINE_PLATFORM_CODE_STUB(CallApiAccessor, PlatformCodeStub);
};
// TODO(dcarney): see if it's possible to remove this later without performance
// degradation.
// This is not a real stub, but a way of generating the CallApiAccessorStub
// (which has the same abi) which makes it clear that it is not an accessor.
class CallApiFunctionWithFixedArgsStub : public CallApiAccessorStub {
public:
static const int kMaxFixedArgs = (1 << kArgBits) - 1;
CallApiFunctionWithFixedArgsStub(Isolate* isolate, int argc,
bool call_data_undefined)
: CallApiAccessorStub(isolate, argc, call_data_undefined) {
DCHECK(0 <= argc && argc <= kMaxFixedArgs);
}
};
typedef ApiAccessorDescriptor ApiFunctionWithFixedArgsDescriptor;
class CallApiGetterStub : public PlatformCodeStub {
public:
explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}

View File

@ -5,7 +5,7 @@
#include "src/compiler/fast-accessor-assembler.h"
#include "src/base/logging.h"
#include "src/code-stubs.h" // For CallApiCallbackStub.
#include "src/code-stubs.h" // For CallApiFunctionStub.
#include "src/compiler/graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
@ -172,8 +172,7 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
CHECK_EQ(kBuilding, state_);
// Create API function stub.
CallApiCallbackStub stub(assembler_->isolate(), 1, true);
DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount());
CallApiFunctionStub stub(assembler_->isolate(), true);
// Wrap the FunctionCallback in an ExternalReference.
ApiFunction callback_api_function(FUNCTION_ADDR(callback_function));
@ -181,27 +180,30 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
ExternalReference::DIRECT_API_CALL,
assembler_->isolate());
// The stub has 6 parameters.
// See: ApiCallbackDescriptorBase::BuildCallInterfaceDescriptorFunctionType
// The stub has 5 parameters, and kJSParam (here: 1) parameters to pass
// through to the callback.
// See: ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType
static const int kStackParam = 1;
Node* args[] = {
// Stub/register parameters:
assembler_->Parameter(0), /* receiver (use accessor's) */
assembler_->UndefinedConstant(), /* call_data (undefined) */
assembler_->NullConstant(), /* holder (null) */
assembler_->ExternalConstant(callback), /* API callback function */
assembler_->Parameter(0), /* receiver (use accessor's) */
assembler_->UndefinedConstant(), /* call_data (undefined) */
assembler_->NullConstant(), /* holder (null) */
assembler_->ExternalConstant(callback), /* API callback function */
assembler_->IntPtrConstant(kStackParam), /* # JS arguments */
// JS arguments, on stack:
// kStackParam stack parameter(s):
FromId(arg),
// Context parameter. (See Linkage::GetStubCallDescriptor.)
assembler_->UndefinedConstant()};
DCHECK_EQ(arraysize(args),
1 + stub.GetCallInterfaceDescriptor().GetParameterCount());
CHECK_EQ(5 + kStackParam + 1, arraysize(args));
Node* call = assembler_->CallN(
Linkage::GetStubCallDescriptor(
assembler_->isolate(), zone(), stub.GetCallInterfaceDescriptor(),
stub.GetStackParameterCount(), CallDescriptor::kNoFlags),
kStackParam + stub.GetStackParameterCount(),
CallDescriptor::kNoFlags),
assembler_->HeapConstant(stub.GetCode()), args);
return FromRaw(call);
}

View File

@ -9231,10 +9231,6 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
if (syntactic_tail_call_mode == TailCallMode::kAllow) {
return false;
}
if (argc > CallApiCallbackStub::kArgMax) {
return false;
}
CallOptimization optimization(function);
if (!optimization.is_simple_api_call()) return false;
Handle<Map> holder_map;
@ -9330,23 +9326,34 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
api_function_address, nullptr};
HInstruction* call = nullptr;
CHECK(argc <= CallApiCallbackStub::kArgMax);
if (!is_function) {
CallApiCallbackStub stub(isolate(), is_store, call_data_undefined,
CallApiAccessorStub stub(isolate(), is_store, call_data_undefined,
!optimization.is_constant_call());
Handle<Code> code = stub.GetCode();
HConstant* code_value = Add<HConstant>(code);
ApiAccessorDescriptor descriptor(isolate());
call = New<HCallWithDescriptor>(
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
code_value, argc + 1, descriptor,
Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
} else {
CallApiCallbackStub stub(isolate(), argc, call_data_undefined);
} else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) {
CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined);
Handle<Code> code = stub.GetCode();
HConstant* code_value = Add<HConstant>(code);
ApiFunctionWithFixedArgsDescriptor descriptor(isolate());
call = New<HCallWithDescriptor>(
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
code_value, argc + 1, descriptor,
Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
Drop(1); // Drop function.
} else {
op_vals[arraysize(op_vals) - 1] = Add<HConstant>(argc);
CallApiFunctionStub stub(isolate(), call_data_undefined);
Handle<Code> code = stub.GetCode();
HConstant* code_value = Add<HConstant>(code);
ApiFunctionDescriptor descriptor(isolate());
call =
New<HCallWithDescriptor>(code_value, argc + 1, descriptor,
Vector<HValue*>(op_vals, arraysize(op_vals)));
Drop(1); // Drop function.
}
ast_context()->ReturnInstruction(call, ast_id);

View File

@ -5688,13 +5688,17 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- edi : callee
// -- ebx : call_data
// -- ecx : holder
// -- edx : api_function_address
// -- esi : context
// -- eax : number of arguments if argc is a register
// --
// -- esp[0] : return address
// -- esp[4] : last argument
@ -5721,9 +5725,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
__ pop(return_address);
// context save.
__ push(context);
DCHECK(argc.is_immediate() || eax.is(argc.reg()));
if (argc.is_immediate()) {
__ pop(return_address);
// context save.
__ push(context);
} else {
// pop return address and save context
__ xchg(context, Operand(esp, 0));
return_address = context;
}
// callee
__ push(callee);
@ -5732,7 +5744,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(call_data);
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
// return value
__ push(Immediate(masm->isolate()->factory()->undefined_value()));
// return value default
@ -5753,7 +5765,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// push return address
__ push(return_address);
if (!is_lazy()) {
if (!is_lazy) {
// load context from callee
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
}
@ -5772,13 +5784,27 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// FunctionCallbackInfo::implicit_args_.
__ mov(ApiParameterOperand(2), scratch);
__ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ Move(ApiParameterOperand(4), Immediate(argc()));
// FunctionCallbackInfo::is_construct_call_.
__ Move(ApiParameterOperand(5), Immediate(0));
if (argc.is_immediate()) {
__ add(scratch,
Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
// FunctionCallbackInfo::is_construct_call_.
__ Move(ApiParameterOperand(5), Immediate(0));
} else {
__ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size,
(FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ mov(ApiParameterOperand(4), argc.reg());
// FunctionCallbackInfo::is_construct_call_.
__ lea(argc.reg(), Operand(argc.reg(), times_pointer_size,
(FCA::kArgsLength + 1) * kPointerSize));
__ mov(ApiParameterOperand(5), argc.reg());
}
// v8::InvocationCallback's argument.
__ lea(scratch, ApiParameterOperand(2));
@ -5791,7 +5817,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
(2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5800,8 +5826,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
int stack_space = 0;
Operand is_construct_call_operand = ApiParameterOperand(5);
Operand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
ApiParameterOperand(1), stack_space,
stack_space_operand, return_value_operand,
@ -5809,6 +5837,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- esp[0] : return address

View File

@ -390,7 +390,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
edi, // callee
ebx, // call_data
ecx, // holder
edx, // api_function_address
eax, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
edi, // callee

View File

@ -253,7 +253,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
}
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = r0;
Register data = r4;
Register holder = r2;
@ -322,7 +322,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ mov(api_function_address, Operand(ref));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -160,7 +160,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = x0;
Register data = x4;
Register holder = x2;
@ -229,7 +229,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ Mov(api_function_address, ref);
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -161,7 +161,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
// Stack now matches JSFunction abi.
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = edi;
Register data = ebx;
Register holder = ecx;
@ -223,7 +223,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ mov(api_function_address, Immediate(function_address));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -242,7 +242,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
}
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = a0;
Register data = t0;
Register holder = a2;
@ -309,7 +309,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ li(api_function_address, Operand(ref));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -242,7 +242,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
}
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = a0;
Register data = a4;
Register holder = a2;
@ -309,7 +309,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ li(api_function_address, Operand(ref));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -246,7 +246,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
}
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = r3;
Register data = r7;
Register holder = r5;
@ -315,7 +315,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ mov(api_function_address, Operand(ref));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -231,7 +231,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
}
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = r2;
Register data = r6;
Register holder = r4;
@ -300,7 +300,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ mov(api_function_address, Operand(ref));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -142,7 +142,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ PushReturnAddressFrom(scratch);
// Stack now matches JSFunction abi.
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = rdi;
Register data = rbx;
Register holder = rcx;
@ -209,7 +209,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
RelocInfo::EXTERNAL_REFERENCE);
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -158,7 +158,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
// Stack now matches JSFunction abi.
DCHECK(optimization.is_simple_api_call());
// Abi for CallApiCallbackStub.
// Abi for CallApiFunctionStub.
Register callee = edi;
Register data = ebx;
Register holder = ecx;
@ -220,7 +220,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
__ mov(api_function_address, Immediate(function_address));
// Jump to stub.
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
!optimization.is_constant_call());
__ TailCallStub(&stub);
}

View File

@ -494,45 +494,28 @@ ArgumentAdaptorDescriptor::BuildCallInterfaceDescriptorFunctionType(
return function;
}
CallInterfaceDescriptor ApiCallbackDescriptorBase::ForArgs(Isolate* isolate,
int argc) {
switch (argc) {
case 0:
return ApiCallbackWith0ArgsDescriptor(isolate);
case 1:
return ApiCallbackWith1ArgsDescriptor(isolate);
case 2:
return ApiCallbackWith2ArgsDescriptor(isolate);
case 3:
return ApiCallbackWith3ArgsDescriptor(isolate);
case 4:
return ApiCallbackWith4ArgsDescriptor(isolate);
case 5:
return ApiCallbackWith5ArgsDescriptor(isolate);
case 6:
return ApiCallbackWith6ArgsDescriptor(isolate);
case 7:
return ApiCallbackWith7ArgsDescriptor(isolate);
default:
UNREACHABLE();
return VoidDescriptor(isolate);
}
}
FunctionType*
ApiCallbackDescriptorBase::BuildCallInterfaceDescriptorFunctionTypeWithArg(
Isolate* isolate, int parameter_count, int argc) {
FunctionType* ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone();
FunctionType* function =
Type::Function(AnyTagged(zone), Type::Undefined(), 4 + argc, zone)
->AsFunction();
Type::Function(AnyTagged(zone), Type::Undefined(), 5, zone)->AsFunction();
function->InitParameter(0, AnyTagged(zone)); // callee
function->InitParameter(1, AnyTagged(zone)); // call_data
function->InitParameter(2, AnyTagged(zone)); // holder
function->InitParameter(3, ExternalPointer(zone)); // api_function_address
function->InitParameter(4, UntaggedIntegral32(zone)); // actual #arguments
return function;
}
FunctionType* ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone();
FunctionType* function =
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
function->InitParameter(0, AnyTagged(zone)); // callee
function->InitParameter(1, AnyTagged(zone)); // call_data
function->InitParameter(2, AnyTagged(zone)); // holder
function->InitParameter(3, ExternalPointer(zone)); // api_function_address
for (int i = 0; i < argc; i++) {
function->InitParameter(i, AnyTagged(zone));
}
return function;
}

View File

@ -67,14 +67,8 @@ class PlatformInterfaceDescriptor;
V(Named) \
V(CallHandler) \
V(ArgumentAdaptor) \
V(ApiCallbackWith0Args) \
V(ApiCallbackWith1Args) \
V(ApiCallbackWith2Args) \
V(ApiCallbackWith3Args) \
V(ApiCallbackWith4Args) \
V(ApiCallbackWith5Args) \
V(ApiCallbackWith6Args) \
V(ApiCallbackWith7Args) \
V(ApiFunction) \
V(ApiAccessor) \
V(ApiGetter) \
V(LoadGlobalViaContext) \
V(StoreGlobalViaContext) \
@ -205,7 +199,6 @@ class CallInterfaceDescriptor {
void Initialize(Isolate* isolate, CallDescriptors::Key key) {
if (!data()->IsInitialized()) {
CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key);
DCHECK(d == data()); // d should be a modifiable pointer to data().
InitializePlatformSpecific(d);
FunctionType* function_type = BuildCallInterfaceDescriptorFunctionType(
isolate, d->register_param_count());
@ -217,20 +210,18 @@ class CallInterfaceDescriptor {
const CallInterfaceDescriptorData* data_;
};
#define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
public: \
explicit name(Isolate* isolate) : base(isolate, key()) { \
Initialize(isolate, key()); \
} \
static inline CallDescriptors::Key key();
#define DECLARE_DESCRIPTOR(name, base) \
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
explicit name(Isolate* isolate) : base(isolate, key()) { \
Initialize(isolate, key()); \
} \
\
protected: \
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
\
public:
public: \
static inline CallDescriptors::Key key();
#define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \
DECLARE_DESCRIPTOR(name, base) \
@ -240,17 +231,6 @@ class CallInterfaceDescriptor {
\
public:
#define DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(name, base, arg) \
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
protected: \
FunctionType* BuildCallInterfaceDescriptorFunctionType( \
Isolate* isolate, int register_param_count) override { \
return BuildCallInterfaceDescriptorFunctionTypeWithArg( \
isolate, register_param_count, arg); \
} \
\
public:
class VoidDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
@ -709,75 +689,18 @@ class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
CallInterfaceDescriptor)
};
// The ApiCallback*Descriptors have a lot of boilerplate. The superclass
// ApiCallbackDescriptorBase contains all the logic, and the
// ApiCallbackWith*ArgsDescriptor merely instantiate these with a
// parameter for the number of args.
//
// The base class is not meant to be instantiated directly and has no
// public constructors to ensure this is so.
//
// The simplest usage for all the ApiCallback*Descriptors is probably
// ApiCallbackDescriptorBase::ForArgs(isolate, argc)
//
class ApiCallbackDescriptorBase : public CallInterfaceDescriptor {
public:
static CallInterfaceDescriptor ForArgs(Isolate* isolate, int argc);
protected:
ApiCallbackDescriptorBase(Isolate* isolate, CallDescriptors::Key key)
: CallInterfaceDescriptor(isolate, key) {}
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override;
FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg(
Isolate* isolate, int parameter_count, int argc);
class ApiFunctionDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiFunctionDescriptor,
CallInterfaceDescriptor)
};
class ApiCallbackWith0ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith0ArgsDescriptor, ApiCallbackDescriptorBase, 0)
};
class ApiCallbackWith1ArgsDescriptor : public ApiCallbackDescriptorBase {
class ApiAccessorDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith1ArgsDescriptor, ApiCallbackDescriptorBase, 1)
};
class ApiCallbackWith2ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith2ArgsDescriptor, ApiCallbackDescriptorBase, 2)
};
class ApiCallbackWith3ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith3ArgsDescriptor, ApiCallbackDescriptorBase, 3)
};
class ApiCallbackWith4ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith4ArgsDescriptor, ApiCallbackDescriptorBase, 4)
};
class ApiCallbackWith5ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith5ArgsDescriptor, ApiCallbackDescriptorBase, 5)
};
class ApiCallbackWith6ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith6ArgsDescriptor, ApiCallbackDescriptorBase, 6)
};
class ApiCallbackWith7ArgsDescriptor : public ApiCallbackDescriptorBase {
public:
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
ApiCallbackWith7ArgsDescriptor, ApiCallbackDescriptorBase, 7)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiAccessorDescriptor,
CallInterfaceDescriptor)
};
@ -821,7 +744,7 @@ class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
static const Register KeyRegister();
};
class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor,
CallInterfaceDescriptor)
@ -854,10 +777,8 @@ class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)
};
#undef DECLARE_DESCRIPTOR_WITH_BASE
#undef DECLARE_DESCRIPTOR
#undef DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE
#undef DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG
// We define the association between CallDescriptors::Key and the specialized
// descriptor here to reduce boilerplate and mistakes.

View File

@ -5604,12 +5604,16 @@ static void CallApiFunctionAndReturn(
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- a0 : callee
// -- t0 : call_data
// -- a2 : holder
// -- a1 : api_function_address
// -- a3 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5635,15 +5639,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
// Save context, callee and call data.
__ Push(context, callee, call_data);
if (!is_lazy()) {
if (!is_lazy) {
// Load context from callee.
__ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// Push return value and default return value.
@ -5668,14 +5674,29 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ Addu(a0, sp, Operand(1 * kPointerSize));
// FunctionCallbackInfo::implicit_args_
__ sw(scratch, MemOperand(a0, 0 * kPointerSize));
// FunctionCallbackInfo::values_
__ Addu(at, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
__ sw(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ li(at, Operand(argc()));
__ sw(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
if (argc.is_immediate()) {
// FunctionCallbackInfo::values_
__ Addu(at, scratch,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ sw(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ li(at, Operand(argc.immediate()));
__ sw(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
} else {
// FunctionCallbackInfo::values_
__ sll(at, argc.reg(), kPointerSizeLog2);
__ Addu(at, at, scratch);
__ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
__ sw(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ Addu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
__ sll(at, argc.reg(), kPointerSizeLog2);
__ sw(at, MemOperand(a0, 3 * kPointerSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5685,7 +5706,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument.
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5693,14 +5714,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
int stack_space = 0;
int32_t stack_space_offset = 4 * kPointerSize;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_offset = kInvalidStackOffset;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_offset = kInvalidStackOffset;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_offset, return_value_operand,
&context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -384,7 +384,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // callee
t0, // call_data
a2, // holder
a1, // api_function_address
a3, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // callee

View File

@ -5628,12 +5628,16 @@ static void CallApiFunctionAndReturn(
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- a0 : callee
// -- a4 : call_data
// -- a2 : holder
// -- a1 : api_function_address
// -- a3 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5659,15 +5663,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
// Save context, callee and call data.
__ Push(context, callee, call_data);
if (!is_lazy()) {
if (!is_lazy) {
// Load context from callee.
__ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// Push return value and default return value.
@ -5692,17 +5698,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ Daddu(a0, sp, Operand(1 * kPointerSize));
// FunctionCallbackInfo::implicit_args_
__ sd(scratch, MemOperand(a0, 0 * kPointerSize));
// FunctionCallbackInfo::values_
__ Daddu(at, scratch,
Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
__ sd(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
// Stored as int field, 32-bit integers within struct on stack always left
// justified by n64 ABI.
__ li(at, Operand(argc()));
__ sw(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ sw(zero_reg, MemOperand(a0, 2 * kPointerSize + kIntSize));
if (argc.is_immediate()) {
// FunctionCallbackInfo::values_
__ Daddu(at, scratch,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ sd(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
// Stored as int field, 32-bit integers within struct on stack always left
// justified by n64 ABI.
__ li(at, Operand(argc.immediate()));
__ sw(at, MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ sw(zero_reg, MemOperand(a0, 2 * kPointerSize + kIntSize));
} else {
// FunctionCallbackInfo::values_
__ dsll(at, argc.reg(), kPointerSizeLog2);
__ Daddu(at, at, scratch);
__ Daddu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
__ sd(at, MemOperand(a0, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
// Stored as int field, 32-bit integers within struct on stack always left
// justified by n64 ABI.
__ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ Daddu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
__ dsll(at, argc.reg(), kPointerSizeLog2);
__ sw(at, MemOperand(a0, 2 * kPointerSize + kIntSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5712,7 +5734,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument.
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5720,14 +5742,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
int stack_space = 0;
int32_t stack_space_offset = 4 * kPointerSize;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_offset = kInvalidStackOffset;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_offset = kInvalidStackOffset;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_offset, return_value_operand,
&context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -384,7 +384,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // callee
a4, // call_data
a2, // holder
a1, // api_function_address
a3, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // callee

View File

@ -5613,12 +5613,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ b(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- r3 : callee
// -- r7 : call_data
// -- r5 : holder
// -- r4 : api_function_address
// -- r6 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5648,7 +5652,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// context save
__ push(context);
if (!is_lazy()) {
if (!is_lazy) {
// load context from callee
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
}
@ -5660,7 +5664,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(call_data);
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// return value
@ -5696,15 +5700,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ addi(r3, sp, Operand(kFunctionCallbackInfoOffset));
// FunctionCallbackInfo::implicit_args_
__ StoreP(scratch, MemOperand(r3, 0 * kPointerSize));
// FunctionCallbackInfo::values_
__ addi(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
__ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ li(ip, Operand(argc()));
__ stw(ip, MemOperand(r3, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ li(ip, Operand::Zero());
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
if (argc.is_immediate()) {
// FunctionCallbackInfo::values_
__ addi(ip, scratch,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ li(ip, Operand(argc.immediate()));
__ stw(ip, MemOperand(r3, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ li(ip, Operand::Zero());
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
} else {
__ ShiftLeftImm(ip, argc.reg(), Operand(kPointerSizeLog2));
__ addi(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_
__ add(r0, scratch, ip);
__ StoreP(r0, MemOperand(r3, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ stw(argc.reg(), MemOperand(r3, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5714,7 +5731,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5724,14 +5741,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
MemOperand is_construct_call_operand =
MemOperand(sp, kFunctionCallbackInfoOffset + 2 * kPointerSize + kIntSize);
MemOperand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,
&context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(r6), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -380,7 +380,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r3, // callee
r7, // call_data
r5, // holder
r4, // api_function_address
r6, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r3, // callee

View File

@ -5543,12 +5543,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ b(&leave_exit_frame, Label::kNear);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- r2 : callee
// -- r6 : call_data
// -- r4 : holder
// -- r3 : api_function_address
// -- r5 : number of arguments if argc is a register
// -- cp : context
// --
// -- sp[0] : last argument
@ -5574,6 +5578,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || r2.is(argc.reg()));
// context save
__ push(context);
if (!is_lazy) {
@ -5588,7 +5594,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(call_data);
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// return value
@ -5624,15 +5630,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ AddP(r2, sp, Operand(kFunctionCallbackInfoOffset));
// FunctionCallbackInfo::implicit_args_
__ StoreP(scratch, MemOperand(r2, 0 * kPointerSize));
// FunctionCallbackInfo::values_
__ AddP(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
__ StoreP(ip, MemOperand(r2, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ LoadImmP(ip, Operand(argc()));
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ LoadImmP(ip, Operand::Zero());
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
if (argc.is_immediate()) {
// FunctionCallbackInfo::values_
__ AddP(ip, scratch,
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
__ StoreP(ip, MemOperand(r2, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ LoadImmP(ip, Operand(argc.immediate()));
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_ = 0
__ LoadImmP(ip, Operand::Zero());
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
} else {
__ ShiftLeftP(ip, argc.reg(), Operand(kPointerSizeLog2));
__ AddP(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_
__ AddP(r0, scratch, ip);
__ StoreP(r0, MemOperand(r2, 1 * kPointerSize));
// FunctionCallbackInfo::length_ = argc
__ StoreW(argc.reg(), MemOperand(r2, 2 * kPointerSize));
// FunctionCallbackInfo::is_construct_call_
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
}
ExternalReference thunk_ref =
ExternalReference::invoke_function_callback(masm->isolate());
@ -5642,7 +5661,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5652,13 +5671,30 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
MemOperand is_construct_call_operand =
MemOperand(sp, kFunctionCallbackInfoOffset + 2 * kPointerSize + kIntSize);
MemOperand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = NULL;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
stack_space_operand, return_value_operand,
&context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(r6), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name

View File

@ -334,7 +334,19 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r2, // callee
r6, // call_data
r4, // holder
r3, // api_function_address
r5, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r2, // callee

View File

@ -5406,7 +5406,10 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- rdi : callee
// -- rbx : call_data
@ -5439,6 +5442,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
DCHECK(argc.is_immediate() || rax.is(argc.reg()));
__ PopReturnAddressTo(return_address);
// context save
@ -5450,7 +5455,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// call data
__ Push(call_data);
Register scratch = call_data;
if (!this->call_data_undefined()) {
if (!call_data_undefined) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
}
// return value
@ -5467,7 +5472,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// Push return address back on stack.
__ PushReturnAddressFrom(return_address);
if (!this->is_lazy()) {
if (!is_lazy) {
// load context from callee
__ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
}
@ -5479,15 +5484,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
PrepareCallApiFunction(masm, kApiStackSpace);
// FunctionCallbackInfo::implicit_args_.
int argc = this->argc();
__ movp(StackSpaceOperand(0), scratch);
__ addp(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ movp(StackSpaceOperand(1), scratch);
// FunctionCallbackInfo::length_.
__ Set(StackSpaceOperand(2), argc);
// 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;
@ -5514,17 +5532,36 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
FCA::kArgsLength - FCA::kContextSaveIndex);
Operand is_construct_call_operand = StackSpaceOperand(3);
Operand return_value_operand = args_from_rbp.GetArgumentOperand(
this->is_store() ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
int stack_space = 0;
Operand* stack_space_operand = &is_construct_call_operand;
stack_space = argc + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg,
stack_space, stack_space_operand,
return_value_operand, &context_restore_operand);
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(rax), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rsp[0] : return address

View File

@ -381,7 +381,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
rdi, // callee
rbx, // call_data
rcx, // holder
rdx, // api_function_address
rax, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
rdi, // callee

View File

@ -5346,13 +5346,17 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
__ jmp(&leave_exit_frame);
}
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
static void CallApiFunctionStubHelper(MacroAssembler* masm,
const ParameterCount& argc,
bool return_first_arg,
bool call_data_undefined, bool is_lazy) {
// ----------- S t a t e -------------
// -- edi : callee
// -- ebx : call_data
// -- ecx : holder
// -- edx : api_function_address
// -- esi : context
// -- eax : number of arguments if argc is a register
// --
// -- esp[0] : return address
// -- esp[4] : last argument
@ -5381,9 +5385,15 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
DCHECK(argc.is_immediate() || eax.is(argc.reg()));
__ pop(return_address);
// context save.
__ push(context);
if (argc.is_immediate()) {
__ pop(return_address);
// context save.
__ push(context);
} else {
// pop return address and save context
__ xchg(context, Operand(esp, 0));
return_address = context;
}
// callee
__ push(callee);
@ -5392,7 +5402,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
__ push(call_data);
Register scratch = call_data;
if (!call_data_undefined()) {
if (!call_data_undefined) {
// return value
__ push(Immediate(masm->isolate()->factory()->undefined_value()));
// return value default
@ -5413,7 +5423,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// push return address
__ push(return_address);
if (!is_lazy()) {
if (!is_lazy) {
// load context from callee
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
}
@ -5432,13 +5442,27 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
// FunctionCallbackInfo::implicit_args_.
__ mov(ApiParameterOperand(2), scratch);
__ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ Move(ApiParameterOperand(4), Immediate(argc));
// FunctionCallbackInfo::is_construct_call_.
__ Move(ApiParameterOperand(5), Immediate(0));
if (argc.is_immediate()) {
__ add(scratch,
Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
// FunctionCallbackInfo::is_construct_call_.
__ Move(ApiParameterOperand(5), Immediate(0));
} else {
__ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size,
(FCA::kArgsLength - 1) * kPointerSize));
// FunctionCallbackInfo::values_.
__ mov(ApiParameterOperand(3), scratch);
// FunctionCallbackInfo::length_.
__ mov(ApiParameterOperand(4), argc.reg());
// FunctionCallbackInfo::is_construct_call_.
__ lea(argc.reg(), Operand(argc.reg(), times_pointer_size,
(FCA::kArgsLength + 1) * kPointerSize));
__ mov(ApiParameterOperand(5), argc.reg());
}
// v8::InvocationCallback's argument.
__ lea(scratch, ApiParameterOperand(2));
@ -5451,7 +5475,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
(2 + FCA::kContextSaveIndex) * kPointerSize);
// Stores return the first js argument
int return_value_offset = 0;
if (is_store()) {
if (return_first_arg) {
return_value_offset = 2 + FCA::kArgsLength;
} else {
return_value_offset = 2 + FCA::kReturnValueOffset;
@ -5460,8 +5484,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
int stack_space = 0;
Operand is_construct_call_operand = ApiParameterOperand(5);
Operand* stack_space_operand = &is_construct_call_operand;
stack_space = argc() + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
if (argc.is_immediate()) {
stack_space = argc.immediate() + FCA::kArgsLength + 1;
stack_space_operand = nullptr;
}
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
ApiParameterOperand(1), stack_space,
stack_space_operand, return_value_operand,
@ -5469,6 +5495,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
}
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
bool call_data_undefined = this->call_data_undefined();
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
call_data_undefined, false);
}
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
bool is_store = this->is_store();
int argc = this->argc();
bool call_data_undefined = this->call_data_undefined();
bool is_lazy = this->is_lazy();
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
call_data_undefined, is_lazy);
}
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- esp[0] : return address

View File

@ -387,7 +387,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
void ApiFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
edi, // callee
ebx, // call_data
ecx, // holder
edx, // api_function_address
eax, // actual number of arguments
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ApiAccessorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
edi, // callee