[INFER] Don't incorrectly mark compilation failure on loop bodies with large modsets, bug 656096.
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 10 May 2011 13:34:23 -0700
changeset 75021 71e561e48de407b07b2c41ed29460939bcea88be
parent 75020 5aadf6bc110b9b4d5a7690f24ed8e543354ee917
child 75022 fd1abc43d698ff67eae944a26a4c2d3098d3f6a0
push id1199
push userjorendorff@mozilla.com
push dateSat, 13 Aug 2011 18:32:33 +0000
treeherdermozilla-inbound@080fece621e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs656096
milestone6.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] Don't incorrectly mark compilation failure on loop bodies with large modsets, bug 656096.
js/src/jit-test/tests/jaeger/bug656096.js
js/src/methodjit/Compiler.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/LoopState.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug656096.js
@@ -0,0 +1,37 @@
+function aes(a) {
+    d = a.slice()
+    for (; a < 28; a++)
+    d[0] = d[0] ^ undefined
+}
+var sjcl = {};
+sjcl.bitArray = {
+    concat: function (a, b) {
+        return d ? a : [];
+    },
+    clamp: function (a, b) {
+        return a
+    }
+};
+function G(a, b, c, d, e, f) {
+    var g = [],
+        h = sjcl.bitArray,
+        f = [];
+    f = h.concat(f, c)
+    if (c) g = []
+    else c = h.concat([], [])
+    h.concat(g, d)
+    h.clamp(f, <x></x> )
+}
+function decrypt(a, b, c, d, e) {
+    G(a, 1, c, d, e, b)
+    var g = [],
+        h = sjcl.bitArray,
+        f = [];
+    h.concat(f, c)
+    if (c) g = []
+    else c = h.concat([], [])
+    h.concat(g, d)
+    h.concat([], c).concat.slice
+}
+aes(sjcl.bitArray.clamp([]));
+decrypt(1, 2, 3);
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -627,16 +627,18 @@ mjit::TryCompile(JSContext *cx, StackFra
          * Treat this the same way as a static overflow and wait for another
          * attempt to compile the script.
          */
         JITScriptStatus status = fp->script()->getJITStatus(fp->isConstructing());
         JS_ASSERT(status != JITScript_Invalid);
         return (status == JITScript_Valid) ? Compile_Okay : Compile_Retry;
     }
 
+    JS_ASSERT_IF(status == Compile_Error, cx->isExceptionPending());
+
     return status;
 }
 
 CompileStatus
 mjit::Compiler::generatePrologue()
 {
     invokeLabel = masm.label();
 
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -118,18 +118,17 @@ LoopState::init(jsbytecode *head, Jump e
             unsigned pframe = index;
             while (ssa->getFrame(pframe).parent != CrossScriptSSA::OUTER_FRAME)
                 pframe = ssa->getFrame(pframe).parent;
             uint32 offset = ssa->getFrame(pframe).parentpc - outerScript->code;
             JS_ASSERT(offset < outerScript->length);
             if (offset < lifetime->head || offset > lifetime->backedge)
                 continue;
         }
-        if (!analyzeLoopBody(index))
-            return false;
+        analyzeLoopBody(index);
     }
 
     if (testLHS != UNASSIGNED) {
         JaegerSpew(JSpew_Analysis, "loop test at %u: %s %s %s + %d\n", lifetime->head,
                    frame.entryName(testLHS),
                    testLessEqual ? "<=" : ">=",
                    (testRHS == UNASSIGNED) ? "" : frame.entryName(testRHS),
                    testConstant);
@@ -1540,17 +1539,17 @@ LoopState::definiteArrayAccess(const SSA
     /*
      * The index is determined from a variable's value at loop entry. We don't
      * carry values with ignored overflows around loop back edges, so will know
      * the index is a non-integer before such overflows are ignored.
      */
     return true;
 }
 
-bool
+void
 LoopState::analyzeLoopBody(unsigned frame)
 {
     JSScript *script = ssa->getFrame(frame).script;
     analyze::ScriptAnalysis *analysis = script->analysis(cx);
     JS_ASSERT(analysis && !analysis->failed() && analysis->ranInference());
 
     /*
      * The temporaries need to be positioned after all values in the deepest
@@ -1627,19 +1626,19 @@ LoopState::analyzeLoopBody(unsigned fram
             }
 
             objTypes->addFreeze(cx);
             for (unsigned i = 0; i < objTypes->getObjectCount(); i++) {
                 types::TypeObject *object = objTypes->getObject(i);
                 if (!object)
                     continue;
                 if (!addModifiedProperty(object, JSID_VOID))
-                    return false;
+                    return;
                 if (op == JSOP_SETHOLE && !addGrowArray(object))
-                    return false;
+                    return;
             }
 
             if (constrainedLoop && !definiteArrayAccess(objValue, elemValue))
                 constrainedLoop = false;
             break;
           }
 
           case JSOP_GETELEM: {
@@ -1762,18 +1761,16 @@ LoopState::analyzeLoopBody(unsigned fram
 
           default:
             constrainedLoop = false;
             break;
         }
 
         offset = successorOffset;
     }
-
-    return true;
 }
 
 bool
 LoopState::addGrowArray(types::TypeObject *object)
 {
     static const uint32 MAX_SIZE = 10;
     for (unsigned i = 0; i < growArrays.length(); i++) {
         if (growArrays[i] == object)
--- a/js/src/methodjit/LoopState.h
+++ b/js/src/methodjit/LoopState.h
@@ -336,17 +336,17 @@ class LoopState : public MacroAssemblerT
      * Whether this loop only performs integer and double arithmetic and dense
      * array accesses. Integer overflows in this loop which only flow to bitops
      * can be ignored.
      */
     bool constrainedLoop;
 
     void analyzeLoopTest();
     void analyzeLoopIncrements();
-    bool analyzeLoopBody(unsigned frame);
+    void analyzeLoopBody(unsigned frame);
 
     bool definiteArrayAccess(const analyze::SSAValue &obj, const analyze::SSAValue &index);
     bool getLoopTestAccess(const analyze::SSAValue &v, uint32 *pslot, int32 *pconstant);
 
     bool addGrowArray(types::TypeObject *object);
     bool addModifiedProperty(types::TypeObject *object, jsid id);
 
     bool hasGrowArray(types::TypeObject *object);