Bug 1004388 part 2 - Call improveTypesAtTest in more cases. r=bhackett

This commit is contained in:
Jan de Mooij 2014-12-12 15:41:06 +01:00
Родитель ca52532afc
Коммит 475547d1ef
1 изменённых файлов: 20 добавлений и 10 удалений

Просмотреть файл

@ -1959,7 +1959,8 @@ IonBuilder::processCfgEntry(CFGState &state)
IonBuilder::ControlStatus IonBuilder::ControlStatus
IonBuilder::processIfEnd(CFGState &state) IonBuilder::processIfEnd(CFGState &state)
{ {
if (current) { bool thenBranchTerminated = !current;
if (!thenBranchTerminated) {
// Here, the false block is the join point. Create an edge from the // Here, the false block is the join point. Create an edge from the
// current block to the false block. Note that a RETURN opcode // current block to the false block. Note that a RETURN opcode
// could have already ended the block. // could have already ended the block.
@ -1973,6 +1974,15 @@ IonBuilder::processIfEnd(CFGState &state)
return ControlStatus_Error; return ControlStatus_Error;
graph().moveBlockToEnd(current); graph().moveBlockToEnd(current);
pc = current->pc(); pc = current->pc();
if (thenBranchTerminated) {
// If we can't reach here via the then-branch, we can filter the types
// after the if-statement based on the if-condition.
MTest *test = state.branch.test;
if (!improveTypesAtTest(test->getOperand(0), test->ifTrue() == current, test))
return ControlStatus_Error;
}
return ControlStatus_Joined; return ControlStatus_Joined;
} }
@ -1989,11 +1999,9 @@ IonBuilder::processIfElseTrueEnd(CFGState &state)
return ControlStatus_Error; return ControlStatus_Error;
graph().moveBlockToEnd(current); graph().moveBlockToEnd(current);
if (state.branch.test) { MTest *test = state.branch.test;
MTest *test = state.branch.test; if (!improveTypesAtTest(test->getOperand(0), test->ifTrue() == current, test))
if (!improveTypesAtTest(test->getOperand(0), test->ifTrue() == current, test)) return ControlStatus_Error;
return ControlStatus_Error;
}
return ControlStatus_Jumped; return ControlStatus_Jumped;
} }
@ -2288,6 +2296,10 @@ IonBuilder::processWhileCondEnd(CFGState &state)
if (!setCurrentAndSpecializePhis(body)) if (!setCurrentAndSpecializePhis(body))
return ControlStatus_Error; return ControlStatus_Error;
// Filter the types in the loop body.
if (!improveTypesAtTest(test->getOperand(0), test->ifTrue() == current, test))
return ControlStatus_Error;
// If this is a for-in loop, unbox the current value as string if possible. // If this is a for-in loop, unbox the current value as string if possible.
if (ins->isIsNoIter()) { if (ins->isIsNoIter()) {
MIteratorMore *iterMore = ins->toIsNoIter()->input()->toIteratorMore(); MIteratorMore *iterMore = ins->toIsNoIter()->input()->toIteratorMore();
@ -3362,10 +3374,8 @@ IonBuilder::improveTypesAtCompare(MCompare *ins, bool trueBranch, MTest *test)
bool bool
IonBuilder::improveTypesAtTest(MDefinition *ins, bool trueBranch, MTest *test) IonBuilder::improveTypesAtTest(MDefinition *ins, bool trueBranch, MTest *test)
{ {
// We explore the test condition to try and deduce // We explore the test condition to try and deduce as much type information
// as much type information as possible. // as possible.
if (!ins)
return true;
// All branches of this switch that don't want to fall through to the // All branches of this switch that don't want to fall through to the
// default behavior must return. The default behavior assumes that a true // default behavior must return. The default behavior assumes that a true