mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1112160 - Baseline Stubs: Align the stack when the number of argument is statically known. r=jandem
This commit is contained in:
parent
d0f0f47d58
commit
4041d7bf8f
@ -4099,6 +4099,10 @@ ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg)
|
||||
// Enter stub frame.
|
||||
enterStubFrame(masm, regs.getAny());
|
||||
|
||||
// Align the stack such that the JitFrameLayout is aligned on
|
||||
// JitStackAlignment.
|
||||
masm.alignJitStackBasedOnNArgs(0);
|
||||
|
||||
// Push |this| for getter (target object).
|
||||
{
|
||||
ValueOperand val = regs.takeAnyValue();
|
||||
@ -7372,6 +7376,10 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
||||
masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
|
||||
|
||||
// Align the stack such that the JitFrameLayout is aligned on
|
||||
// JitStackAlignment.
|
||||
masm.alignJitStackBasedOnNArgs(0);
|
||||
|
||||
// Getter is called with 0 arguments, just |obj| as thisv.
|
||||
// Note that we use Push, not push, so that callJit will align the stack
|
||||
// properly on ARM.
|
||||
@ -8866,14 +8874,17 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
||||
masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
|
||||
|
||||
// Align the stack such that the JitFrameLayout is aligned on
|
||||
// JitStackAlignment.
|
||||
masm.alignJitStackBasedOnNArgs(1);
|
||||
|
||||
// Setter is called with the new value as the only argument, and |obj| as thisv.
|
||||
// Note that we use Push, not push, so that callJit will align the stack
|
||||
// properly on ARM.
|
||||
|
||||
// To Push R1, read it off of the stowed values on stack.
|
||||
// Stack: [ ..., R0, R1, ..STUBFRAME-HEADER.. ]
|
||||
masm.movePtr(BaselineStackReg, scratch);
|
||||
masm.PushValue(Address(scratch, STUB_FRAME_SIZE));
|
||||
// Stack: [ ..., R0, R1, ..STUBFRAME-HEADER.., padding? ]
|
||||
masm.PushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE));
|
||||
masm.Push(R0);
|
||||
EmitCreateStubFrameDescriptor(masm, scratch);
|
||||
masm.Push(Imm32(1)); // ActualArgc is 1
|
||||
@ -10835,25 +10846,34 @@ ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
if (canUseTailCallReg)
|
||||
regs.add(BaselineTailCallReg);
|
||||
|
||||
// Decrement argc if argc > 0. If argc == 0, push |undefined| as |this|.
|
||||
Label zeroArgs, done;
|
||||
masm.branchTest32(Assembler::Zero, argcReg, argcReg, &zeroArgs);
|
||||
|
||||
// Avoid the copy of the callee (function.call).
|
||||
masm.sub32(Imm32(1), argcReg);
|
||||
|
||||
// Values are on the stack left-to-right. Calling convention wants them
|
||||
// right-to-left so duplicate them on the stack in reverse order.
|
||||
pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
|
||||
|
||||
// Discard callee (function.call).
|
||||
masm.addPtr(Imm32(sizeof(Value)), StackPointer);
|
||||
|
||||
// Pop scripted callee (the original |this|).
|
||||
ValueOperand val = regs.takeAnyValue();
|
||||
masm.popValue(val);
|
||||
|
||||
// Decrement argc if argc > 0. If argc == 0, push |undefined| as |this|.
|
||||
Label zeroArgs, done;
|
||||
masm.branchTest32(Assembler::Zero, argcReg, argcReg, &zeroArgs);
|
||||
masm.sub32(Imm32(1), argcReg);
|
||||
masm.jump(&done);
|
||||
|
||||
masm.bind(&zeroArgs);
|
||||
|
||||
// Copy scripted callee (the original |this|).
|
||||
Address thisSlotFromStubFrame(BaselineFrameReg, STUB_FRAME_SIZE);
|
||||
masm.loadValue(thisSlotFromStubFrame, val);
|
||||
|
||||
// Align the stack.
|
||||
masm.alignJitStackBasedOnNArgs(0);
|
||||
|
||||
// Store the new |this|.
|
||||
masm.pushValue(UndefinedValue());
|
||||
|
||||
masm.bind(&done);
|
||||
|
||||
// Unbox scripted callee.
|
||||
|
@ -2332,6 +2332,7 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
||||
Label assert;
|
||||
maybeAssert = &assert;
|
||||
#endif
|
||||
assertStackAlignment(sizeof(Value), 0);
|
||||
branchTestPtr(Assembler::NonZero, nargs, Imm32(1), &odd);
|
||||
branchTestPtr(Assembler::NonZero, StackPointer, Imm32(JitStackAlignment - 1), maybeAssert);
|
||||
subPtr(Imm32(sizeof(Value)), StackPointer);
|
||||
@ -2344,3 +2345,37 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
||||
andPtr(Imm32(~(JitStackAlignment - 1)), StackPointer);
|
||||
bind(&end);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs)
|
||||
{
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment == 1)
|
||||
return;
|
||||
|
||||
// A JitFrameLayout is composed of the following:
|
||||
// [padding?] [argN] .. [arg1] [this] [[argc] [callee] [descr] [raddr]]
|
||||
//
|
||||
// We want to ensure that the |raddr| address is aligned.
|
||||
// Which implies that we want to ensure that |this| is aligned.
|
||||
static_assert(sizeof(JitFrameLayout) % JitStackAlignment == 0,
|
||||
"No need to consider the JitFrameLayout for aligning the stack");
|
||||
|
||||
// Which implies that |argN| is aligned if |nargs| is even, and offset by
|
||||
// |sizeof(Value)| if |nargs| is odd.
|
||||
MOZ_ASSERT(alignment == 2);
|
||||
|
||||
// Thus the |padding| is offset by |sizeof(Value)| if |nargs| is even, and
|
||||
// aligned if |nargs| is odd.
|
||||
|
||||
assertStackAlignment(sizeof(Value), 0);
|
||||
if (nargs % 2 == 0) {
|
||||
Label end;
|
||||
branchTestPtr(Assembler::NonZero, StackPointer, Imm32(JitStackAlignment - 1), &end);
|
||||
subPtr(Imm32(sizeof(Value)), StackPointer);
|
||||
bind(&end);
|
||||
assertStackAlignment(JitStackAlignment, sizeof(Value));
|
||||
} else {
|
||||
andPtr(Imm32(~(JitStackAlignment - 1)), StackPointer);
|
||||
}
|
||||
}
|
||||
|
@ -1256,6 +1256,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
// on the stack, such that the JitFrameLayout would be correctly aligned on
|
||||
// the JitStackAlignment.
|
||||
void alignJitStackBasedOnNArgs(Register nargs);
|
||||
void alignJitStackBasedOnNArgs(uint32_t nargs);
|
||||
|
||||
void assertStackAlignment(uint32_t alignment, int32_t offset = 0) {
|
||||
#ifdef DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user