Commit 85cd0d87 authored by jgruber's avatar jgruber Committed by Commit Bot

Refactor InterpreterPushArgsThenConstruct

This reorders arguments in preparation for removing ebx from its
calling convention (in a follow-up some args will be passed on the
stack).

Drive-by: Improve readability in the code handling different cases
(array,spread,...).

Bug: v8:6666
Change-Id: I0160f8efafd0fd0e841739578e01c32b38adb66e
Reviewed-on: https://chromium-review.googlesource.com/1196884Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55557}
parent e034c1ad
...@@ -237,10 +237,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -237,10 +237,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
r0, // argument count (not including receiver) r0, // argument count (not including receiver)
r3, // new target r4, // address of the first argument
r1, // constructor to call r1, // constructor to call
r3, // new target
r2, // allocation site feedback if available, undefined otherwise r2, // allocation site feedback if available, undefined otherwise
r4 // address of the first argument
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -242,10 +242,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -242,10 +242,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
x0, // argument count (not including receiver) x0, // argument count (not including receiver)
x3, // new target x4, // address of the first argument
x1, // constructor to call x1, // constructor to call
x3, // new target
x2, // allocation site feedback if available, undefined otherwise x2, // allocation site feedback if available, undefined otherwise
x4 // address of the first argument
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -1110,29 +1110,26 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( ...@@ -1110,29 +1110,26 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
__ Pop(edx); __ Pop(edx);
__ Pop(edi); __ Pop(edi);
if (mode == InterpreterPushArgsMode::kWithFinalSpread) { // Call the appropriate constructor. Arguments are already in registers.
__ PopReturnAddressTo(ebx);
__ Pop(ecx); // Pass the spread in a register
__ PushReturnAddressFrom(ebx);
__ sub(eax, Immediate(1)); // Subtract one for spread
} else {
__ AssertUndefinedOrAllocationSite(ebx);
}
if (mode == InterpreterPushArgsMode::kArrayFunction) { if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Tail call to the array construct stub (still in the caller // Tail call to the array construct stub (still in the caller context at
// context at this point). // this point).
__ AssertUndefinedOrAllocationSite(ebx);
__ AssertFunction(edi); __ AssertFunction(edi);
__ MoveForRootRegisterRefactoring(kJavaScriptCallExtraArg1Register, ebx); __ MoveForRootRegisterRefactoring(kJavaScriptCallExtraArg1Register, ebx);
Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayConstructorImpl); Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayConstructorImpl);
__ Jump(code, RelocInfo::CODE_TARGET); __ Jump(code, RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) { } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with unmodified eax, edi, edx values. __ PopReturnAddressTo(ebx);
__ Pop(ecx); // Pass the spread in a register
__ PushReturnAddressFrom(ebx);
__ sub(eax, Immediate(1)); // Subtract one for spread
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread), __ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
RelocInfo::CODE_TARGET); RelocInfo::CODE_TARGET);
} else { } else {
DCHECK_EQ(InterpreterPushArgsMode::kOther, mode); DCHECK_EQ(InterpreterPushArgsMode::kOther, mode);
// Call the constructor with unmodified eax, edi, edx values. __ AssertUndefinedOrAllocationSite(ebx);
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
} }
......
...@@ -246,10 +246,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -246,10 +246,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
eax, // argument count (not including receiver) eax, // argument count (not including receiver)
edx, // new target
edi, // constructor
ebx, // allocation site feedback
ecx, // address of first argument ecx, // address of first argument
edi, // constructor to call
edx, // new target
ebx, // allocation site feedback if available, undefined otherwise
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -1004,13 +1004,13 @@ class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor { ...@@ -1004,13 +1004,13 @@ class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
class InterpreterPushArgsThenConstructDescriptor class InterpreterPushArgsThenConstructDescriptor
: public CallInterfaceDescriptor { : public CallInterfaceDescriptor {
public: public:
DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor, DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
kFeedbackElement, kFirstArgument) kNewTarget, kFeedbackElement)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
MachineType::AnyTagged(), // kNewTarget MachineType::Pointer(), // kFirstArgument
MachineType::AnyTagged(), // kConstructor MachineType::AnyTagged(), // kConstructor
MachineType::AnyTagged(), // kFeedbackElement MachineType::AnyTagged(), // kNewTarget
MachineType::Pointer()) // kFirstArgument MachineType::AnyTagged()) // kFeedbackElement
DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor, DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
CallInterfaceDescriptor) CallInterfaceDescriptor)
}; };
......
...@@ -1074,8 +1074,8 @@ Node* InterpreterAssembler::Construct(Node* target, Node* context, ...@@ -1074,8 +1074,8 @@ Node* InterpreterAssembler::Construct(Node* target, Node* context,
isolate(), InterpreterPushArgsMode::kArrayFunction); isolate(), InterpreterPushArgsMode::kArrayFunction);
Node* code_target = HeapConstant(callable.code()); Node* code_target = HeapConstant(callable.code());
var_result.Bind(CallStub(callable.descriptor(), code_target, context, var_result.Bind(CallStub(callable.descriptor(), code_target, context,
args.reg_count(), new_target, target, args.reg_count(), args.base_reg_location(), target,
var_site.value(), args.base_reg_location())); new_target, var_site.value()));
Goto(&return_result); Goto(&return_result);
} }
...@@ -1087,8 +1087,8 @@ Node* InterpreterAssembler::Construct(Node* target, Node* context, ...@@ -1087,8 +1087,8 @@ Node* InterpreterAssembler::Construct(Node* target, Node* context,
isolate(), InterpreterPushArgsMode::kOther); isolate(), InterpreterPushArgsMode::kOther);
Node* code_target = HeapConstant(callable.code()); Node* code_target = HeapConstant(callable.code());
var_result.Bind(CallStub(callable.descriptor(), code_target, context, var_result.Bind(CallStub(callable.descriptor(), code_target, context,
args.reg_count(), new_target, target, args.reg_count(), args.base_reg_location(), target,
UndefinedConstant(), args.base_reg_location())); new_target, UndefinedConstant()));
Goto(&return_result); Goto(&return_result);
} }
...@@ -1212,8 +1212,8 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, ...@@ -1212,8 +1212,8 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context,
isolate(), InterpreterPushArgsMode::kWithFinalSpread); isolate(), InterpreterPushArgsMode::kWithFinalSpread);
Node* code_target = HeapConstant(callable.code()); Node* code_target = HeapConstant(callable.code());
return CallStub(callable.descriptor(), code_target, context, args.reg_count(), return CallStub(callable.descriptor(), code_target, context, args.reg_count(),
new_target, target, UndefinedConstant(), args.base_reg_location(), target, new_target,
args.base_reg_location()); UndefinedConstant());
} }
Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context, Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
......
...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
a0, // argument count (not including receiver) a0, // argument count (not including receiver)
a3, // new target t4, // address of the first argument
a1, // constructor to call a1, // constructor to call
a2, // allocation site feedback if available, undefined otherwise. a3, // new target
t4 // address of the first argument a2, // allocation site feedback if available, undefined otherwise
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
a0, // argument count (not including receiver) a0, // argument count (not including receiver)
a3, // new target a4, // address of the first argument
a1, // constructor to call a1, // constructor to call
a2, // allocation site feedback if available, undefined otherwise. a3, // new target
a4 // address of the first argument a2, // allocation site feedback if available, undefined otherwise
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -238,10 +238,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
r3, // argument count (not including receiver) r3, // argument count (not including receiver)
r6, // new target r7, // address of the first argument
r4, // constructor to call r4, // constructor to call
r6, // new target
r5, // allocation site feedback if available, undefined otherwise r5, // allocation site feedback if available, undefined otherwise
r7 // address of the first argument
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -236,10 +236,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -236,10 +236,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
r2, // argument count (not including receiver) r2, // argument count (not including receiver)
r5, // new target r6, // address of the first argument
r3, // constructor to call r3, // constructor to call
r5, // new target
r4, // allocation site feedback if available, undefined otherwise r4, // allocation site feedback if available, undefined otherwise
r6 // address of the first argument
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -239,10 +239,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( ...@@ -239,10 +239,10 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
rax, // argument count (not including receiver) rax, // argument count (not including receiver)
rcx, // address of first argument
rdi, // constructor to call
rdx, // new target rdx, // new target
rdi, // constructor
rbx, // allocation site feedback if available, undefined otherwise rbx, // allocation site feedback if available, undefined otherwise
rcx, // address of first argument
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
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