mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 736299: Prevent the frame pointer from being allocated when profiling is enabled. r=nbp
This commit is contained in:
parent
c74e64e4b2
commit
7e5f28dc59
@ -435,6 +435,8 @@ void
|
||||
MacroAssembler::performOsr()
|
||||
{
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::All();
|
||||
if (FramePointer != InvalidReg && sps && sps->enabled())
|
||||
regs.take(FramePointer);
|
||||
|
||||
// This register must be fixed as it's used in the Osr prologue.
|
||||
regs.take(OsrFrameReg);
|
||||
|
@ -523,7 +523,7 @@ LinearScanAllocator::buildLivenessInfo()
|
||||
for (LInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) {
|
||||
// Calls may clobber registers, so force a spill and reload around the callsite.
|
||||
if (ins->isCall()) {
|
||||
for (AnyRegisterIterator iter(RegisterSet::All()); iter.more(); iter++) {
|
||||
for (AnyRegisterIterator iter(allRegisters); iter.more(); iter++) {
|
||||
if (!addFixedRangeAtHead(*iter, inputOf(*ins), outputOf(*ins)))
|
||||
return false;
|
||||
}
|
||||
@ -1611,7 +1611,7 @@ LinearScanAllocator::findBestFreeRegister(CodePosition *freeUntil)
|
||||
// Compute free-until positions for all registers
|
||||
CodePosition freeUntilPos[AnyRegister::Total];
|
||||
bool needFloat = current->reg()->isDouble();
|
||||
for (AnyRegisterIterator regs(RegisterSet::All()); regs.more(); regs++) {
|
||||
for (AnyRegisterIterator regs(allRegisters); regs.more(); regs++) {
|
||||
AnyRegister reg = *regs;
|
||||
if (reg.isFloat() == needFloat)
|
||||
freeUntilPos[reg.code()] = CodePosition::MAX;
|
||||
@ -1704,7 +1704,7 @@ LinearScanAllocator::findBestBlockedRegister(CodePosition *nextUsed)
|
||||
// Compute next-used positions for all registers
|
||||
CodePosition nextUsePos[AnyRegister::Total];
|
||||
bool needFloat = current->reg()->isDouble();
|
||||
for (AnyRegisterIterator regs(RegisterSet::All()); regs.more(); regs++) {
|
||||
for (AnyRegisterIterator regs(allRegisters); regs.more(); regs++) {
|
||||
AnyRegister reg = *regs;
|
||||
if (reg.isFloat() == needFloat)
|
||||
nextUsePos[reg.code()] = CodePosition::MAX;
|
||||
|
@ -611,6 +611,9 @@ class LinearScanAllocator
|
||||
SlotList finishedSlots_;
|
||||
SlotList finishedDoubleSlots_;
|
||||
|
||||
// Pool of all registers that should be considered allocateable
|
||||
RegisterSet allRegisters;
|
||||
|
||||
// Run-time state
|
||||
UnhandledQueue unhandled;
|
||||
InlineList<LiveInterval> active;
|
||||
@ -684,8 +687,12 @@ class LinearScanAllocator
|
||||
public:
|
||||
LinearScanAllocator(LIRGenerator *lir, LIRGraph &graph)
|
||||
: lir(lir),
|
||||
graph(graph)
|
||||
{ }
|
||||
graph(graph),
|
||||
allRegisters(RegisterSet::All())
|
||||
{
|
||||
if (FramePointer != InvalidReg && lir->mir()->instrumentedProfiling())
|
||||
allRegisters.take(AnyRegister(FramePointer));
|
||||
}
|
||||
|
||||
bool go();
|
||||
};
|
||||
|
@ -62,6 +62,7 @@ static const FloatRegister InvalidFloatReg = { FloatRegisters::invalid_freg };
|
||||
static const Register JSReturnReg_Type = r3;
|
||||
static const Register JSReturnReg_Data = r2;
|
||||
static const Register StackPointer = sp;
|
||||
static const Register FramePointer = InvalidReg;
|
||||
static const Register ReturnReg = r0;
|
||||
static const FloatRegister ReturnFloatReg = { FloatRegisters::d1 };
|
||||
static const FloatRegister ScratchFloatReg = { FloatRegisters::d0 };
|
||||
|
@ -63,6 +63,7 @@ static const Register InvalidReg = { JSC::X86Registers::invalid_reg };
|
||||
static const FloatRegister InvalidFloatReg = { JSC::X86Registers::invalid_xmm };
|
||||
|
||||
static const Register StackPointer = rsp;
|
||||
static const Register FramePointer = rbp;
|
||||
static const Register JSReturnReg = rcx;
|
||||
// Avoid, except for assertions.
|
||||
static const Register JSReturnReg_Type = JSReturnReg;
|
||||
|
@ -209,6 +209,8 @@ IonCompartment::generateInvalidator(JSContext *cx)
|
||||
IonCode *
|
||||
IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
{
|
||||
// Do not erase the frame pointer in this function.
|
||||
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
// ArgumentsRectifierReg contains the |nargs| pushed onto the current frame.
|
||||
@ -225,7 +227,7 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
|
||||
masm.moveValue(UndefinedValue(), r10);
|
||||
|
||||
masm.movq(rsp, rbp); // Save %rsp.
|
||||
masm.movq(rsp, r9); // Save %rsp.
|
||||
|
||||
// Push undefined.
|
||||
{
|
||||
@ -240,7 +242,7 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
}
|
||||
|
||||
// Get the topmost argument.
|
||||
BaseIndex b = BaseIndex(rbp, r8, TimesEight, sizeof(IonRectifierFrameLayout));
|
||||
BaseIndex b = BaseIndex(r9, r8, TimesEight, sizeof(IonRectifierFrameLayout));
|
||||
masm.lea(Operand(b), rcx);
|
||||
|
||||
// Push arguments, |nargs| + 1 times (to include |this|).
|
||||
@ -261,13 +263,13 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
}
|
||||
|
||||
// Construct descriptor.
|
||||
masm.subq(rsp, rbp);
|
||||
masm.makeFrameDescriptor(rbp, IonFrame_Rectifier);
|
||||
masm.subq(rsp, r9);
|
||||
masm.makeFrameDescriptor(r9, IonFrame_Rectifier);
|
||||
|
||||
// Construct IonJSFrameLayout.
|
||||
masm.push(rdx); // numActualArgs
|
||||
masm.push(rax); // calleeToken
|
||||
masm.push(rbp); // descriptor
|
||||
masm.push(r9); // descriptor
|
||||
|
||||
// Call the target function.
|
||||
// Note that this code assumes the function is JITted.
|
||||
@ -278,11 +280,11 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
masm.call(rax);
|
||||
|
||||
// Remove the rectifier frame.
|
||||
masm.pop(rbp); // rbp <- descriptor with FrameType.
|
||||
masm.shrq(Imm32(FRAMESIZE_SHIFT), rbp);
|
||||
masm.pop(r9); // r9 <- descriptor with FrameType.
|
||||
masm.shrq(Imm32(FRAMESIZE_SHIFT), r9);
|
||||
masm.pop(r11); // Discard calleeToken.
|
||||
masm.pop(r11); // Discard numActualArgs.
|
||||
masm.addq(rbp, rsp); // Discard pushed arguments.
|
||||
masm.addq(r9, rsp); // Discard pushed arguments.
|
||||
|
||||
masm.ret();
|
||||
|
||||
|
@ -40,6 +40,7 @@ static const FloatRegister InvalidFloatReg = { JSC::X86Registers::invalid_xmm };
|
||||
static const Register JSReturnReg_Type = ecx;
|
||||
static const Register JSReturnReg_Data = edx;
|
||||
static const Register StackPointer = esp;
|
||||
static const Register FramePointer = ebp;
|
||||
static const Register ReturnReg = eax;
|
||||
static const FloatRegister ReturnFloatReg = xmm0;
|
||||
static const FloatRegister ScratchFloatReg = xmm7;
|
||||
|
@ -227,7 +227,8 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
|
||||
masm.moveValue(UndefinedValue(), ebx, edi);
|
||||
|
||||
masm.movl(esp, ebp); // Save %esp.
|
||||
masm.push(FramePointer);
|
||||
masm.movl(esp, FramePointer); // Save %esp.
|
||||
|
||||
// Push undefined.
|
||||
{
|
||||
@ -242,8 +243,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
masm.j(Assembler::NonZero, &undefLoopTop);
|
||||
}
|
||||
|
||||
// Get the topmost argument.
|
||||
BaseIndex b = BaseIndex(ebp, esi, TimesEight, sizeof(IonRectifierFrameLayout));
|
||||
// Get the topmost argument. We did a push of %ebp earlier, so be sure to
|
||||
// account for this in the offset
|
||||
BaseIndex b = BaseIndex(FramePointer, esi, TimesEight,
|
||||
sizeof(IonRectifierFrameLayout) + sizeof(void*));
|
||||
masm.lea(Operand(b), ecx);
|
||||
|
||||
// Push arguments, |nargs| + 1 times (to include |this|).
|
||||
@ -264,14 +267,15 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
masm.j(Assembler::NonZero, ©LoopTop);
|
||||
}
|
||||
|
||||
// Construct descriptor.
|
||||
masm.subl(esp, ebp);
|
||||
masm.makeFrameDescriptor(ebp, IonFrame_Rectifier);
|
||||
// Construct descriptor, accounting for pushed frame pointer above
|
||||
masm.lea(Operand(FramePointer, sizeof(void*)), ebx);
|
||||
masm.subl(esp, ebx);
|
||||
masm.makeFrameDescriptor(ebx, IonFrame_Rectifier);
|
||||
|
||||
// Construct IonJSFrameLayout.
|
||||
masm.push(edx); // number of actual arguments
|
||||
masm.push(eax); // calleeToken
|
||||
masm.push(ebp); // descriptor
|
||||
masm.push(ebx); // descriptor
|
||||
|
||||
// Call the target function.
|
||||
// Note that this assumes the function is JITted.
|
||||
@ -282,12 +286,16 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
|
||||
masm.call(eax);
|
||||
|
||||
// Remove the rectifier frame.
|
||||
masm.pop(ebp); // ebp <- descriptor with FrameType.
|
||||
masm.shrl(Imm32(FRAMESIZE_SHIFT), ebp); // ebp <- descriptor.
|
||||
masm.pop(ebx); // ebx <- descriptor with FrameType.
|
||||
masm.shrl(Imm32(FRAMESIZE_SHIFT), ebx); // ebx <- descriptor.
|
||||
masm.pop(edi); // Discard calleeToken.
|
||||
masm.pop(edi); // Discard number of actual arguments.
|
||||
masm.addl(ebp, esp); // Discard pushed arguments.
|
||||
|
||||
// Discard pushed arguments, but not the pushed frame pointer.
|
||||
BaseIndex unwind = BaseIndex(esp, ebx, TimesOne, -sizeof(void*));
|
||||
masm.lea(Operand(unwind), esp);
|
||||
|
||||
masm.pop(FramePointer);
|
||||
masm.ret();
|
||||
|
||||
Linker linker(masm);
|
||||
|
Loading…
Reference in New Issue
Block a user