[INFER] Don't fold CALLPROP pushed value in SSA analysis, force out entries for popped values when returning from inlined calls, bug 653962.

This commit is contained in:
Brian Hackett 2011-05-10 13:21:44 -07:00
parent 4995d87bb4
commit efa5cac9d0
2 changed files with 27 additions and 7 deletions

View File

@ -1442,7 +1442,6 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
case JSOP_FORNAME:
case JSOP_FORGNAME:
case JSOP_CALLPROP:
stack[stackDepth - 1] = code->poppedValues[0];
break;
@ -1826,6 +1825,21 @@ CrossScriptSSA::foldValue(const CrossSSAValue &cv)
break;
}
case JSOP_CALLPROP: {
/*
* The second value pushed by CALLPROP is the same as its popped
* value. We don't do this folding during the SSA analysis itself
* as we still need to distinguish the two values during type
* inference --- any popped null or undefined value will throw an
* exception, and not actually end up in the pushed set.
*/
if (v.pushedIndex() == 1) {
ScriptAnalysis *analysis = frame.script->analysis(cx);
return foldValue(CrossSSAValue(cv.frame, analysis->poppedValue(pc, 0)));
}
break;
}
default:;
}
}

View File

@ -657,19 +657,25 @@ FrameState::syncForAllocation(RegisterAllocation *alloc, bool inlineReturn, Uses
* call returns.
*/
FrameEntry *topEntry;
FrameEntry *topEntry = NULL;
if (inlineReturn)
topEntry = a->parent->sp - (GET_ARGC(a->parent->PC) + 2);
else
topEntry = a->sp - uses.nuses;
for (uint32 i = tracker.nentries - 1; i < tracker.nentries; i--) {
FrameEntry *fe = tracker[i];
if (deadEntry(fe))
if (deadEntry(fe, uses.nuses))
continue;
if (!isTemporary(fe) && fe >= topEntry) {
/* No need to sync, this will get popped before branching. */
if (topEntry && fe >= topEntry && !isTemporary(fe)) {
/*
* The return value has already been stored, so there is no need to
* keep any of the entries for this frame or for values popped once
* the call returns intact. Forcibly evict any registers for these,
* so that we don't emit sync code for them if we need a register
* in syncFe below.
*/
forgetAllRegs(fe);
fe->resetSynced();
continue;
}