Update JSEntry for MIPS for new parameter ordering
As a follow-up of https://crrev.com/c/1372857 that repordered
the parameters of JSEntry, this CL updates JSEntry for MIPS for new
ordering.
Bug: v8:8124
Change-Id: Ic7f22a4f59b1c15a959a3249b4f13cd8f3f1c331
Reviewed-on: https://chromium-review.googlesource.com/c/1405166
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58721}
diff --git a/src/builtins/mips/builtins-mips.cc b/src/builtins/mips/builtins-mips.cc
index 16f8d21..8654db6 100644
--- a/src/builtins/mips/builtins-mips.cc
+++ b/src/builtins/mips/builtins-mips.cc
@@ -370,20 +370,21 @@
__ CallRuntime(Runtime::kThrowConstructedNonConstructable);
}
-// Clobbers a2; preserves all other registers.
-static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc) {
+// Clobbers scratch1 and scratch2; preserves all other registers.
+static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc,
+ Register scratch1, Register scratch2) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
Label okay;
- __ LoadRoot(a2, RootIndex::kRealStackLimit);
+ __ LoadRoot(scratch1, RootIndex::kRealStackLimit);
// Make a2 the space we have left. The stack might already be overflowed
// here which will cause a2 to become negative.
- __ Subu(a2, sp, a2);
+ __ Subu(scratch1, sp, scratch1);
// Check if the arguments will overflow the stack.
- __ sll(t3, argc, kPointerSizeLog2);
+ __ sll(scratch2, argc, kPointerSizeLog2);
// Signed comparison.
- __ Branch(&okay, gt, a2, Operand(t3));
+ __ Branch(&okay, gt, scratch1, Operand(scratch2));
// Out of stack space.
__ CallRuntime(Runtime::kThrowStackOverflow);
@@ -393,57 +394,51 @@
namespace {
+// Used by JSEntryTrampoline to refer C++ parameter to JSEntryVariant.
+constexpr int kPushedStackSpace =
+ kCArgsSlotsSize + (kNumCalleeSaved + 1) * kPointerSize +
+ kNumCalleeSavedFPU * kDoubleSize + 4 * kPointerSize +
+ EntryFrameConstants::kCallerFPOffset;
+
// Called with the native C calling convention. The corresponding function
-// signature is:
+// signature is either:
//
-// using JSEntryFunction = GeneratedCode<Address(
-// Address root_register_value, Address new_target, Address target,
-// Address receiver, intptr_t argc, Address** args)>;
+// using JSEntryFunction = GeneratedCode<Address(
+// Address root_register_value, Address new_target, Address target,
+// Address receiver, intptr_t argc, Address** argv)>;
+// or
+// using JSEntryFunction = GeneratedCode<Address(
+// Address root_register_value, MicrotaskQueue* microtask_queue)>;
+//
+// Passes through a0, a1, a2, a3 and stack to JSEntryTrampoline.
void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
Builtins::Name entry_trampoline) {
- // TODO(tzik): |root_register_value| is moved from sixth to first. Update
- // JSEntryVariant and JSEntryTrampoline for it.
-
Label invoke, handler_entry, exit;
- static constexpr int kPushedStackSpace =
- (kNumCalleeSaved + 1) * kPointerSize + kNumCalleeSavedFPU * kDoubleSize;
-
+ int pushed_stack_space = kCArgsSlotsSize;
{
NoRootArrayScope no_root_array(masm);
// Registers:
- // a0: entry address
- // a1: function
- // a2: receiver
- // a3: argc
- //
- // Stack:
- // 4 arg slots
- // argv
- // root register value
+ // a0: root_register_value
// Save callee saved registers on the stack.
__ MultiPush(kCalleeSaved | ra.bit());
+ pushed_stack_space +=
+ kNumCalleeSaved * kPointerSize + kPointerSize /* ra */;
// Save callee-saved FPU registers.
__ MultiPushFPU(kCalleeSavedFPU);
+ pushed_stack_space += kNumCalleeSavedFPU * kDoubleSize;
+
// Set up the reserved register for 0.0.
__ Move(kDoubleRegZero, 0.0);
// Initialize the root register.
- // C calling convention. The sixth argument is passed on the stack.
- static constexpr int kOffsetToRootRegisterValue =
- kPushedStackSpace + kCArgsSlotsSize +
- EntryFrameConstants::kRootRegisterValueOffset;
- __ lw(kRootRegister, MemOperand(sp, kOffsetToRootRegisterValue));
+ // C calling convention. The first argument is passed in a0.
+ __ mov(kRootRegister, a0);
}
- // Load argv in s0 register.
- static constexpr int kOffsetToArgv =
- kPushedStackSpace + kCArgsSlotsSize + EntryFrameConstants::kArgvOffset;
- __ lw(s0, MemOperand(sp, kOffsetToArgv));
-
// We build an EntryFrame.
__ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used.
__ li(t2, Operand(StackFrame::TypeToMarker(type)));
@@ -452,15 +447,14 @@
masm->isolate()));
__ lw(t0, MemOperand(t0));
__ Push(t3, t2, t1, t0);
+ pushed_stack_space += 4 * kPointerSize;
+
// Set up frame pointer for the frame to be pushed.
__ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
+ pushed_stack_space += EntryFrameConstants::kCallerFPOffset;
// Registers:
- // a0: entry_address
- // a1: function
- // a2: receiver_pointer
- // a3: argc
- // s0: argv
+ // a0: root_register_value
//
// Stack:
// caller fp |
@@ -469,7 +463,6 @@
// bad fp (0xFF...F) |
// callee saved registers + ra
// 4 args slots
- // args
// If this is the outermost JS call, set js_entry_sp value.
Label non_outermost_js;
@@ -516,24 +509,19 @@
// restores all kCalleeSaved registers (including cp and fp) to their
// saved values before returning a failure to C.
//
- // Registers:
- // a0: entry_address
- // a1: function
- // a2: receiver_pointer
- // a3: argc
- // s0: argv
+ // Preserve a1, a2 and a3 passed by C++ and pass them to the trampoline.
//
// Stack:
// handler frame
// entry frame
// callee saved registers + ra
// 4 args slots
- // args
//
// Invoke the function by calling through JS entry trampoline builtin and
// pop the faked function when we return.
Handle<Code> trampoline_code =
masm->isolate()->builtins()->builtin_handle(entry_trampoline);
+ DCHECK_EQ(kPushedStackSpace, pushed_stack_space);
__ Call(trampoline_code, RelocInfo::CODE_TARGET);
// Unlink this frame from the handler chain.
@@ -586,11 +574,12 @@
static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
bool is_construct) {
// ----------- S t a t e -------------
- // -- a0: new.target
- // -- a1: function
- // -- a2: receiver_pointer
- // -- a3: argc
- // -- s0: argv
+ // -- a0: root_register_value (unused)
+ // -- a1: new.target
+ // -- a2: function
+ // -- a3: receiver_pointer
+ // -- [fp + kPushedStackSpace + 0 * kPointerSize]: argc
+ // -- [fp + kPushedStackSpace + 1 * kPointerSize]: argv
// -----------------------------------
// Enter an internal frame.
@@ -604,20 +593,31 @@
__ lw(cp, MemOperand(cp));
// Push the function and the receiver onto the stack.
- __ Push(a1, a2);
+ __ Push(a2, a3);
+
+ __ mov(a3, a1);
+ __ mov(a1, a2);
+
+ __ lw(s0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+ __ lw(a0,
+ MemOperand(s0, kPushedStackSpace + EntryFrameConstants::kArgcOffset));
+ __ lw(s0,
+ MemOperand(s0, kPushedStackSpace + EntryFrameConstants::kArgvOffset));
+
+ // a0: argc
+ // a1: function
+ // a3: new.target
+ // s0: argv
// Check if we have enough stack space to push all arguments.
- // Clobbers a2.
- Generate_CheckStackOverflow(masm, a3);
-
- // Remember new.target.
- __ mov(t1, a0);
+ // Clobbers a2 and t0.
+ Generate_CheckStackOverflow(masm, a0, a2, t0);
// Copy arguments to the stack in a loop.
- // a3: argc
+ // a0: argc
// s0: argv, i.e. points to first arg
Label loop, entry;
- __ Lsa(t2, s0, a3, kPointerSizeLog2);
+ __ Lsa(t2, s0, a0, kPointerSizeLog2);
__ b(&entry);
__ nop(); // Branch delay slot nop.
// t2 points past last arg.
@@ -629,13 +629,14 @@
__ bind(&entry);
__ Branch(&loop, ne, s0, Operand(t2));
- // Setup new.target and argc.
- __ mov(a0, a3);
- __ mov(a3, t1);
+ // a0: argc
+ // a1: function
+ // a3: new.target
// Initialize all JavaScript callee-saved registers, since they will be seen
// by the garbage collector as part of handlers.
__ LoadRoot(t0, RootIndex::kUndefinedValue);
+ __ mov(s0, t0);
__ mov(s1, t0);
__ mov(s2, t0);
__ mov(s3, t0);
diff --git a/src/mips/frame-constants-mips.h b/src/mips/frame-constants-mips.h
index 4e80158..eab0e9b 100644
--- a/src/mips/frame-constants-mips.h
+++ b/src/mips/frame-constants-mips.h
@@ -19,8 +19,8 @@
-(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
// Stack offsets for arguments passed to JSEntry.
- static constexpr int kArgvOffset = +0 * kSystemPointerSize;
- static constexpr int kRootRegisterValueOffset = +1 * kSystemPointerSize;
+ static constexpr int kArgcOffset = +0 * kSystemPointerSize;
+ static constexpr int kArgvOffset = +1 * kSystemPointerSize;
};
class ExitFrameConstants : public TypedFrameConstants {