Fixed multitrees assert regression from bug 469044 (bug 474935, r=gal).

This commit is contained in:
David Anderson 2009-01-23 22:24:58 -05:00
parent a4ec9c19ad
commit d1ac280790

View File

@ -3201,6 +3201,16 @@ js_RecordTree(JSContext* cx, JSTraceMonitor* tm, Fragment* f, Fragment* outer)
return true;
}
static inline bool isSlotUndemotable(JSContext* cx, TreeInfo* ti, unsigned slot)
{
if (slot < ti->stackSlots)
return oracle.isStackSlotUndemotable(cx, slot);
JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx);
uint16* gslots = tm->globalSlots->data();
return oracle.isGlobalSlotUndemotable(cx, gslots[slot - ti->stackSlots]);
}
JS_REQUIRES_STACK static bool
js_AttemptToStabilizeTree(JSContext* cx, VMSideExit* exit, Fragment* outer)
{
@ -3224,8 +3234,11 @@ js_AttemptToStabilizeTree(JSContext* cx, VMSideExit* exit, Fragment* outer)
/* If this exit does not have enough globals, there might exist a peer with more globals that we
* can join to.
*/
TreeInfo* ti;
uint8* m2;
Fragment* f;
TreeInfo* ti;
bool matched;
bool undemote;
bool bound = false;
unsigned int checkSlots;
for (f = from->first; f != NULL; f = f->peer) {
@ -3235,7 +3248,33 @@ js_AttemptToStabilizeTree(JSContext* cx, VMSideExit* exit, Fragment* outer)
JS_ASSERT(exit->numStackSlots == ti->stackSlots);
/* Check the minimum number of slots that need to be compared. */
checkSlots = JS_MIN(exit->numStackSlots + exit->numGlobalSlots, ti->typeMap.length());
if (memcmp(getFullTypeMap(exit), ti->typeMap.data(), checkSlots) == 0) {
m = getFullTypeMap(exit);
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.
*/
matched = true;
undemote = false;
for (uint32 i = 0; i < checkSlots; i++) {
/* If the types are equal we're okay. */
if (m[i] == m2[i])
continue;
matched = false;
/* If there's an I->D that cannot be resolved, flag it.
* Otherwise, break and go to the next peer.
*/
if (m[i] == JSVAL_INT && m2[i] == JSVAL_DOUBLE && isSlotUndemotable(cx, ti, i)) {
undemote = true;
} else {
undemote = false;
break;
}
}
if (matched) {
/* Capture missing globals on both trees and link the fragments together. */
if (from != f) {
ti->dependentTrees.addUnique(from);
@ -3259,6 +3298,11 @@ js_AttemptToStabilizeTree(JSContext* cx, VMSideExit* exit, Fragment* outer)
JS_ASSERT(bound);
debug_only_v(js_DumpPeerStability(tm->fragmento, f->ip);)
break;
} else if (undemote) {
/* The original tree is unconnectable, so trash it. */
js_TrashTree(cx, f);
/* We shouldn't attempt to record now, since we'll hit a duplicate. */
return false;
}
}
if (bound)