@@ -76,6 +76,32 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
7676
7777namespace {
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+
79105void 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
20102067void 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 (©);
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, ©);
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 (©);
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, ©);
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