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 25233 f181184427b9
parent 25232 8ef4084ee700
child 25234 cceff72682c3
push id1426
push userrsayre@mozilla.com
push date2009-05-15 18:23 +0000
reviewersgal
bugs489682
milestone1.9.1b5pre
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
@@ -3631,27 +3631,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.
          */