mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[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:
parent
4995d87bb4
commit
efa5cac9d0
@ -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:;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user