[INFER] Clear all frame ncode values on GC to avoid confusing the recompiler, bug 673812.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 25 Jul 2011 13:57:29 -0700
changeset 77382 4d1506b097db00d81d4b06c594f86220195b3cf9
parent 77380 7e5a5d2e28f86a93c36b8473591411c212be870f
child 77383 681d2903edb79aa46050872ee0962aa6527c178e
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs673812
milestone8.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
[INFER] Clear all frame ncode values on GC to avoid confusing the recompiler, bug 673812.
js/src/jit-test/tests/jaeger/recompile/bug673812.js
js/src/methodjit/Retcon.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/recompile/bug673812.js
@@ -0,0 +1,18 @@
+gczeal(2);
+try {
+    DoWhile_3();
+} catch (e) {}
+function f() {
+    test();
+    yield 170;
+}
+function test() {
+    function foopy() {
+        try {
+            for (var i in f());
+        } catch (e) {}
+    }
+    foopy();
+    gc();
+}
+test();
--- a/js/src/methodjit/Retcon.cpp
+++ b/js/src/methodjit/Retcon.cpp
@@ -378,24 +378,28 @@ ClearAllFrames(JSCompartment *compartmen
         return;
 
     ExpandInlineFrames(compartment, true);
 
     for (VMFrame *f = compartment->jaegerCompartment()->activeFrame();
          f != NULL;
          f = f->previous) {
 
-        // We don't need to scan the frames internal to this VMFrame, or update
-        // their ncode values. Patching the VMFrame's return address will cause
-        // all its frames to finish in the interpreter, unless the interpreter
-        // enters one of the intermediate frames at a loop boundary. In such a
-        // case, the interpreter will enter through EnterMethodJIT, which
-        // overwrites the entry frame's ncode value.
+        Recompiler::patchFrame(compartment, f, f->fp()->script());
 
-        Recompiler::patchFrame(compartment, f, f->fp()->script());
+        // Clear ncode values from all frames associated with the VMFrame.
+        // Patching the VMFrame's return address will cause all its frames to
+        // finish in the interpreter, unless the interpreter enters one of the
+        // intermediate frames at a loop boundary (where EnterMethodJIT will
+        // overwrite ncode). However, leaving stale values for ncode in stack
+        // frames can confuse the recompiler, which may see the VMFrame before
+        // it has resumed execution.
+
+        for (StackFrame *fp = f->fp(); fp != f->entryfp; fp = fp->prev())
+            fp->setNativeReturnAddress(NULL);
     }
 }
 
 Recompiler::Recompiler(JSContext *cx, JSScript *script)
   : cx(cx), script(script)
 {    
 }