[ia32] Unalias kRootRegister in Call/ConstructVarargs

These two builtins are a special case in that their calling convention
must be kept in-sync since they are both generated from
Generate_CallOrConstructVarargs.

ConstructVarargs in particular used all available registers. In order
to free ebx, the calling convention is changed to pass the last
argument on the stack.

As part of this change, the order of the last two arguments is swapped
since the stack parameter must be tagged.

Bug: v8:6666
Change-Id: If1ad14fc09693c36dd63ffebb6f34fcd3f012896
Reviewed-on: https://chromium-review.googlesource.com/1193444
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55458}
This commit is contained in:
jgruber 2018-08-28 14:19:33 +02:00 committed by Commit Bot
parent dd40b33371
commit 988d703f23
11 changed files with 69 additions and 59 deletions

View File

@ -88,9 +88,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// r0 : number of arguments (on the stack, not including receiver)
// r1 : the target to call
// r2 : arguments list (FixedArray)
// r4 : arguments list length (untagged)
Register registers[] = {r1, r0, r2, r4};
// r2 : arguments list (FixedArray)
Register registers[] = {r1, r0, r4, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -125,9 +125,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// r0 : number of arguments (on the stack, not including receiver)
// r1 : the target to call
// r3 : the new target
// r2 : arguments list (FixedArray)
// r4 : arguments list length (untagged)
Register registers[] = {r1, r3, r0, r2, r4};
// r2 : arguments list (FixedArray)
Register registers[] = {r1, r3, r0, r4, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -89,9 +89,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x0 : number of arguments (on the stack, not including receiver)
// x1 : the target to call
// x2 : arguments list (FixedArray)
// x4 : arguments list length (untagged)
Register registers[] = {x1, x0, x2, x4};
// x2 : arguments list (FixedArray)
Register registers[] = {x1, x0, x4, x2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -126,9 +126,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// x0 : number of arguments (on the stack, not including receiver)
// x1 : the target to call
// x3 : the new target
// x2 : arguments list (FixedArray)
// x4 : arguments list length (untagged)
Register registers[] = {x1, x3, x0, x2, x4};
// x2 : arguments list (FixedArray)
Register registers[] = {x1, x3, x0, x4, x2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -211,11 +211,11 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithArrayLike(
{
if (new_target == nullptr) {
Callable callable = CodeFactory::CallVarargs(isolate());
TailCallStub(callable, context, target, args_count, elements, length);
TailCallStub(callable, context, target, args_count, length, elements);
} else {
Callable callable = CodeFactory::ConstructVarargs(isolate());
TailCallStub(callable, context, target, new_target, args_count,
elements, length);
TailCallStub(callable, context, target, new_target, args_count, length,
elements);
}
}
@ -266,11 +266,11 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructDoubleVarargs(
{
if (new_target == nullptr) {
Callable callable = CodeFactory::CallVarargs(isolate());
TailCallStub(callable, context, target, args_count, new_elements, length);
TailCallStub(callable, context, target, args_count, length, new_elements);
} else {
Callable callable = CodeFactory::ConstructVarargs(isolate());
TailCallStub(callable, context, target, new_target, args_count,
new_elements, length);
TailCallStub(callable, context, target, new_target, args_count, length,
new_elements);
}
}
}
@ -346,11 +346,11 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
if (new_target == nullptr) {
Callable callable = CodeFactory::CallVarargs(isolate());
TailCallStub(callable, context, target, args_count, elements, length);
TailCallStub(callable, context, target, args_count, length, elements);
} else {
Callable callable = CodeFactory::ConstructVarargs(isolate());
TailCallStub(callable, context, target, new_target, args_count, elements,
length);
TailCallStub(callable, context, target, new_target, args_count, length,
elements);
}
}

View File

@ -1657,9 +1657,9 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
// ----------- S t a t e -------------
// -- edi : target
// -- eax : number of parameters on the stack (not including the receiver)
// -- ebx : arguments list (a FixedArray)
// -- ecx : len (number of elements to from args)
// -- edx : new.target (checked to be constructor or undefined)
// -- ecx : new.target (checked to be constructor or undefined)
// -- esp[4] : arguments list (a FixedArray)
// -- esp[0] : return address.
// -----------------------------------
@ -1668,16 +1668,25 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
__ movd(xmm1, edi);
__ movd(xmm2, eax);
// TODO(v8:6666): Remove this usage of ebx to enable kRootRegister support.
const Register kArgumentsList = ebx;
const Register kArgumentsLength = ecx;
__ PopReturnAddressTo(edx);
__ pop(kArgumentsList);
__ PushReturnAddressFrom(edx);
if (masm->emit_debug_code()) {
// Allow ebx to be a FixedArray, or a FixedDoubleArray if ecx == 0.
// Allow kArgumentsList to be a FixedArray, or a FixedDoubleArray if
// kArgumentsLength == 0.
Label ok, fail;
__ AssertNotSmi(ebx);
__ mov(edx, FieldOperand(ebx, HeapObject::kMapOffset));
__ AssertNotSmi(kArgumentsList);
__ mov(edx, FieldOperand(kArgumentsList, HeapObject::kMapOffset));
__ CmpInstanceType(edx, FIXED_ARRAY_TYPE);
__ j(equal, &ok);
__ CmpInstanceType(edx, FIXED_DOUBLE_ARRAY_TYPE);
__ j(not_equal, &fail);
__ cmp(ecx, 0);
__ cmp(kArgumentsLength, 0);
__ j(equal, &ok);
// Fall through.
__ bind(&fail);
@ -1700,7 +1709,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
__ add(edx, esp);
__ sar(edx, kPointerSizeLog2);
// Check if the arguments will overflow the stack.
__ cmp(edx, ecx);
__ cmp(edx, kArgumentsLength);
__ j(greater, &done, Label::kNear); // Signed comparison.
__ TailCallRuntime(Runtime::kThrowStackOverflow);
__ bind(&done);
@ -1712,11 +1721,11 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
__ Move(eax, Immediate(0));
Label done, push, loop;
__ bind(&loop);
__ cmp(eax, ecx);
__ cmp(eax, kArgumentsLength);
__ j(equal, &done, Label::kNear);
// Turn the hole into undefined as we go.
__ mov(edi,
FieldOperand(ebx, eax, times_pointer_size, FixedArray::kHeaderSize));
__ mov(edi, FieldOperand(kArgumentsList, eax, times_pointer_size,
FixedArray::kHeaderSize));
__ CompareRoot(edi, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &push, Label::kNear);
__ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
@ -1734,7 +1743,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
__ movd(edx, xmm0);
// Compute the actual parameter count.
__ add(eax, ecx);
__ add(eax, kArgumentsLength);
// Tail-call to the actual Call or Construct builtin.
__ Jump(code, RelocInfo::CODE_TARGET);

View File

@ -96,9 +96,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// eax : number of arguments (on the stack, not including receiver)
// edi : the target to call
// ebx : arguments list (FixedArray)
// ecx : arguments list length (untagged)
Register registers[] = {edi, eax, ebx, ecx};
// On the stack : arguments list (FixedArray)
Register registers[] = {edi, eax, ecx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -133,9 +133,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// eax : number of arguments (on the stack, not including receiver)
// edi : the target to call
// edx : the new target
// ebx : arguments list (FixedArray)
// ecx : arguments list length (untagged)
Register registers[] = {edi, edx, eax, ebx, ecx};
// On the stack : arguments list (FixedArray)
Register registers[] = {edi, edx, eax, ecx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -690,12 +690,12 @@ class CallTrampolineDescriptor : public CallInterfaceDescriptor {
class CallVarargsDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsList,
kArgumentsLength)
DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsLength,
kArgumentsList)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
MachineType::Int32(), // kActualArgumentsCount
MachineType::AnyTagged(), // kArgumentsList
MachineType::Int32()) // kArgumentsLength
MachineType::Int32(), // kArgumentsLength
MachineType::AnyTagged()) // kArgumentsList
DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
};
@ -727,9 +727,10 @@ class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_JS_PARAMETERS(kArgumentsList, kArgumentsLength)
DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged(), // kArgumentsList
MachineType::Int32()) // kArgumentsLength
DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(), // kArgumentsLength
MachineType::AnyTagged()) // kArgumentsList
DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
};

View File

@ -88,9 +88,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// a0 : number of arguments (on the stack, not including receiver)
// a1 : the target to call
// a2 : arguments list (FixedArray)
// t0 : arguments list length (untagged)
Register registers[] = {a1, a0, a2, t0};
// a2 : arguments list (FixedArray)
Register registers[] = {a1, a0, t0, a2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -125,9 +125,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// a0 : number of arguments (on the stack, not including receiver)
// a1 : the target to call
// a3 : the new target
// a2 : arguments list (FixedArray)
// t0 : arguments list length (untagged)
Register registers[] = {a1, a3, a0, a2, t0};
// a2 : arguments list (FixedArray)
Register registers[] = {a1, a3, a0, t0, a2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -88,9 +88,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// a0 : number of arguments (on the stack, not including receiver)
// a1 : the target to call
// a2 : arguments list (FixedArray)
// a4 : arguments list length (untagged)
Register registers[] = {a1, a0, a2, a4};
// a2 : arguments list (FixedArray)
Register registers[] = {a1, a0, a4, a2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -125,9 +125,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// a0 : number of arguments (on the stack, not including receiver)
// a1 : the target to call
// a3 : the new target
// a2 : arguments list (FixedArray)
// a4 : arguments list length (untagged)
Register registers[] = {a1, a3, a0, a2, a4};
// a2 : arguments list (FixedArray)
Register registers[] = {a1, a3, a0, a4, a2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -88,9 +88,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r5 : arguments list (FixedArray)
// r7 : arguments list length (untagged)
Register registers[] = {r4, r3, r5, r7};
// r5 : arguments list (FixedArray)
Register registers[] = {r4, r3, r7, r5};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -125,9 +125,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r6 : the new target
// r5 : arguments list (FixedArray)
// r7 : arguments list length (untagged)
Register registers[] = {r4, r6, r3, r5, r7};
// r5 : arguments list (FixedArray)
Register registers[] = {r4, r6, r3, r7, r5};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -87,9 +87,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// r2 : number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r4 : arguments list (FixedArray)
// r6 : arguments list length (untagged)
Register registers[] = {r3, r2, r4, r6};
// r4 : arguments list (FixedArray)
Register registers[] = {r3, r2, r6, r4};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -124,9 +124,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// r2 : number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r5 : the new target
// r4 : arguments list (FixedArray)
// r6 : arguments list length (untagged)
Register registers[] = {r3, r5, r2, r4, r6};
// r4 : arguments list (FixedArray)
Register registers[] = {r3, r5, r2, r6, r4};
data->InitializePlatformSpecific(arraysize(registers), registers);
}

View File

@ -90,9 +90,9 @@ void CallVarargsDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// rax : number of arguments (on the stack, not including receiver)
// rdi : the target to call
// rbx : arguments list (FixedArray)
// rcx : arguments list length (untagged)
Register registers[] = {rdi, rax, rbx, rcx};
// rbx : arguments list (FixedArray)
Register registers[] = {rdi, rax, rcx, rbx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
@ -127,9 +127,9 @@ void ConstructVarargsDescriptor::InitializePlatformSpecific(
// rax : number of arguments (on the stack, not including receiver)
// rdi : the target to call
// rdx : the new target
// rbx : arguments list (FixedArray)
// rcx : arguments list length (untagged)
Register registers[] = {rdi, rdx, rax, rbx, rcx};
// rbx : arguments list (FixedArray)
Register registers[] = {rdi, rdx, rax, rcx, rbx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}