mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 723773 - Liveness analysis makes mistakes when analyzing try/catch (r=bhackett)
This commit is contained in:
parent
2817419f26
commit
48692f96aa
@ -940,12 +940,15 @@ ScriptAnalysis::killVariable(JSContext *cx, LifetimeVariable &var, unsigned offs
|
|||||||
/*
|
/*
|
||||||
* The variable is live even before the write, due to an enclosing try
|
* The variable is live even before the write, due to an enclosing try
|
||||||
* block. We need to split the lifetime to indicate there was a write.
|
* block. We need to split the lifetime to indicate there was a write.
|
||||||
|
* We set the new interval's savedEnd to 0, since it will always be
|
||||||
|
* adjacent to the old interval, so it never needs to be extended.
|
||||||
*/
|
*/
|
||||||
var.lifetime = cx->typeLifoAlloc().new_<Lifetime>(start, offset, var.lifetime);
|
var.lifetime = cx->typeLifoAlloc().new_<Lifetime>(start, 0, var.lifetime);
|
||||||
if (!var.lifetime) {
|
if (!var.lifetime) {
|
||||||
setOOM(cx);
|
setOOM(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var.lifetime->end = offset;
|
||||||
} else {
|
} else {
|
||||||
var.saved = var.lifetime;
|
var.saved = var.lifetime;
|
||||||
var.savedEnd = 0;
|
var.savedEnd = 0;
|
||||||
@ -973,25 +976,43 @@ ScriptAnalysis::extendVariable(JSContext *cx, LifetimeVariable &var,
|
|||||||
var.lifetime->start = start;
|
var.lifetime->start = start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When walking backwards through loop bodies, we don't know which vars
|
* Consider this code:
|
||||||
* are live at the loop's backedge. We save the endpoints for lifetime
|
|
||||||
* segments which we *would* use if the variables were live at the backedge
|
|
||||||
* and extend the variable with new lifetimes if we find the variable is
|
|
||||||
* indeed live at the head of the loop.
|
|
||||||
*
|
*
|
||||||
* while (...) {
|
* while (...) { (#1)
|
||||||
* if (x #1) { ... }
|
* use x; (#2)
|
||||||
* ...
|
* ...
|
||||||
* if (... #2) { x = 0; #3}
|
* x = ...; (#3)
|
||||||
* }
|
* ...
|
||||||
|
* } (#4)
|
||||||
*
|
*
|
||||||
* If x is not live after the loop, we treat it as dead in the walk and
|
* Just before analyzing the while statement, there would be a live range
|
||||||
* make a point lifetime for the write at #3. At the beginning of that
|
* from #1..#2 and a "point range" at #3. The job of extendVariable is to
|
||||||
* basic block (#2), we save the loop endpoint; if we knew x was live in
|
* create a new live range from #3..#4.
|
||||||
* the next iteration then a new lifetime would be made here. At #1 we
|
*
|
||||||
* mark x live again, make a segment between the head of the loop and #1,
|
* However, more extensions may be required if the definition of x is
|
||||||
* and then extend x with loop tail lifetimes from #1 to #2, and from #3
|
* conditional. Consider the following.
|
||||||
* to the back edge.
|
*
|
||||||
|
* while (...) { (#1)
|
||||||
|
* use x; (#2)
|
||||||
|
* ...
|
||||||
|
* if (...) (#5)
|
||||||
|
* x = ...; (#3)
|
||||||
|
* ...
|
||||||
|
* } (#4)
|
||||||
|
*
|
||||||
|
* Assume that x is not used after the loop. Then, before extendVariable is
|
||||||
|
* run, the live ranges would be the same as before (#1..#2 and #3..#3). We
|
||||||
|
* still need to create a range from #3..#4. But, since the assignment at #3
|
||||||
|
* may never run, we also need to create a range from #2..#3. This is done
|
||||||
|
* as follows.
|
||||||
|
*
|
||||||
|
* Each time we create a Lifetime, we store the start of the most recently
|
||||||
|
* seen sequence of conditional code in the Lifetime's savedEnd field. So,
|
||||||
|
* when creating the Lifetime at #2, we set the Lifetime's savedEnd to
|
||||||
|
* #5. (The start of the most recent conditional is cached in each
|
||||||
|
* variable's savedEnd field.) Consequently, extendVariable is able to
|
||||||
|
* create a new interval from #2..#5 using the savedEnd field of the
|
||||||
|
* existing #1..#2 interval.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Lifetime *segment = var.lifetime;
|
Lifetime *segment = var.lifetime;
|
||||||
|
Loading…
Reference in New Issue
Block a user