mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[INFER] Fix liveness analysis for try block, bug 673341. r=bhackett
This commit is contained in:
parent
c46be499d6
commit
4ed56d317b
@ -863,6 +863,29 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
|
|||||||
if (loop && code->jumpTarget && offset != loop->entry && offset > loop->lastBlock)
|
if (loop && code->jumpTarget && offset != loop->entry && offset > loop->lastBlock)
|
||||||
loop->lastBlock = offset;
|
loop->lastBlock = offset;
|
||||||
|
|
||||||
|
if (code->exceptionEntry) {
|
||||||
|
unsigned tryOffset;
|
||||||
|
JSTryNote *tn = script->trynotes()->vector;
|
||||||
|
JSTryNote *tnlimit = tn + script->trynotes()->length;
|
||||||
|
for (; tn < tnlimit; tn++) {
|
||||||
|
unsigned startOffset = script->main - script->code + tn->start;
|
||||||
|
if (startOffset + tn->length == offset) {
|
||||||
|
tryOffset = startOffset - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JS_NOT_REACHED("Start of try block not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extend all live variables at exception entry to the start of
|
||||||
|
* the try block.
|
||||||
|
*/
|
||||||
|
for (unsigned i = 0; i < numSlots; i++) {
|
||||||
|
if (lifetimes[i].lifetime)
|
||||||
|
ensureVariable(lifetimes[i], tryOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case JSOP_GETARG:
|
case JSOP_GETARG:
|
||||||
case JSOP_CALLARG:
|
case JSOP_CALLARG:
|
||||||
@ -906,7 +929,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
|
|||||||
case JSOP_LOOKUPSWITCHX:
|
case JSOP_LOOKUPSWITCHX:
|
||||||
case JSOP_TABLESWITCH:
|
case JSOP_TABLESWITCH:
|
||||||
case JSOP_TABLESWITCHX:
|
case JSOP_TABLESWITCHX:
|
||||||
case JSOP_TRY:
|
|
||||||
/* Restore all saved variables. :FIXME: maybe do this precisely. */
|
/* Restore all saved variables. :FIXME: maybe do this precisely. */
|
||||||
for (unsigned i = 0; i < savedCount; i++) {
|
for (unsigned i = 0; i < savedCount; i++) {
|
||||||
LifetimeVariable &var = *saved[i];
|
LifetimeVariable &var = *saved[i];
|
||||||
@ -922,6 +944,17 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
|
|||||||
savedCount = 0;
|
savedCount = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case JSOP_TRY:
|
||||||
|
for (unsigned i = 0; i < numSlots; i++) {
|
||||||
|
LifetimeVariable &var = lifetimes[i];
|
||||||
|
if (var.ensured) {
|
||||||
|
JS_ASSERT(var.lifetime);
|
||||||
|
if (var.lifetime->start == offset)
|
||||||
|
var.ensured = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case JSOP_NEW:
|
case JSOP_NEW:
|
||||||
case JSOP_CALL:
|
case JSOP_CALL:
|
||||||
case JSOP_EVAL:
|
case JSOP_EVAL:
|
||||||
@ -1063,6 +1096,9 @@ ScriptAnalysis::addVariable(JSContext *cx, LifetimeVariable &var, unsigned offse
|
|||||||
LifetimeVariable **&saved, unsigned &savedCount)
|
LifetimeVariable **&saved, unsigned &savedCount)
|
||||||
{
|
{
|
||||||
if (var.lifetime) {
|
if (var.lifetime) {
|
||||||
|
if (var.ensured)
|
||||||
|
return;
|
||||||
|
|
||||||
JS_ASSERT(offset < var.lifetime->start);
|
JS_ASSERT(offset < var.lifetime->start);
|
||||||
var.lifetime->start = offset;
|
var.lifetime->start = offset;
|
||||||
} else {
|
} else {
|
||||||
@ -1102,6 +1138,10 @@ ScriptAnalysis::killVariable(JSContext *cx, LifetimeVariable &var, unsigned offs
|
|||||||
var.savedEnd = 0;
|
var.savedEnd = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (var.ensured)
|
||||||
|
return;
|
||||||
|
|
||||||
JS_ASSERT(offset < var.lifetime->start);
|
JS_ASSERT(offset < var.lifetime->start);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1124,6 +1164,16 @@ ScriptAnalysis::extendVariable(JSContext *cx, LifetimeVariable &var,
|
|||||||
unsigned start, unsigned end)
|
unsigned start, unsigned end)
|
||||||
{
|
{
|
||||||
JS_ASSERT(var.lifetime);
|
JS_ASSERT(var.lifetime);
|
||||||
|
if (var.ensured) {
|
||||||
|
/*
|
||||||
|
* If we are still ensured to be live, the try block must scope over
|
||||||
|
* the loop, in which case the variable is already guaranteed to be
|
||||||
|
* live for the entire loop.
|
||||||
|
*/
|
||||||
|
JS_ASSERT(var.lifetime->start < start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var.lifetime->start = start;
|
var.lifetime->start = start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1193,6 +1243,15 @@ ScriptAnalysis::extendVariable(JSContext *cx, LifetimeVariable &var,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ScriptAnalysis::ensureVariable(LifetimeVariable &var, unsigned until)
|
||||||
|
{
|
||||||
|
JS_ASSERT(var.lifetime);
|
||||||
|
JS_ASSERT(until < var.lifetime->start);
|
||||||
|
var.lifetime->start = until;
|
||||||
|
var.ensured = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ScriptAnalysis::clearAllocations()
|
ScriptAnalysis::clearAllocations()
|
||||||
{
|
{
|
||||||
|
@ -559,7 +559,10 @@ struct LifetimeVariable
|
|||||||
Lifetime *saved;
|
Lifetime *saved;
|
||||||
|
|
||||||
/* Jump preceding the basic block which killed this variable. */
|
/* Jump preceding the basic block which killed this variable. */
|
||||||
uint32 savedEnd;
|
uint32 savedEnd : 31;
|
||||||
|
|
||||||
|
/* If the variable needs to be kept alive until lifetime->start. */
|
||||||
|
bool ensured : 1;
|
||||||
|
|
||||||
/* Whether this variable is live at offset. */
|
/* Whether this variable is live at offset. */
|
||||||
Lifetime * live(uint32 offset) const {
|
Lifetime * live(uint32 offset) const {
|
||||||
@ -1168,6 +1171,7 @@ class ScriptAnalysis
|
|||||||
inline void killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
|
inline void killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
|
||||||
LifetimeVariable **&saved, unsigned &savedCount);
|
LifetimeVariable **&saved, unsigned &savedCount);
|
||||||
inline void extendVariable(JSContext *cx, LifetimeVariable &var, unsigned start, unsigned end);
|
inline void extendVariable(JSContext *cx, LifetimeVariable &var, unsigned start, unsigned end);
|
||||||
|
inline void ensureVariable(LifetimeVariable &var, unsigned until);
|
||||||
|
|
||||||
/* SSA helpers */
|
/* SSA helpers */
|
||||||
bool makePhi(JSContext *cx, uint32 slot, uint32 offset, SSAValue *pv);
|
bool makePhi(JSContext *cx, uint32 slot, uint32 offset, SSAValue *pv);
|
||||||
|
Loading…
Reference in New Issue
Block a user