Skip to content

Commit 89933af

Browse files
Patrick ThierV8 LUCI CQ
authored andcommitted
[masm] Create helpers to manipulate arguments on the stack.
- Introduce helper to push arguments onto the stack (Standalone this change doesn't make a lot of sense, but is in preparation for including the receiver in argc). - Introduce helper to shift arguments already on the stack to make room for new arguments (Varargs). - arm64 is not included because a) there was already a helper similar to ShiftArguments and b) PushArguments is not similar enough to make sense for arm64 because of small differences (e.g. also pushing the function) in conjunction with stack alignment. Drive-by: Use masm DropArguments in Sparkplug EmitReturn Bug: v8:11112 Change-Id: Id7a3a5f025abb19e2a52dae27b3b484fe87e9faf Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3097275 Reviewed-by: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Patrick Thier <pthier@chromium.org> Cr-Commit-Position: refs/heads/main@{#76392}
1 parent 30f5140 commit 89933af

7 files changed

Lines changed: 290 additions & 198 deletions

File tree

src/baseline/arm/baseline-assembler-arm-inl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,8 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
501501
__ masm()->LeaveFrame(StackFrame::BASELINE);
502502

503503
// Drop receiver + arguments.
504-
__ masm()->add(params_size, params_size,
505-
Operand(1)); // Include the receiver.
506-
__ masm()->Drop(params_size);
504+
__ masm()->DropArguments(params_size, TurboAssembler::kCountIsInteger,
505+
TurboAssembler::kCountExcludesReceiver);
507506
__ masm()->Ret();
508507
}
509508

src/baseline/arm64/baseline-assembler-arm64-inl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,7 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
583583
__ masm()->LeaveFrame(StackFrame::BASELINE);
584584

585585
// Drop receiver + arguments.
586-
__ masm()->Add(params_size, params_size, 1); // Include the receiver.
587-
__ masm()->DropArguments(params_size);
586+
__ masm()->DropArguments(params_size, TurboAssembler::kCountExcludesReceiver);
588587
__ masm()->Ret();
589588
}
590589

src/baseline/ia32/baseline-assembler-ia32-inl.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,9 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
457457
__ masm()->LeaveFrame(StackFrame::BASELINE);
458458

459459
// Drop receiver + arguments.
460-
Register return_pc = scratch;
461-
__ masm()->PopReturnAddressTo(return_pc);
462-
__ masm()->lea(esp, MemOperand(esp, params_size, times_system_pointer_size,
463-
kSystemPointerSize));
464-
__ masm()->PushReturnAddressFrom(return_pc);
460+
__ masm()->DropArguments(params_size, scratch,
461+
TurboAssembler::kCountIsInteger,
462+
TurboAssembler::kCountExcludesReceiver);
465463
__ masm()->Ret();
466464
}
467465

src/baseline/x64/baseline-assembler-x64-inl.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,9 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
468468
__ masm()->LeaveFrame(StackFrame::BASELINE);
469469

470470
// Drop receiver + arguments.
471-
Register return_pc = scratch;
472-
__ masm()->PopReturnAddressTo(return_pc);
473-
__ masm()->leaq(rsp, MemOperand(rsp, params_size, times_system_pointer_size,
474-
kSystemPointerSize));
475-
__ masm()->PushReturnAddressFrom(return_pc);
471+
__ masm()->DropArguments(params_size, scratch,
472+
TurboAssembler::kCountIsInteger,
473+
TurboAssembler::kCountExcludesReceiver);
476474
__ masm()->Ret();
477475
}
478476

src/builtins/arm/builtins-arm.cc

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,32 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
7676

7777
namespace {
7878

79+
enum class ArgumentsElementType {
80+
kRaw, // Push arguments as they are.
81+
kHandle // Dereference arguments before pushing.
82+
};
83+
84+
void Generate_PushArguments(MacroAssembler* masm, Register array, Register argc,
85+
Register scratch,
86+
ArgumentsElementType element_type) {
87+
DCHECK(!AreAliased(array, argc, scratch));
88+
UseScratchRegisterScope temps(masm);
89+
Register counter = scratch;
90+
Register value = temps.Acquire();
91+
Label loop, entry;
92+
__ mov(counter, argc);
93+
__ b(&entry);
94+
__ bind(&loop);
95+
__ ldr(value, MemOperand(array, counter, LSL, kSystemPointerSizeLog2));
96+
if (element_type == ArgumentsElementType::kHandle) {
97+
__ ldr(value, MemOperand(value));
98+
}
99+
__ push(value);
100+
__ bind(&entry);
101+
__ sub(counter, counter, Operand(1), SetCC);
102+
__ b(ge, &loop);
103+
}
104+
79105
void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
80106
// ----------- S t a t e -------------
81107
// -- r0 : number of arguments
@@ -106,12 +132,14 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
106132
// correct position (including any undefined), instead of delaying this to
107133
// InvokeFunction.
108134

109-
// Set up pointer to last argument (skip receiver).
135+
// Set up pointer to first argument (skip receiver).
110136
__ add(
111137
r4, fp,
112138
Operand(StandardFrameConstants::kCallerSPOffset + kSystemPointerSize));
113139
// Copy arguments and receiver to the expression stack.
114-
__ PushArray(r4, r0, r5);
140+
// r4: Pointer to start of arguments.
141+
// r0: Number of arguments.
142+
Generate_PushArguments(masm, r4, r0, r5, ArgumentsElementType::kRaw);
115143
// The receiver for the builtin/api call.
116144
__ PushRoot(RootIndex::kTheHoleValue);
117145

@@ -230,7 +258,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
230258
// InvokeFunction.
231259

232260
// Copy arguments to the expression stack.
233-
__ PushArray(r4, r0, r5);
261+
// r4: Pointer to start of argument.
262+
// r0: Number of arguments.
263+
Generate_PushArguments(masm, r4, r0, r5, ArgumentsElementType::kRaw);
234264

235265
// Push implicit receiver.
236266
__ Push(r6);
@@ -715,24 +745,13 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
715745

716746
__ bind(&enough_stack_space);
717747

718-
// Copy arguments to the stack in a loop.
748+
// Copy arguments to the stack.
719749
// r1: new.target
720750
// r2: function
721751
// r3: receiver
722752
// r0: argc
723753
// r4: argv, i.e. points to first arg
724-
Label loop, entry;
725-
__ add(r6, r4, Operand(r0, LSL, kSystemPointerSizeLog2));
726-
// r6 points past last arg.
727-
__ b(&entry);
728-
__ bind(&loop);
729-
__ ldr(r5, MemOperand(r6, -kSystemPointerSize,
730-
PreIndex)); // read next parameter
731-
__ ldr(r5, MemOperand(r5)); // dereference handle
732-
__ push(r5); // push parameter
733-
__ bind(&entry);
734-
__ cmp(r4, r6);
735-
__ b(ne, &loop);
754+
Generate_PushArguments(masm, r4, r0, r5, ArgumentsElementType::kHandle);
736755

737756
// Push the receiver.
738757
__ Push(r3);
@@ -2005,6 +2024,44 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
20052024
RelocInfo::CODE_TARGET);
20062025
}
20072026

2027+
namespace {
2028+
2029+
// Allocate new stack space for |count| arguments and shift all existing
2030+
// arguments already on the stack. |pointer_to_new_space_out| points to the
2031+
// first free slot on the stack to copy additional arguments to and
2032+
// |argc_in_out| is updated to include |count|.
2033+
void Generate_AllocateSpaceAndShiftExistingArguments(
2034+
MacroAssembler* masm, Register count, Register argc_in_out,
2035+
Register pointer_to_new_space_out, Register scratch1, Register scratch2) {
2036+
DCHECK(!AreAliased(count, argc_in_out, pointer_to_new_space_out, scratch1,
2037+
scratch2));
2038+
UseScratchRegisterScope temps(masm);
2039+
Register old_sp = scratch1;
2040+
Register new_space = scratch2;
2041+
__ mov(old_sp, sp);
2042+
__ lsl(new_space, count, Operand(kSystemPointerSizeLog2));
2043+
__ AllocateStackSpace(new_space);
2044+
2045+
Register end = scratch2;
2046+
Register value = temps.Acquire();
2047+
Register dest = pointer_to_new_space_out;
2048+
__ mov(dest, sp);
2049+
__ add(end, old_sp, Operand(argc_in_out, LSL, kSystemPointerSizeLog2));
2050+
Label loop, done;
2051+
__ bind(&loop);
2052+
__ cmp(old_sp, end);
2053+
__ b(gt, &done);
2054+
__ ldr(value, MemOperand(old_sp, kSystemPointerSize, PostIndex));
2055+
__ str(value, MemOperand(dest, kSystemPointerSize, PostIndex));
2056+
__ b(&loop);
2057+
__ bind(&done);
2058+
2059+
// Update total number of arguments.
2060+
__ add(argc_in_out, argc_in_out, count);
2061+
}
2062+
2063+
} // namespace
2064+
20082065
// static
20092066
// TODO(v8:11615): Observe Code::kMaxArguments in CallOrConstructVarargs
20102067
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
@@ -2042,23 +2099,10 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
20422099

20432100
// Move the arguments already in the stack,
20442101
// including the receiver and the return address.
2045-
{
2046-
Label copy, check;
2047-
Register num = r5, src = r6, dest = r9; // r7 and r8 are context and root.
2048-
__ mov(src, sp);
2049-
// Update stack pointer.
2050-
__ lsl(scratch, r4, Operand(kSystemPointerSizeLog2));
2051-
__ AllocateStackSpace(scratch);
2052-
__ mov(dest, sp);
2053-
__ mov(num, r0);
2054-
__ b(&check);
2055-
__ bind(&copy);
2056-
__ ldr(scratch, MemOperand(src, kSystemPointerSize, PostIndex));
2057-
__ str(scratch, MemOperand(dest, kSystemPointerSize, PostIndex));
2058-
__ sub(num, num, Operand(1), SetCC);
2059-
__ bind(&check);
2060-
__ b(ge, &copy);
2061-
}
2102+
// r4: Number of arguments to make room for.
2103+
// r0: Number of arguments already on the stack.
2104+
// r9: Points to first free slot on the stack after arguments were shifted.
2105+
Generate_AllocateSpaceAndShiftExistingArguments(masm, r4, r0, r9, r5, r6);
20622106

20632107
// Copy arguments onto the stack (thisArgument is already on the stack).
20642108
{
@@ -2077,7 +2121,6 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
20772121
__ add(r6, r6, Operand(1));
20782122
__ b(&loop);
20792123
__ bind(&done);
2080-
__ add(r0, r0, r6);
20812124
}
20822125

20832126
// Tail-call to the actual Call or Construct builtin.
@@ -2145,30 +2188,17 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
21452188

21462189
// Move the arguments already in the stack,
21472190
// including the receiver and the return address.
2148-
{
2149-
Label copy, check;
2150-
Register num = r8, src = r9,
2151-
dest = r2; // r7 and r10 are context and root.
2152-
__ mov(src, sp);
2153-
// Update stack pointer.
2154-
__ lsl(scratch, r5, Operand(kSystemPointerSizeLog2));
2155-
__ AllocateStackSpace(scratch);
2156-
__ mov(dest, sp);
2157-
__ mov(num, r0);
2158-
__ b(&check);
2159-
__ bind(&copy);
2160-
__ ldr(scratch, MemOperand(src, kSystemPointerSize, PostIndex));
2161-
__ str(scratch, MemOperand(dest, kSystemPointerSize, PostIndex));
2162-
__ sub(num, num, Operand(1), SetCC);
2163-
__ bind(&check);
2164-
__ b(ge, &copy);
2165-
}
2191+
// r5: Number of arguments to make room for.
2192+
// r0: Number of arguments already on the stack.
2193+
// r2: Points to first free slot on the stack after arguments were shifted.
2194+
Generate_AllocateSpaceAndShiftExistingArguments(masm, r5, r0, r2, scratch,
2195+
r8);
2196+
21662197
// Copy arguments from the caller frame.
21672198
// TODO(victorgomes): Consider using forward order as potentially more cache
21682199
// friendly.
21692200
{
21702201
Label loop;
2171-
__ add(r0, r0, r5);
21722202
__ bind(&loop);
21732203
{
21742204
__ sub(r5, r5, Operand(1), SetCC);

0 commit comments

Comments
 (0)