[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_FORNAME:
case JSOP_FORGNAME: case JSOP_FORGNAME:
case JSOP_CALLPROP:
stack[stackDepth - 1] = code->poppedValues[0]; stack[stackDepth - 1] = code->poppedValues[0];
break; break;
@ -1826,6 +1825,21 @@ CrossScriptSSA::foldValue(const CrossSSAValue &cv)
break; 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:; default:;
} }
} }

View File

@ -657,19 +657,25 @@ FrameState::syncForAllocation(RegisterAllocation *alloc, bool inlineReturn, Uses
* call returns. * call returns.
*/ */
FrameEntry *topEntry; FrameEntry *topEntry = NULL;
if (inlineReturn) if (inlineReturn)
topEntry = a->parent->sp - (GET_ARGC(a->parent->PC) + 2); 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--) { for (uint32 i = tracker.nentries - 1; i < tracker.nentries; i--) {
FrameEntry *fe = tracker[i]; FrameEntry *fe = tracker[i];
if (deadEntry(fe)) if (deadEntry(fe, uses.nuses))
continue; continue;
if (!isTemporary(fe) && fe >= topEntry) { if (topEntry && fe >= topEntry && !isTemporary(fe)) {
/* No need to sync, this will get popped before branching. */ /*
* 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; continue;
} }