Fix stack logic when removing bailout frames (
bug 677871, r=sstangl).
--- a/js/src/ion/x64/Trampoline-x64.cpp
+++ b/js/src/ion/x64/Trampoline-x64.cpp
@@ -207,25 +207,26 @@ GenerateBailoutThunk(MacroAssembler &mas
// Get the stack pointer into a register, pre-alignment.
masm.movq(rsp, r8);
// Call the bailout function.
masm.setupUnalignedABICall(1, rax);
masm.setABIArg(0, r8);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, Bailout));
- // Remove the common bailout frame.
+ // Stack is:
+ // [frame]
+ // snapshotOffset
+ // frameSize
+ // [bailoutFrame]
uint32 bailoutFrameSize = sizeof(void *) * Registers::Total +
- sizeof(double) * FloatRegisters::Total +
- sizeof(void *); // bailout id;
+ sizeof(double) * FloatRegisters::Total;
masm.addq(Imm32(bailoutFrameSize), rsp);
-
- // Remove the Ion frame.
masm.pop(rcx);
- masm.addq(rcx, rsp);
+ masm.lea(Operand(rsp, rcx, TimesOne, sizeof(void *)), rsp);
Label exception;
// Either interpret or handle an exception.
masm.testl(rax, rax);
masm.j(Assembler::NonZero, &exception);
// If we're about to interpret, we've removed the depth of the local ion
--- a/js/src/ion/x86/Trampoline-x86.cpp
+++ b/js/src/ion/x86/Trampoline-x86.cpp
@@ -215,30 +215,37 @@ GenerateBailoutThunk(MacroAssembler &mas
// Get the stack pointer into a register, pre-alignment.
masm.movl(esp, eax);
// Call the bailout function.
masm.setupUnalignedABICall(1, ecx);
masm.setABIArg(0, eax);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, Bailout));
- // Remove the common bailout frame.
- uint32 bailoutFrameSize = sizeof(void *) * Registers::Total +
+ // Common size of a bailout frame.
+ uint32 bailoutFrameSize = sizeof(void *) + // frameClass
sizeof(double) * FloatRegisters::Total +
- sizeof(void *) + // frameClass
- sizeof(void *); // bailout id
- masm.addl(Imm32(bailoutFrameSize), esp);
-
+ sizeof(void *) * Registers::Total;
// Remove the Ion frame.
if (frameClass == NO_FRAME_SIZE_CLASS_ID) {
+ // Stack is:
+ // ... frame ...
+ // snapshotOffset
+ // frameSize
+ // ... bailoutFrame ...
+ masm.addl(Imm32(bailoutFrameSize), esp);
masm.pop(ecx);
- masm.addl(ecx, esp);
+ masm.lea(Operand(esp, ecx, TimesOne, sizeof(void *)), esp);
} else {
+ // Stack is:
+ // ... frame ...
+ // bailoutId
+ // ... bailoutFrame ...
uint32 frameSize = FrameSizeClass::FromClass(frameClass).frameSize();
- masm.addl(Imm32(frameSize), esp);
+ masm.addl(Imm32(bailoutFrameSize + sizeof(void *) + frameSize), esp);
}
Label exception;
// Either interpret or handle an exception.
masm.testl(eax, eax);
masm.j(Assembler::NonZero, &exception);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug677871.js
@@ -0,0 +1,18 @@
+function f0(p0,p1,p2,p3,p4,p5,p6) {
+ var v0;
+ var v1;
+ if (v1) {
+ do {
+ v0 = v0 + p3;
+ v1 = p3 + p3 + v1 + v0;
+ if (v1) {
+ v0 = v0 + p1 + p4 + p2 + p0 + v1;
+ continue;
+ }
+ break;
+ } while (v0);
+ }
+ v0 + v1;
+}
+assertEq(f0(1,2,3,4,5,6), undefined);
+