Partial typemap in loop exit can lead to maltyped nested trees (489682, r=gal).
authordanderson@mozilla.com
Thu, 07 May 2009 12:16:12 -0700
changeset 28097 9d7ca9e8c8a5
parent 28096 0fb93c90d996
child 28099 e40b313aca1f
push id6892
push userrsayre@mozilla.com
push date2009-05-08 00:23 +0000
treeherdermozilla-central@bed245918256 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs489682
milestone1.9.2a1pre
Partial typemap in loop exit can lead to maltyped nested trees (489682, r=gal).
js/src/jstracer.cpp
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -3685,27 +3685,35 @@ js_AttemptToStabilizeTree(JSContext* cx,
     }
     m = getGlobalTypeMap(exit);
     for (unsigned i = 0; i < exit->numGlobalSlots; i++) {
         if (m[i] == JSVAL_DOUBLE)
             oracle.markGlobalSlotUndemotable(cx, from_ti->globalSlots->data()[i]);
     }
 
     /* If this exit does not have enough globals, there might exist a peer with more globals that we
-     * can join to.
+     * can join to, but only if the parent's globals match.
      */
+    m = getFullTypeMap(exit);
+    if (exit->numGlobalSlots < from_ti->nGlobalTypes()) {
+        uint32 partial = exit->numStackSlots + exit->numGlobalSlots;
+        m = (uint8*)alloca(from_ti->typeMap.length());
+        memcpy(m, getFullTypeMap(exit), partial);
+        memcpy(m + partial, from_ti->globalTypeMap() + exit->numGlobalSlots,
+               from_ti->nGlobalTypes() - exit->numGlobalSlots);
+    }
+
     bool bound = false;
     for (Fragment* f = from->first; f != NULL; f = f->peer) {
         if (!f->code())
             continue;
         TreeInfo* ti = (TreeInfo*)f->vmprivate;
         JS_ASSERT(exit->numStackSlots == ti->nStackTypes);
         /* Check the minimum number of slots that need to be compared. */
-        unsigned checkSlots = JS_MIN(exit->numStackSlots + exit->numGlobalSlots, ti->typeMap.length());
-        m = getFullTypeMap(exit);
+        unsigned checkSlots = JS_MIN(from_ti->typeMap.length(), ti->typeMap.length());
         uint8* m2 = ti->typeMap.data();
         /* Analyze the exit typemap against the peer typemap.
          * Two conditions are important:
          * 1) Typemaps are identical: these peers can be attached.
          * 2) Typemaps do not match, but only contain I->D mismatches.
          *    In this case, the original tree must be trashed because it
          *    will never connect to any peer.
          */