Commit 9b12ec9a authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Call ArgumentsAccessStub to materialize arguments.

This lowers JSCreateArgument nodes to call the ArgumentsAccessStub for
help with materializing arguments objects when possible. Along the way
this changes the calling convention of said stub to take parameters in
registers instead of on the stack.

R=mvstanton@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30919}
parent 347fa906
This diff is collapsed.
...@@ -60,6 +60,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return r1; } ...@@ -60,6 +60,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return r1; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return r0; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return r0; }
const Register ArgumentsAccessNewDescriptor::function() { return r1; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return r2; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return r3; }
const Register ApiGetterDescriptor::function_address() { return r2; } const Register ApiGetterDescriptor::function_address() { return r2; }
......
This diff is collapsed.
...@@ -60,6 +60,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return x1; } ...@@ -60,6 +60,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return x1; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; }
const Register ArgumentsAccessNewDescriptor::function() { return x1; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return x2; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return x3; }
const Register ApiGetterDescriptor::function_address() { return x2; } const Register ApiGetterDescriptor::function_address() { return x2; }
......
...@@ -235,6 +235,17 @@ Callable CodeFactory::FastNewClosure(Isolate* isolate, ...@@ -235,6 +235,17 @@ Callable CodeFactory::FastNewClosure(Isolate* isolate,
} }
// static
Callable CodeFactory::ArgumentsAccess(Isolate* isolate,
bool is_unmapped_arguments,
bool has_duplicate_parameters) {
ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
is_unmapped_arguments, has_duplicate_parameters);
ArgumentsAccessStub stub(isolate, type);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static // static
Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
AllocateHeapNumberStub stub(isolate); AllocateHeapNumberStub stub(isolate);
......
...@@ -88,6 +88,9 @@ class CodeFactory final { ...@@ -88,6 +88,9 @@ class CodeFactory final {
static Callable FastNewClosure(Isolate* isolate, LanguageMode language_mode, static Callable FastNewClosure(Isolate* isolate, LanguageMode language_mode,
FunctionKind kind); FunctionKind kind);
static Callable ArgumentsAccess(Isolate* isolate, bool is_unmapped_arguments,
bool has_duplicate_parameters);
static Callable AllocateHeapNumber(Isolate* isolate); static Callable AllocateHeapNumber(Isolate* isolate);
static Callable CallFunction(Isolate* isolate, int argc, static Callable CallFunction(Isolate* isolate, int argc,
......
...@@ -1899,8 +1899,19 @@ class ArgumentsAccessStub: public PlatformCodeStub { ...@@ -1899,8 +1899,19 @@ class ArgumentsAccessStub: public PlatformCodeStub {
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
if (type() == READ_ELEMENT) { if (type() == READ_ELEMENT) {
return ArgumentsAccessReadDescriptor(isolate()); return ArgumentsAccessReadDescriptor(isolate());
} else {
return ArgumentsAccessNewDescriptor(isolate());
}
}
static Type ComputeType(bool is_unmapped, bool has_duplicate_parameters) {
if (is_unmapped) {
return Type::NEW_STRICT;
} else if (has_duplicate_parameters) {
return Type::NEW_SLOPPY_SLOW;
} else {
return Type::NEW_SLOPPY_FAST;
} }
return ContextOnlyDescriptor(isolate());
} }
private: private:
......
...@@ -1098,6 +1098,45 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicContext(Node* node) { ...@@ -1098,6 +1098,45 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicContext(Node* node) {
} }
Reduction JSTypedLowering::ReduceJSCreateArguments(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
CreateArgumentsParameters const& p = CreateArgumentsParametersOf(node->op());
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
// Use the ArgumentsAccessStub for materializing both mapped and unmapped
// arguments object, but only for non-inlined (i.e. outermost) frames.
if (p.type() != CreateArgumentsParameters::kRestArray &&
outer_state->opcode() != IrOpcode::kFrameState) {
Handle<SharedFunctionInfo> shared;
Isolate* isolate = jsgraph()->isolate();
if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
bool unmapped = p.type() == CreateArgumentsParameters::kUnmappedArguments;
Callable callable = CodeFactory::ArgumentsAccess(
isolate, unmapped, shared->has_duplicate_parameters());
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate, graph()->zone(), callable.descriptor(), 0,
CallDescriptor::kNeedsFrameState);
const Operator* new_op = common()->Call(desc);
int parameter_count = state_info.parameter_count() - 1;
int parameter_offset = parameter_count * kPointerSize;
int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset;
Node* stub_code = jsgraph()->HeapConstant(callable.code());
Node* parameter_pointer = graph()->NewNode(
machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()),
jsgraph()->IntPtrConstant(offset));
node->InsertInput(graph()->zone(), 0, stub_code);
node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(parameter_count));
node->InsertInput(graph()->zone(), 3, parameter_pointer);
NodeProperties::ChangeOp(node, new_op);
return Changed(node);
}
return NoChange();
}
Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
...@@ -1652,6 +1691,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -1652,6 +1691,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSLoadDynamicGlobal(node); return ReduceJSLoadDynamicGlobal(node);
case IrOpcode::kJSLoadDynamicContext: case IrOpcode::kJSLoadDynamicContext:
return ReduceJSLoadDynamicContext(node); return ReduceJSLoadDynamicContext(node);
case IrOpcode::kJSCreateArguments:
return ReduceJSCreateArguments(node);
case IrOpcode::kJSCreateClosure: case IrOpcode::kJSCreateClosure:
return ReduceJSCreateClosure(node); return ReduceJSCreateClosure(node);
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
......
...@@ -57,6 +57,7 @@ class JSTypedLowering final : public AdvancedReducer { ...@@ -57,6 +57,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSToNumber(Node* node); Reduction ReduceJSToNumber(Node* node);
Reduction ReduceJSToStringInput(Node* input); Reduction ReduceJSToStringInput(Node* input);
Reduction ReduceJSToString(Node* node); Reduction ReduceJSToString(Node* node);
Reduction ReduceJSCreateArguments(Node* node);
Reduction ReduceJSCreateClosure(Node* node); Reduction ReduceJSCreateClosure(Node* node);
Reduction ReduceJSCreateLiteralArray(Node* node); Reduction ReduceJSCreateLiteralArray(Node* node);
Reduction ReduceJSCreateLiteralObject(Node* node); Reduction ReduceJSCreateLiteralObject(Node* node);
......
...@@ -281,32 +281,26 @@ void FullCodeGenerator::Generate() { ...@@ -281,32 +281,26 @@ void FullCodeGenerator::Generate() {
if (arguments != NULL) { if (arguments != NULL) {
// Function uses arguments object. // Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
DCHECK(r1.is(ArgumentsAccessNewDescriptor::function()));
if (!function_in_register_r1) { if (!function_in_register_r1) {
// Load this again, if it's used by the local context below. // Load this again, if it's used by the local context below.
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ mov(r3, r1);
} }
// Receiver is just before the parameters on the caller's stack. // Receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ mov(ArgumentsAccessNewDescriptor::parameter_count(),
__ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); Operand(Smi::FromInt(num_parameters)));
__ mov(r1, Operand(Smi::FromInt(num_parameters))); __ add(ArgumentsAccessNewDescriptor::parameter_pointer(), fp,
__ Push(r3, r2, r1); Operand(StandardFrameConstants::kCallerSPOffset + offset));
// Arguments to ArgumentsAccessStub: // Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count. // function, parameter pointer, parameter count.
// The stub will rewrite receiver and parameter count if the previous // The stub will rewrite parameter pointer and parameter count if the
// stack frame was an arguments adapter frame. // previous stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type; bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
if (is_strict(language_mode()) || !has_simple_parameters()) { ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
type = ArgumentsAccessStub::NEW_STRICT; is_unmapped, literal()->has_duplicate_parameters());
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
...@@ -289,31 +289,26 @@ void FullCodeGenerator::Generate() { ...@@ -289,31 +289,26 @@ void FullCodeGenerator::Generate() {
if (arguments != NULL) { if (arguments != NULL) {
// Function uses arguments object. // Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
DCHECK(x1.is(ArgumentsAccessNewDescriptor::function()));
if (!function_in_register_x1) { if (!function_in_register_x1) {
// Load this again, if it's used by the local context below. // Load this again, if it's used by the local context below.
__ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ Ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ Mov(x3, x1);
} }
// Receiver is just before the parameters on the caller's stack. // Receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset); __ Mov(ArgumentsAccessNewDescriptor::parameter_count(),
__ Mov(x1, Smi::FromInt(num_parameters)); Smi::FromInt(num_parameters));
__ Push(x3, x2, x1); __ Add(ArgumentsAccessNewDescriptor::parameter_pointer(), fp,
StandardFrameConstants::kCallerSPOffset + offset);
// Arguments to ArgumentsAccessStub: // Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count. // function, parameter pointer, parameter count.
// The stub will rewrite receiver and parameter count if the previous // The stub will rewrite parameter pointer and parameter count if the
// stack frame was an arguments adapter frame. // previous stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type; bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
if (is_strict(language_mode()) || !has_simple_parameters()) { ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
type = ArgumentsAccessStub::NEW_STRICT; is_unmapped, literal()->has_duplicate_parameters());
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
...@@ -283,31 +283,25 @@ void FullCodeGenerator::Generate() { ...@@ -283,31 +283,25 @@ void FullCodeGenerator::Generate() {
if (arguments != NULL) { if (arguments != NULL) {
// Function uses arguments object. // Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
if (function_in_register) { DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
__ push(edi); if (!function_in_register) {
} else { __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
} }
// Receiver is just before the parameters on the caller's stack. // Receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ lea(edx, __ mov(ArgumentsAccessNewDescriptor::parameter_count(),
Immediate(Smi::FromInt(num_parameters)));
__ lea(ArgumentsAccessNewDescriptor::parameter_pointer(),
Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
__ push(edx);
__ push(Immediate(Smi::FromInt(num_parameters)));
// Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count.
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
// Arguments to ArgumentsAccessStub:
// function, parameter pointer, parameter count.
// The stub will rewrite parameter pointer and parameter count if the
// previous stack frame was an arguments adapter frame.
bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
is_unmapped, literal()->has_duplicate_parameters());
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
...@@ -299,32 +299,26 @@ void FullCodeGenerator::Generate() { ...@@ -299,32 +299,26 @@ void FullCodeGenerator::Generate() {
if (arguments != NULL) { if (arguments != NULL) {
// Function uses arguments object. // Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
DCHECK(a1.is(ArgumentsAccessNewDescriptor::function()));
if (!function_in_register_a1) { if (!function_in_register_a1) {
// Load this again, if it's used by the local context below. // Load this again, if it's used by the local context below.
__ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ lw(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ mov(a3, a1);
} }
// Receiver is just before the parameters on the caller's stack. // Receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ Addu(a2, fp, __ li(ArgumentsAccessNewDescriptor::parameter_count(),
Operand(StandardFrameConstants::kCallerSPOffset + offset)); Operand(Smi::FromInt(num_parameters)));
__ li(a1, Operand(Smi::FromInt(num_parameters))); __ Addu(ArgumentsAccessNewDescriptor::parameter_pointer(), fp,
__ Push(a3, a2, a1); Operand(StandardFrameConstants::kCallerSPOffset + offset));
// Arguments to ArgumentsAccessStub: // Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count. // function, parameter pointer, parameter count.
// The stub will rewrite receiever and parameter count if the previous // The stub will rewrite parameter pointer and parameter count if the
// stack frame was an arguments adapter frame. // previous stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type; bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
if (is_strict(language_mode()) || !has_simple_parameters()) { ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
type = ArgumentsAccessStub::NEW_STRICT; is_unmapped, literal()->has_duplicate_parameters());
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
...@@ -295,32 +295,26 @@ void FullCodeGenerator::Generate() { ...@@ -295,32 +295,26 @@ void FullCodeGenerator::Generate() {
if (arguments != NULL) { if (arguments != NULL) {
// Function uses arguments object. // Function uses arguments object.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
DCHECK(a1.is(ArgumentsAccessNewDescriptor::function()));
if (!function_in_register_a1) { if (!function_in_register_a1) {
// Load this again, if it's used by the local context below. // Load this again, if it's used by the local context below.
__ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ mov(a3, a1);
} }
// Receiver is just before the parameters on the caller's stack. // Receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ Daddu(a2, fp, __ li(ArgumentsAccessNewDescriptor::parameter_count(),
Operand(StandardFrameConstants::kCallerSPOffset + offset)); Operand(Smi::FromInt(num_parameters)));
__ li(a1, Operand(Smi::FromInt(num_parameters))); __ Daddu(ArgumentsAccessNewDescriptor::parameter_pointer(), fp,
__ Push(a3, a2, a1); Operand(StandardFrameConstants::kCallerSPOffset + offset));
// Arguments to ArgumentsAccessStub: // Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count. // function, parameter pointer, parameter count.
// The stub will rewrite receiever and parameter count if the previous // The stub will rewrite parameter pointer and parameter count if the
// stack frame was an arguments adapter frame. // previous stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type; bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
if (is_strict(language_mode()) || !has_simple_parameters()) { ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
type = ArgumentsAccessStub::NEW_STRICT; is_unmapped, literal()->has_duplicate_parameters());
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
...@@ -281,31 +281,25 @@ void FullCodeGenerator::Generate() { ...@@ -281,31 +281,25 @@ void FullCodeGenerator::Generate() {
// Arguments object must be allocated after the context object, in // Arguments object must be allocated after the context object, in
// case the "arguments" or ".arguments" variables are in the context. // case the "arguments" or ".arguments" variables are in the context.
Comment cmnt(masm_, "[ Allocate arguments object"); Comment cmnt(masm_, "[ Allocate arguments object");
if (function_in_register) { DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
__ Push(rdi); if (!function_in_register) {
} else { __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
} }
// The receiver is just before the parameters on the caller's stack. // The receiver is just before the parameters on the caller's stack.
int num_parameters = info->scope()->num_parameters(); int num_parameters = info->scope()->num_parameters();
int offset = num_parameters * kPointerSize; int offset = num_parameters * kPointerSize;
__ leap(rdx, __ Move(ArgumentsAccessNewDescriptor::parameter_count(),
Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); Smi::FromInt(num_parameters));
__ Push(rdx); __ leap(ArgumentsAccessNewDescriptor::parameter_pointer(),
__ Push(Smi::FromInt(num_parameters)); Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset));
// Arguments to ArgumentsAccessStub: // Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count. // function, parameter pointer, parameter count.
// The stub will rewrite receiver and parameter count if the previous // The stub will rewrite parameter pointer and parameter count if the
// stack frame was an arguments adapter frame. // previous stack frame was an arguments adapter frame.
bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
ArgumentsAccessStub::Type type; ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
if (is_strict(language_mode()) || !has_simple_parameters()) { is_unmapped, literal()->has_duplicate_parameters());
type = ArgumentsAccessStub::NEW_STRICT;
} else if (literal()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub); __ CallStub(&stub);
......
This diff is collapsed.
...@@ -65,6 +65,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return edx; } ...@@ -65,6 +65,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return edx; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; }
const Register ArgumentsAccessNewDescriptor::function() { return edi; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return ecx; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return edx; }
const Register ApiGetterDescriptor::function_address() { return edx; } const Register ApiGetterDescriptor::function_address() { return edx; }
......
...@@ -310,6 +310,26 @@ void ArgumentsAccessReadDescriptor::InitializePlatformSpecific( ...@@ -310,6 +310,26 @@ void ArgumentsAccessReadDescriptor::InitializePlatformSpecific(
} }
Type::FunctionType*
ArgumentsAccessNewDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone();
Type::FunctionType* function =
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
function->InitParameter(0, AnyTagged(zone));
function->InitParameter(1, SmiType(zone));
function->InitParameter(2, ExternalPointer(zone));
return function;
}
void ArgumentsAccessNewDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {function(), parameter_count(), parameter_pointer()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void ContextOnlyDescriptor::InitializePlatformSpecific( void ContextOnlyDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
data->InitializePlatformSpecific(0, nullptr); data->InitializePlatformSpecific(0, nullptr);
......
...@@ -61,6 +61,7 @@ class PlatformInterfaceDescriptor; ...@@ -61,6 +61,7 @@ class PlatformInterfaceDescriptor;
V(ApiAccessor) \ V(ApiAccessor) \
V(ApiGetter) \ V(ApiGetter) \
V(ArgumentsAccessRead) \ V(ArgumentsAccessRead) \
V(ArgumentsAccessNew) \
V(StoreArrayLiteralElement) \ V(StoreArrayLiteralElement) \
V(LoadGlobalViaContext) \ V(LoadGlobalViaContext) \
V(StoreGlobalViaContext) \ V(StoreGlobalViaContext) \
...@@ -638,6 +639,17 @@ class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor { ...@@ -638,6 +639,17 @@ class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
}; };
class ArgumentsAccessNewDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArgumentsAccessNewDescriptor,
CallInterfaceDescriptor)
static const Register function();
static const Register parameter_count();
static const Register parameter_pointer();
};
class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor { class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
public: public:
DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor, DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
......
This diff is collapsed.
...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return a1; } ...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return a1; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return a0; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return a0; }
const Register ArgumentsAccessNewDescriptor::function() { return a1; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return a2; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return a3; }
const Register ApiGetterDescriptor::function_address() { return a2; } const Register ApiGetterDescriptor::function_address() { return a2; }
......
This diff is collapsed.
...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return a1; } ...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return a1; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return a0; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return a0; }
const Register ArgumentsAccessNewDescriptor::function() { return a1; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return a2; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return a3; }
const Register ApiGetterDescriptor::function_address() { return a2; } const Register ApiGetterDescriptor::function_address() { return a2; }
......
This diff is collapsed.
...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return rdx; } ...@@ -58,6 +58,11 @@ const Register ArgumentsAccessReadDescriptor::index() { return rdx; }
const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; } const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; }
const Register ArgumentsAccessNewDescriptor::function() { return rdi; }
const Register ArgumentsAccessNewDescriptor::parameter_count() { return rcx; }
const Register ArgumentsAccessNewDescriptor::parameter_pointer() { return rdx; }
const Register ApiGetterDescriptor::function_address() { return r8; } const Register ApiGetterDescriptor::function_address() { return r8; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment