[arm64] ArgumentsAdaptorTrampoline fix for jssp removal.

Even though a previous patch made the number of slots pushed/claimed on
the stack aligned, the boundary between frames was not a multiple of
two slots as well. We were pushing the number of arguments (which belongs
in the ArgumentAdaptor frame) together with the arguments to pass to the
callee (which belong to the frame of the callee). Those need to be
separated so we can drop the arguments without messing up the alignment.

Bug: v8:6644
Change-Id: I259c58db33a7c2726e5a3c74bcd67496f607d1d0
Reviewed-on: https://chromium-review.googlesource.com/793047
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Georgia Kouveli <georgia.kouveli@arm.com>
Cr-Commit-Position: refs/heads/master@{#49759}
This commit is contained in:
Georgia Kouveli 2017-11-29 17:04:39 +00:00 committed by Commit Bot
parent 1de9248e4f
commit 1228c556b6
10 changed files with 68 additions and 50 deletions

View File

@ -1799,8 +1799,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ mov(r4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ mov(r4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
__ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
fp.bit() | lr.bit()); fp.bit() | lr.bit());
__ Push(Smi::kZero); // Padding.
__ add(fp, sp, __ add(fp, sp,
Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -1809,8 +1810,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then tear down the parameters. // then tear down the parameters.
__ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ ldr(r1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
__ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
@ -2434,8 +2434,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
__ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2)); __ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
// Adjust for frame. // Adjust for frame.
__ sub(r4, r4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ sub(r4, r4,
2 * kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
kPointerSize));
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);

View File

@ -2064,10 +2064,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ Push(lr, fp); __ Push(lr, fp);
__ Mov(x11, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)); __ Mov(x11, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
__ Push(x11, x1); // x1: function __ Push(x11, x1); // x1: function
// We do not yet push the number of arguments, to maintain a 16-byte aligned __ SmiTag(x11, x0); // x0: number of arguments.
// stack pointer. This is done in step (3) in __ Push(x11, padreg);
// Generate_ArgumentsAdaptorTrampoline. __ Add(fp, jssp, ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp);
__ Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -2076,8 +2075,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then drop the parameters and the receiver. // then drop the parameters and the receiver.
__ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ Ldr(x10, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
__ Mov(jssp, fp); __ Mov(jssp, fp);
__ Pop(fp, lr); __ Pop(fp, lr);
@ -2651,14 +2649,16 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// 4 | num of | | // 4 | num of | |
// | actual args | | // | actual args | |
// |- - - - - - - - -| | // |- - - - - - - - -| |
// [5] | [padding] | | // 5 | padding | |
// |-----------------+---- | // |-----------------+---- |
// 5+pad | receiver | ^ | // [6] | [padding] | ^ |
// |- - - - - - - - -| | |
// 6+pad | receiver | | |
// | (parameter 0) | | | // | (parameter 0) | | |
// |- - - - - - - - -| | | // |- - - - - - - - -| | |
// 6+pad | parameter 1 | | | // 7+pad | parameter 1 | | |
// |- - - - - - - - -| Frame slots ----> expected args // |- - - - - - - - -| Frame slots ----> expected args
// 7+pad | parameter 2 | | | // 8+pad | parameter 2 | | |
// |- - - - - - - - -| | | // |- - - - - - - - -| | |
// | | | | // | | | |
// ... | ... | | | // ... | ... | | |
@ -2671,7 +2671,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// | [undefined] | v <-- stack ptr v // | [undefined] | v <-- stack ptr v
// -----+-----------------+--------------------------------- // -----+-----------------+---------------------------------
// //
// There is an optional slot of padding to ensure stack alignment. // There is an optional slot of padding above the receiver to ensure stack
// alignment of the arguments.
// If the number of expected arguments is larger than the number of actual // If the number of expected arguments is larger than the number of actual
// arguments, the remaining expected slots will be filled with undefined. // arguments, the remaining expected slots will be filled with undefined.
@ -2695,10 +2696,10 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
Register argc_unused_actual = x14; Register argc_unused_actual = x14;
Register scratch1 = x15, scratch2 = x16; Register scratch1 = x15, scratch2 = x16;
// We need slots for the expected arguments, with two extra slots for the // We need slots for the expected arguments, with one extra slot for the
// number of actual arguments and the receiver. // receiver.
__ RecordComment("-- Stack check --"); __ RecordComment("-- Stack check --");
__ Add(scratch1, argc_expected, 2); __ Add(scratch1, argc_expected, 1);
Generate_StackOverflowCheck(masm, scratch1, &stack_overflow); Generate_StackOverflowCheck(masm, scratch1, &stack_overflow);
// Round up number of slots to be even, to maintain stack alignment. // Round up number of slots to be even, to maintain stack alignment.
@ -2738,7 +2739,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ Bind(&enough_arguments); __ Bind(&enough_arguments);
// (2) Copy all of the actual arguments, or as many as we need. // (2) Copy all of the actual arguments, or as many as we need.
Label skip_copy;
__ RecordComment("-- Copy actual arguments --"); __ RecordComment("-- Copy actual arguments --");
__ Cbz(argc_to_copy, &skip_copy);
__ Add(copy_end, copy_to, Operand(argc_to_copy, LSL, kPointerSizeLog2)); __ Add(copy_end, copy_to, Operand(argc_to_copy, LSL, kPointerSizeLog2));
__ Add(copy_from, fp, 2 * kPointerSize); __ Add(copy_from, fp, 2 * kPointerSize);
// Adjust for difference between actual and expected arguments. // Adjust for difference between actual and expected arguments.
@ -2755,12 +2758,12 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ Stp(scratch1, scratch2, MemOperand(copy_to, 2 * kPointerSize, PostIndex)); __ Stp(scratch1, scratch2, MemOperand(copy_to, 2 * kPointerSize, PostIndex));
__ Cmp(copy_end, copy_to); __ Cmp(copy_end, copy_to);
__ B(hi, &copy_2_by_2); __ B(hi, &copy_2_by_2);
__ Bind(&skip_copy);
// (3) Store number of actual arguments and padding. The padding might be // (3) Store padding, which might be overwritten by the receiver, if it is not
// unnecessary, in which case it will be overwritten by the receiver. // necessary.
__ RecordComment("-- Store number of args and padding --"); __ RecordComment("-- Store padding --");
__ SmiTag(scratch1, argc_actual); __ Str(padreg, MemOperand(fp, -5 * kPointerSize));
__ Stp(xzr, scratch1, MemOperand(fp, -4 * kPointerSize));
// (4) Store receiver. Calculate target address from jssp to avoid checking // (4) Store receiver. Calculate target address from jssp to avoid checking
// for padding. Storing the receiver will overwrite either the extra slot // for padding. Storing the receiver will overwrite either the extra slot

View File

@ -1875,6 +1875,8 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTagSize == 1); STATIC_ASSERT(kSmiTagSize == 1);
__ lea(edi, Operand(eax, eax, times_1, kSmiTag)); __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
__ push(edi); __ push(edi);
__ Push(Immediate(0)); // Padding.
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {

View File

@ -1804,8 +1804,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ sll(a0, a0, kSmiTagSize); __ sll(a0, a0, kSmiTagSize);
__ li(t0, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ li(t0, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
__ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit()); __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit());
__ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ Push(Smi::kZero); // Padding.
kPointerSize)); __ Addu(fp, sp,
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -1814,8 +1815,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then tear down the parameters. // then tear down the parameters.
__ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ lw(a1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
__ mov(sp, fp); __ mov(sp, fp);
__ MultiPop(fp.bit() | ra.bit()); __ MultiPop(fp.bit() | ra.bit());
__ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize); __ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize);
@ -2489,8 +2489,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ sll(t2, a2, kPointerSizeLog2); __ sll(t2, a2, kPointerSizeLog2);
__ Subu(t1, fp, Operand(t2)); __ Subu(t1, fp, Operand(t2));
// Adjust for frame. // Adjust for frame.
__ Subu(t1, t1, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ Subu(t1, t1,
2 * kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
kPointerSize));
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);

View File

@ -1820,8 +1820,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ dsll32(a0, a0, 0); __ dsll32(a0, a0, 0);
__ li(a4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ li(a4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
__ MultiPush(a0.bit() | a1.bit() | a4.bit() | fp.bit() | ra.bit()); __ MultiPush(a0.bit() | a1.bit() | a4.bit() | fp.bit() | ra.bit());
__ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ Push(Smi::kZero); // Padding.
kPointerSize)); __ Daddu(fp, sp,
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -1830,8 +1831,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then tear down the parameters. // then tear down the parameters.
__ Ld(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ Ld(a1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
__ mov(sp, fp); __ mov(sp, fp);
__ MultiPop(fp.bit() | ra.bit()); __ MultiPop(fp.bit() | ra.bit());
__ SmiScale(a4, a1, kPointerSizeLog2); __ SmiScale(a4, a1, kPointerSizeLog2);
@ -2510,8 +2510,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ dsll(a6, a2, kPointerSizeLog2); __ dsll(a6, a2, kPointerSizeLog2);
__ Dsubu(a4, fp, Operand(a6)); __ Dsubu(a4, fp, Operand(a6));
// Adjust for frame. // Adjust for frame.
__ Dsubu(a4, a4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ Dsubu(a4, a4,
2 * kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
kPointerSize));
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);

View File

@ -1867,8 +1867,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
} else { } else {
__ Push(fp, r7, r4, r3); __ Push(fp, r7, r4, r3);
} }
__ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ Push(Smi::kZero); // Padding.
kPointerSize)); __ addi(fp, sp,
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -1877,8 +1878,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then tear down the parameters. // then tear down the parameters.
__ LoadP(r4, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ LoadP(r4, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
int stack_adjustment = kPointerSize; // adjust for receiver int stack_adjustment = kPointerSize; // adjust for receiver
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment);
__ SmiToPtrArrayOffset(r0, r4); __ SmiToPtrArrayOffset(r0, r4);
@ -2524,8 +2524,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ ShiftLeftImm(r7, r5, Operand(kPointerSizeLog2)); __ ShiftLeftImm(r7, r5, Operand(kPointerSizeLog2));
__ sub(r7, fp, r7); __ sub(r7, fp, r7);
// Adjust for frame. // Adjust for frame.
__ subi(r7, r7, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ subi(r7, r7,
2 * kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
kPointerSize));
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);

View File

@ -1854,7 +1854,8 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
// Old FP <--- New FP // Old FP <--- New FP
// Argument Adapter SMI // Argument Adapter SMI
// Function // Function
// ArgC as SMI <--- New SP // ArgC as SMI
// Padding <--- New SP
__ lay(sp, MemOperand(sp, -5 * kPointerSize)); __ lay(sp, MemOperand(sp, -5 * kPointerSize));
// Cleanse the top nibble of 31-bit pointers. // Cleanse the top nibble of 31-bit pointers.
@ -1864,8 +1865,9 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ StoreP(r6, MemOperand(sp, 2 * kPointerSize)); __ StoreP(r6, MemOperand(sp, 2 * kPointerSize));
__ StoreP(r3, MemOperand(sp, 1 * kPointerSize)); __ StoreP(r3, MemOperand(sp, 1 * kPointerSize));
__ StoreP(r2, MemOperand(sp, 0 * kPointerSize)); __ StoreP(r2, MemOperand(sp, 0 * kPointerSize));
__ la(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp + __ Push(Smi::kZero); // Padding.
kPointerSize)); __ la(fp,
MemOperand(sp, ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
@ -1874,8 +1876,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Get the number of arguments passed (as a smi), tear down the frame and // Get the number of arguments passed (as a smi), tear down the frame and
// then tear down the parameters. // then tear down the parameters.
__ LoadP(r3, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + __ LoadP(r3, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
kPointerSize)));
int stack_adjustment = kPointerSize; // adjust for receiver int stack_adjustment = kPointerSize; // adjust for receiver
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment);
__ SmiToPtrArrayOffset(r3, r3); __ SmiToPtrArrayOffset(r3, r3);
@ -2522,8 +2523,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ ShiftLeftP(r6, r4, Operand(kPointerSizeLog2)); __ ShiftLeftP(r6, r4, Operand(kPointerSizeLog2));
__ SubP(r6, fp, r6); __ SubP(r6, fp, r6);
// Adjust for frame. // Adjust for frame.
__ SubP(r6, r6, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + __ SubP(r6, r6,
2 * kPointerSize)); Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
kPointerSize));
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);

View File

@ -1863,6 +1863,8 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
// arguments and the receiver. // arguments and the receiver.
__ Integer32ToSmi(r8, rax); __ Integer32ToSmi(r8, rax);
__ Push(r8); __ Push(r8);
__ Push(Immediate(0)); // Padding.
} }
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {

View File

@ -1080,6 +1080,10 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(
PrintF(trace_scope_->file(), "(%d)\n", height - 1); PrintF(trace_scope_->file(), "(%d)\n", height - 1);
} }
output_offset -= kPointerSize;
WriteValueToOutput(isolate()->heap()->the_hole_value(), 0, frame_index,
output_offset, "padding ");
DCHECK_EQ(0, output_offset); DCHECK_EQ(0, output_offset);
Builtins* builtins = isolate_->builtins(); Builtins* builtins = isolate_->builtins();

View File

@ -217,7 +217,8 @@ class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
// FP-relative. // FP-relative.
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0); static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1); static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
DEFINE_TYPED_FRAME_SIZES(2); static const int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
DEFINE_TYPED_FRAME_SIZES(3);
}; };
class BuiltinFrameConstants : public TypedFrameConstants { class BuiltinFrameConstants : public TypedFrameConstants {