[INFER] Don't use untracked entries when converting doubles back to integers, bug 652305.
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 24 Apr 2011 08:40:19 -0700
changeset 74978 591e2ce8966865a4494c65850d85b031dca55530
parent 74977 e6880baebb5d3a2099885d600910fe7f6e17eb2f
child 74979 8f0c5e12eba9a6e0e3b95487c730c60ec2024889
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs652305
milestone6.0a1
[INFER] Don't use untracked entries when converting doubles back to integers, bug 652305.
js/src/jit-test/tests/jaeger/bug652305.js
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
--- a/js/src/jit-test/tests/jaeger/bug652305.js
+++ b/js/src/jit-test/tests/jaeger/bug652305.js
@@ -1,20 +1,21 @@
 var sjcl = {
     cipher: {},
 };
+var global = 99;
 sjcl.cipher.aes = function (a) {
     var b, c, d, e, f = this.h[0][4],
     g = this.h[1];
     d = a.slice(0);
     this.a = [d, []];
     for (a = 8; a < 60; a++) {
         c = d[a - 1];
         if (a % 8 === 0) {
-            c = 99;
+            c = global;
             if (0 === 0) {
                 h = 2;
             }
         }
         d[a] = c;
     }
     assertEq(this.a[0][50], 99);
 };
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1322,22 +1322,33 @@ mjit::Compiler::generateMethod()
              * any entries into doubles for a branch at that previous op,
              * revert those entries into integers. Maintain an invariant that
              * for any variables inferred to be integers, the compiler
              * maintains them as integers slots, both for faster code inside
              * basic blocks and for fewer conversions needed when branching.
              * :XXX: this code is hacky and slow, but doesn't run that much.
              */
             for (unsigned i = 0; i < fixedDoubleEntries.length(); i++) {
-                FrameEntry *fe = fixedDoubleEntries[i];
+                FrameEntry *fe = frame.getOrTrack(fixedDoubleEntries[i]);
                 frame.ensureInteger(fe);
             }
         }
         fixedDoubleEntries.clear();
 
+#ifdef DEBUG
+        if (fallthrough && cx->typeInferenceEnabled()) {
+            for (uint32 slot = analyze::ArgSlot(0); slot < analyze::TotalSlots(script); slot++) {
+                if (a->varTypes[slot].type == JSVAL_TYPE_INT32) {
+                    FrameEntry *fe = frame.getOrTrack(slot);
+                    JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
+                }
+            }
+        }
+#endif
+
         if (opinfo->jumpTarget || trap) {
             if (fallthrough) {
                 fixDoubleTypes(PC);
                 fixedDoubleEntries.clear();
 
                 /*
                  * Watch for fallthrough to the head of a 'do while' loop.
                  * We don't know what register state we will be using at the head
@@ -7092,29 +7103,27 @@ mjit::Compiler::fixDoubleTypes(jsbytecod
                 restoreTypes.append(SlotType(newv->slot, vt));
                 vt.types = analysis->getValueTypes(newv->value);
                 vt.type = vt.types->getKnownTypeTag(cx);
             }
             newv++;
         }
     }
 
-    for (uint32 slot = analyze::ArgSlot(0);
-         slot < analyze::LocalSlot(script, script->nfixed);
-         slot++) {
+    for (uint32 slot = analyze::ArgSlot(0); slot < analyze::TotalSlots(script); slot++) {
         if (!fixDoubleSlot(slot))
             continue;
         if (a->varTypes[slot].type == JSVAL_TYPE_DOUBLE) {
             FrameEntry *fe = frame.getOrTrack(slot);
             if (!fe->isType(JSVAL_TYPE_DOUBLE)) {
                 /*
                  * Remember any slots we converted to double, so we can convert
                  * them back into ints at the start of the next iteration.
                  */
-                fixedDoubleEntries.append(fe);
+                fixedDoubleEntries.append(frame.indexOfFe(fe));
                 frame.ensureDouble(fe);
             }
         }
     }
 
     for (unsigned i = 0; i < restoreTypes.length(); i++) {
         const SlotType &rt = restoreTypes[i];
         a->varTypes[rt.slot] = rt.vt;
@@ -7136,19 +7145,17 @@ mjit::Compiler::restoreAnalysisTypes()
                 vt.types = analysis->getValueTypes(newv->value);
                 vt.type = vt.types->getKnownTypeTag(cx);
             }
             newv++;
         }
     }
 
     /* Restore known types of locals/args. */
-    for (uint32 slot = analyze::ArgSlot(0);
-         slot < analyze::LocalSlot(script, script->nfixed);
-         slot++) {
+    for (uint32 slot = analyze::ArgSlot(0); slot < analyze::TotalSlots(script); slot++) {
         JSValueType type = a->varTypes[slot].type;
         if (type != JSVAL_TYPE_UNKNOWN && (type != JSVAL_TYPE_DOUBLE || fixDoubleSlot(slot))) {
             FrameEntry *fe = frame.getOrTrack(slot);
             JS_ASSERT_IF(fe->isTypeKnown(), fe->isType(type));
             if (!fe->isTypeKnown())
                 frame.learnType(fe, type, false);
         }
     }
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -521,17 +521,17 @@ class Compiler : public BaseCompiler
     js::Vector<PICGenInfo, 16, CompilerAllocPolicy> pics;
     js::Vector<GetElementICInfo, 16, CompilerAllocPolicy> getElemICs;
     js::Vector<SetElementICInfo, 16, CompilerAllocPolicy> setElemICs;
 #endif
     js::Vector<CallPatchInfo, 64, CompilerAllocPolicy> callPatches;
     js::Vector<InternalCallSite, 64, CompilerAllocPolicy> callSites;
     js::Vector<InternalRejoinSite, 64, CompilerAllocPolicy> rejoinSites;
     js::Vector<DoublePatch, 16, CompilerAllocPolicy> doubleList;
-    js::Vector<FrameEntry*, 4, CompilerAllocPolicy> fixedDoubleEntries;
+    js::Vector<uint32, 4, CompilerAllocPolicy> fixedDoubleEntries;
     js::Vector<JumpTable, 16> jumpTables;
     js::Vector<uint32, 16> jumpTableOffsets;
     js::Vector<LoopEntry, 16> loopEntries;
     StubCompiler stubcc;
     Label invokeLabel;
     Label arityLabel;
 #ifdef JS_MONOIC
     Label argsCheckStub;