Skip next OSR in case forbidOSR flag is GC-ed. (Bug 751383, r=dvander)
authorNicolas Pierron <nicolas.b.pierron@mozilla.com>
Thu, 03 May 2012 22:55:29 -0700
changeset 106194 89dc67e650160839e2f83c1bc732992f77ddd8e7
parent 106193 c660397f6ab25e596d6fd1a2ce3eb2ca1b52626f
child 106195 68777651999a5c9c31a9d653717532d37c1563bb
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs751383
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Skip next OSR in case forbidOSR flag is GC-ed. (Bug 751383, r=dvander)
js/src/ion/Bailouts.cpp
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -468,16 +468,28 @@ ion::RecompileForInlining()
 
 JSBool
 ion::ThunkToInterpreter(Value *vp)
 {
     JSContext *cx = GetIonContext()->cx;
     IonActivation *activation = cx->runtime->ionActivation;
     BailoutClosure *br = activation->takeBailout();
 
+    // By default we set the forbidOsr flag on the ion script, but if a GC
+    // happens just after we re-enter the interpreter, the ion script get
+    // invalidated and we do not see the forbidOsr flag.  This may cause a loop
+    // which apear with eager compilation and gc zeal enabled.  This code is a
+    // workaround to avoid recompiling with OSR just after a bailout followed by
+    // a GC. (see Bug 746691 & Bug 751383)
+    jsbytecode *pc = cx->regs().pc;
+    while (JSOp(*pc) == JSOP_GOTO)
+        pc += GET_JUMP_OFFSET(pc);
+    if (JSOp(*pc) == JSOP_LOOPENTRY)
+        cx->regs().pc = GetNextPc(pc);
+
     bool ok = Interpret(cx, br->entryfp(), JSINTERP_BAILOUT);
 
     if (ok)
         *vp = br->entryfp()->returnValue();
 
     // The BailoutFrameGuard's destructor will ensure that the frame is
     // removed.
     cx->delete_(br);