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.
|
// Enter stub frame.
|
||||||
enterStubFrame(masm, regs.getAny());
|
enterStubFrame(masm, regs.getAny());
|
||||||
|
|
||||||
|
// Align the stack such that the JitFrameLayout is aligned on
|
||||||
|
// JitStackAlignment.
|
||||||
|
masm.alignJitStackBasedOnNArgs(0);
|
||||||
|
|
||||||
// Push |this| for getter (target object).
|
// Push |this| for getter (target object).
|
||||||
{
|
{
|
||||||
ValueOperand val = regs.takeAnyValue();
|
ValueOperand val = regs.takeAnyValue();
|
||||||
@ -7372,6 +7376,10 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
||||||
masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
|
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.
|
// Getter is called with 0 arguments, just |obj| as thisv.
|
||||||
// Note that we use Push, not push, so that callJit will align the stack
|
// Note that we use Push, not push, so that callJit will align the stack
|
||||||
// properly on ARM.
|
// properly on ARM.
|
||||||
@ -8866,14 +8874,17 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
|
||||||
masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
|
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.
|
// 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
|
// Note that we use Push, not push, so that callJit will align the stack
|
||||||
// properly on ARM.
|
// properly on ARM.
|
||||||
|
|
||||||
// To Push R1, read it off of the stowed values on stack.
|
// To Push R1, read it off of the stowed values on stack.
|
||||||
// Stack: [ ..., R0, R1, ..STUBFRAME-HEADER.. ]
|
// Stack: [ ..., R0, R1, ..STUBFRAME-HEADER.., padding? ]
|
||||||
masm.movePtr(BaselineStackReg, scratch);
|
masm.PushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE));
|
||||||
masm.PushValue(Address(scratch, STUB_FRAME_SIZE));
|
|
||||||
masm.Push(R0);
|
masm.Push(R0);
|
||||||
EmitCreateStubFrameDescriptor(masm, scratch);
|
EmitCreateStubFrameDescriptor(masm, scratch);
|
||||||
masm.Push(Imm32(1)); // ActualArgc is 1
|
masm.Push(Imm32(1)); // ActualArgc is 1
|
||||||
@ -10835,25 +10846,34 @@ ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
if (canUseTailCallReg)
|
if (canUseTailCallReg)
|
||||||
regs.add(BaselineTailCallReg);
|
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
|
// Values are on the stack left-to-right. Calling convention wants them
|
||||||
// right-to-left so duplicate them on the stack in reverse order.
|
// right-to-left so duplicate them on the stack in reverse order.
|
||||||
pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
|
pushCallArguments(masm, regs, argcReg, /* isJitCall = */ true);
|
||||||
|
|
||||||
// Discard callee (function.call).
|
|
||||||
masm.addPtr(Imm32(sizeof(Value)), StackPointer);
|
|
||||||
|
|
||||||
// Pop scripted callee (the original |this|).
|
// Pop scripted callee (the original |this|).
|
||||||
ValueOperand val = regs.takeAnyValue();
|
ValueOperand val = regs.takeAnyValue();
|
||||||
masm.popValue(val);
|
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.jump(&done);
|
||||||
|
|
||||||
masm.bind(&zeroArgs);
|
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.pushValue(UndefinedValue());
|
||||||
|
|
||||||
masm.bind(&done);
|
masm.bind(&done);
|
||||||
|
|
||||||
// Unbox scripted callee.
|
// Unbox scripted callee.
|
||||||
|
@ -2332,6 +2332,7 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
|||||||
Label assert;
|
Label assert;
|
||||||
maybeAssert = &assert;
|
maybeAssert = &assert;
|
||||||
#endif
|
#endif
|
||||||
|
assertStackAlignment(sizeof(Value), 0);
|
||||||
branchTestPtr(Assembler::NonZero, nargs, Imm32(1), &odd);
|
branchTestPtr(Assembler::NonZero, nargs, Imm32(1), &odd);
|
||||||
branchTestPtr(Assembler::NonZero, StackPointer, Imm32(JitStackAlignment - 1), maybeAssert);
|
branchTestPtr(Assembler::NonZero, StackPointer, Imm32(JitStackAlignment - 1), maybeAssert);
|
||||||
subPtr(Imm32(sizeof(Value)), StackPointer);
|
subPtr(Imm32(sizeof(Value)), StackPointer);
|
||||||
@ -2344,3 +2345,37 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
|||||||
andPtr(Imm32(~(JitStackAlignment - 1)), StackPointer);
|
andPtr(Imm32(~(JitStackAlignment - 1)), StackPointer);
|
||||||
bind(&end);
|
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
|
// on the stack, such that the JitFrameLayout would be correctly aligned on
|
||||||
// the JitStackAlignment.
|
// the JitStackAlignment.
|
||||||
void alignJitStackBasedOnNArgs(Register nargs);
|
void alignJitStackBasedOnNArgs(Register nargs);
|
||||||
|
void alignJitStackBasedOnNArgs(uint32_t nargs);
|
||||||
|
|
||||||
void assertStackAlignment(uint32_t alignment, int32_t offset = 0) {
|
void assertStackAlignment(uint32_t alignment, int32_t offset = 0) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
Loading…
Reference in New Issue
Block a user