mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Backout consolidation of pending arrays for switch targets, bug 730888. r=dvander
This commit is contained in:
parent
2b8aaf381a
commit
11e1796a6b
14
js/src/jit-test/tests/basic/bug730888.js
Normal file
14
js/src/jit-test/tests/basic/bug730888.js
Normal 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;
|
||||
}
|
||||
}
|
||||
})();
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user