mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fixed multitrees assert regression from bug 469044 (bug 474935, r=gal).
This commit is contained in:
parent
a4ec9c19ad
commit
d1ac280790
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user