[INFER] Don't try to fixup doubles on adjusted frame in call path, bug 649769.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 13 Apr 2011 14:45:25 -0700
changeset 74940 affaa35f4a14cc23844d2d062099c9daa11f6364
parent 74939 a3eeee8f7803279669dbba47f6c5e57ea9995942
child 74941 15c08e8910110be8341a8cf6586e5223df8d93cb
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs649769
milestone6.0a1
[INFER] Don't try to fixup doubles on adjusted frame in call path, bug 649769.
js/src/jit-test/tests/jaeger/recompile/bug649769.js
js/src/methodjit/Compiler.cpp
js/src/methodjit/InvokeHelpers.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/recompile/bug649769.js
@@ -0,0 +1,16 @@
+
+function g(x) {
+    if (!x) {
+        throw 1;
+    }
+}
+
+function f(a, b, c, d) {
+    var x = [].push(3);
+    g(true);
+    assertEq(x, 1);
+}
+f(1.2, 2, 3, 4);
+gc();
+f(1, 2, 3, 4);
+
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -2057,16 +2057,17 @@ mjit::Compiler::generateMethod()
 
                 autoRejoinCall.oolRejoin(stubcc.masm.label());
                 Jump fallthrough = stubcc.masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
                                                              Registers::ReturnReg);
                 if (frameSize.isStatic())
                     stubcc.masm.move(Imm32(frameSize.staticArgc()), JSParamReg_Argc);
                 else
                     stubcc.masm.load32(FrameAddress(offsetof(VMFrame, u.call.dynamicArgc)), JSParamReg_Argc);
+                stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.sp)), JSFrameReg);
 
                 CallPatchInfo callPatch;
                 callPatch.hasSlowNcode = true;
                 callPatch.slowNcodePatch =
                     stubcc.masm.storePtrWithPatch(ImmPtr(NULL),
                                                   Address(JSFrameReg, JSStackFrame::offsetOfncode()));
                 stubcc.masm.jump(Registers::ReturnReg);
 
@@ -3286,18 +3287,17 @@ mjit::Compiler::emitUncachedCall(uint32 
 
     frame.syncAndKill(Uses(argc + 2));
     prepareStubCall(Uses(argc + 2));
     masm.move(Imm32(argc), Registers::ArgReg1);
     INLINE_STUBCALL(stub);
 
     Jump notCompiled = masm.branchTestPtr(Assembler::Zero, r0, r0);
 
-    if (!cx->typeInferenceEnabled())
-        masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
+    masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.sp)), JSFrameReg);
 
     callPatch.hasFastNcode = true;
     callPatch.fastNcodePatch =
         masm.storePtrWithPatch(ImmPtr(NULL),
                                Address(JSFrameReg, JSStackFrame::offsetOfncode()));
 
     masm.jump(r0);
     callPatch.joinPoint = masm.label();
@@ -3674,18 +3674,17 @@ mjit::Compiler::inlineCallHelper(uint32 
          * function pointer to jump to.
          */
         rejoin1 = stubcc.masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
                                             Registers::ReturnReg);
         if (callIC.frameSize.isStatic())
             stubcc.masm.move(Imm32(callIC.frameSize.staticArgc()), JSParamReg_Argc);
         else
             stubcc.masm.load32(FrameAddress(offsetof(VMFrame, u.call.dynamicArgc)), JSParamReg_Argc);
-        if (!cx->typeInferenceEnabled())
-            stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
+        stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.sp)), JSFrameReg);
         callPatch.hasSlowNcode = true;
         callPatch.slowNcodePatch =
             stubcc.masm.storePtrWithPatch(ImmPtr(NULL),
                                           Address(JSFrameReg, JSStackFrame::offsetOfncode()));
         stubcc.masm.jump(Registers::ReturnReg);
 
 
 
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -423,16 +423,24 @@ UncachedInlineCall(VMFrame &f, uint32 fl
 
     /*
      * If newscript was successfully compiled, run it. Skip for calls which
      * will be constructing a new type object for 'this'.
      */
     if (!newType) {
         if (JITScript *jit = newscript->getJIT(newfp->isConstructing())) {
             *pret = jit->invokeEntry;
+
+            /*
+             * Keep the old fp around and let the JIT code repush it. If we are
+             * rejoining into a recompiled frame then the code patching up
+             * doubles needs to see the calling script's frame.
+             */
+            f.regs.sp = (Value *) f.regs.fp;
+            f.regs.fp = f.regs.fp->prev();
             return true;
         }
     }
 
     /* Otherwise, run newscript in the interpreter. */
     bool ok = !!Interpret(cx, cx->fp());
     InlineReturn(f);