Backout consolidation of pending arrays for switch targets, bug 730888. r=dvander

This commit is contained in:
Brian Hackett 2012-03-01 17:48:32 -08:00
parent 2b8aaf381a
commit 11e1796a6b
3 changed files with 27 additions and 52 deletions

View File

@ -0,0 +1,14 @@
(function() {
for (var i = 0; i < 64; ++i) {
var name;
switch (this) {
case 0: name = 'firstAttr'; break;
case 1: name = 'secondAttr';
case 2: name = 'thirdAttr'; break;
}
switch (name) {
case 'firstAttr': assertEq(result, 'value'); break;
}
}
})();

View File

@ -1316,6 +1316,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
SlotValue &v = (*pending)[i];
if (v.slot < numSlots && liveness(v.slot).firstWrite(code->loop) != UINT32_MAX) {
if (v.value.kind() != SSAValue::PHI || v.value.phiOffset() != offset) {
JS_ASSERT(v.value.phiOffset() < offset);
SSAValue ov = v.value;
if (!makePhi(cx, v.slot, offset, &ov))
return;
@ -1524,19 +1525,14 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
jsint high = GET_JUMP_OFFSET(pc2);
pc2 += JUMP_OFFSET_LEN;
Vector<SlotValue> *pending = NULL;
uint32_t pendingOffset = 0;
for (jsint i = low; i <= high; i++) {
unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
if (targetOffset != offset)
checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth,
&pending, &pendingOffset);
checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
pc2 += JUMP_OFFSET_LEN;
}
checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth,
&pending, &pendingOffset);
checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth);
break;
}
@ -1546,20 +1542,15 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
unsigned npairs = GET_UINT16(pc2);
pc2 += UINT16_LEN;
Vector<SlotValue> *pending = NULL;
uint32_t pendingOffset = 0;
while (npairs) {
pc2 += UINT32_INDEX_LEN;
unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth,
&pending, &pendingOffset);
checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
pc2 += JUMP_OFFSET_LEN;
npairs--;
}
checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth,
&pending, &pendingOffset);
checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth);
break;
}
@ -1696,7 +1687,7 @@ ScriptAnalysis::mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, Sl
if (v == pv->value)
return;
if (pv->value.kind() != SSAValue::PHI || pv->value.phiOffset() != offset) {
if (pv->value.kind() != SSAValue::PHI || pv->value.phiOffset() < offset) {
SSAValue ov = pv->value;
if (makePhi(cx, pv->slot, offset, &pv->value)) {
insertPhi(cx, pv->value, v);
@ -1705,6 +1696,7 @@ ScriptAnalysis::mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, Sl
return;
}
JS_ASSERT(pv->value.phiOffset() == offset);
insertPhi(cx, pv->value, v);
}
@ -1726,8 +1718,7 @@ ScriptAnalysis::checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slo
void
ScriptAnalysis::checkBranchTarget(JSContext *cx, uint32_t targetOffset,
Vector<uint32_t> &branchTargets,
SSAValueInfo *values, uint32_t stackDepth,
Vector<SlotValue> **ppending, uint32_t *ppendingOffset)
SSAValueInfo *values, uint32_t stackDepth)
{
unsigned targetDepth = getCode(targetOffset).stackDepth;
JS_ASSERT(targetDepth <= stackDepth);
@ -1744,25 +1735,11 @@ ScriptAnalysis::checkBranchTarget(JSContext *cx, uint32_t targetOffset,
mergeValue(cx, targetOffset, values[v.slot].v, &v);
}
} else {
if (ppending && *ppending) {
JS_ASSERT(*ppendingOffset != targetOffset);
pending = *ppending;
getCode(Min(targetOffset, *ppendingOffset)).switchSharesPending = true;
} else {
pending = cx->new_< Vector<SlotValue> >(cx);
if (!pending) {
setOOM(cx);
return;
}
}
if (!branchTargets.append(targetOffset)) {
pending = cx->new_< Vector<SlotValue> >(cx);
if (!pending || !branchTargets.append(targetOffset)) {
setOOM(cx);
return;
}
if (ppending) {
*ppending = pending;
*ppendingOffset = Max(targetOffset, *ppendingOffset);
}
}
/*
@ -1822,13 +1799,6 @@ ScriptAnalysis::mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t s
const Bytecode &code = getCode(branchTargets[i]);
/*
* If the pending array for this offset is shared with a later branch
* target, it will be updated when that offset is handled.
*/
if (code.switchSharesPending)
continue;
Vector<SlotValue> *pending = code.pendingValues;
checkPendingValue(cx, value.v, slot, pending);
}
@ -1893,8 +1863,7 @@ ScriptAnalysis::freezeNewValues(JSContext *cx, uint32_t offset)
unsigned count = pending->length();
if (count == 0) {
if (!code.switchSharesPending)
cx->delete_(pending);
cx->delete_(pending);
return;
}
@ -1909,8 +1878,7 @@ ScriptAnalysis::freezeNewValues(JSContext *cx, uint32_t offset)
code.newValues[count].slot = 0;
code.newValues[count].value.clear();
if (!code.switchSharesPending)
cx->delete_(pending);
cx->delete_(pending);
}
CrossSSAValue

View File

@ -142,12 +142,6 @@ class Bytecode
bool getStringElement:1; /* GETELEM which has accessed string properties. */
bool accessGetter: 1; /* Property read on a shape with a getter hook. */
/*
* Switch target other than the last one, which shares its pending values
* with a later offset during SSA analysis.
*/
bool switchSharesPending : 1;
/* Stack depth before this opcode. */
uint32_t stackDepth;
@ -1213,8 +1207,7 @@ class ScriptAnalysis
void checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slot,
Vector<SlotValue> *pending);
void checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector<uint32_t> &branchTargets,
SSAValueInfo *values, uint32_t stackDepth,
Vector<SlotValue> **ppending = NULL, uint32_t *ppendingOffset = NULL);
SSAValueInfo *values, uint32_t stackDepth);
void checkExceptionTarget(JSContext *cx, uint32_t catchOffset,
Vector<uint32_t> &exceptionTargets);
void mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t slot,