| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index decfb14542d1fe24999514b2241260e0b9053dfc..bbe121704ce18641f70dd238c8daeb56d4584b5e 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -4773,23 +4773,24 @@ void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
|
| HBasicBlock* cond_false = graph()->CreateBasicBlock();
|
| CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
|
|
|
| - if (cond_true->HasPredecessor()) {
|
| - cond_true->SetJoinId(stmt->ThenId());
|
| - set_current_block(cond_true);
|
| - CHECK_BAILOUT(Visit(stmt->then_statement()));
|
| - cond_true = current_block();
|
| - } else {
|
| - cond_true = NULL;
|
| - }
|
| + // Technically, we should be able to handle the case when one side of
|
| + // the test is not connected, but this can trip up liveness analysis
|
| + // if we did not fully connect the test context based on some optimistic
|
| + // assumption. If such an assumption was violated, we would end up with
|
| + // an environment with optimized-out values. So we should always
|
| + // conservatively connect the test context.
|
| + CHECK(cond_true->HasPredecessor());
|
| + CHECK(cond_false->HasPredecessor());
|
| +
|
| + cond_true->SetJoinId(stmt->ThenId());
|
| + set_current_block(cond_true);
|
| + CHECK_BAILOUT(Visit(stmt->then_statement()));
|
| + cond_true = current_block();
|
|
|
| - if (cond_false->HasPredecessor()) {
|
| - cond_false->SetJoinId(stmt->ElseId());
|
| - set_current_block(cond_false);
|
| - CHECK_BAILOUT(Visit(stmt->else_statement()));
|
| - cond_false = current_block();
|
| - } else {
|
| - cond_false = NULL;
|
| - }
|
| + cond_false->SetJoinId(stmt->ElseId());
|
| + set_current_block(cond_false);
|
| + CHECK_BAILOUT(Visit(stmt->else_statement()));
|
| + cond_false = current_block();
|
|
|
| HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId());
|
| set_current_block(join);
|
| @@ -11319,12 +11320,10 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
|
|
|
| // Translate right subexpression by visiting it in the same AST
|
| // context as the entire expression.
|
| - if (eval_right->HasPredecessor()) {
|
| - eval_right->SetJoinId(expr->RightId());
|
| - set_current_block(eval_right);
|
| - Visit(expr->right());
|
| - }
|
| -
|
| + CHECK(eval_right->HasPredecessor());
|
| + eval_right->SetJoinId(expr->RightId());
|
| + set_current_block(eval_right);
|
| + Visit(expr->right());
|
| } else if (ast_context()->IsValue()) {
|
| CHECK_ALIVE(VisitForValue(expr->left()));
|
| DCHECK(current_block() != NULL);
|
| @@ -11380,20 +11379,22 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
|
| // second one is not a merge node, and that we really have no good AST ID to
|
| // put on that first HSimulate.
|
|
|
| - if (empty_block->HasPredecessor()) {
|
| - empty_block->SetJoinId(expr->id());
|
| - } else {
|
| - empty_block = NULL;
|
| - }
|
| + // Technically, we should be able to handle the case when one side of
|
| + // the test is not connected, but this can trip up liveness analysis
|
| + // if we did not fully connect the test context based on some optimistic
|
| + // assumption. If such an assumption was violated, we would end up with
|
| + // an environment with optimized-out values. So we should always
|
| + // conservatively connect the test context.
|
|
|
| - if (right_block->HasPredecessor()) {
|
| - right_block->SetJoinId(expr->RightId());
|
| - set_current_block(right_block);
|
| - CHECK_BAILOUT(VisitForEffect(expr->right()));
|
| - right_block = current_block();
|
| - } else {
|
| - right_block = NULL;
|
| - }
|
| + CHECK(right_block->HasPredecessor());
|
| + CHECK(empty_block->HasPredecessor());
|
| +
|
| + empty_block->SetJoinId(expr->id());
|
| +
|
| + right_block->SetJoinId(expr->RightId());
|
| + set_current_block(right_block);
|
| + CHECK_BAILOUT(VisitForEffect(expr->right()));
|
| + right_block = current_block();
|
|
|
| HBasicBlock* join_block =
|
| CreateJoin(empty_block, right_block, expr->id());
|
|
|