Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 95090d5160ca096a9391e6d39d10548a37ea193a..f127680804f5f5748365d0662a21f7873c097f03 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -828,7 +828,6 @@ void HGraphBuilder::IfBuilder::Else() { |
ASSERT(!captured_); |
ASSERT(!finished_); |
last_true_block_ = builder_->current_block(); |
- ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); |
builder_->set_current_block(first_false_block_); |
did_else_ = true; |
} |
@@ -864,9 +863,11 @@ void HGraphBuilder::IfBuilder::End() { |
if (!did_else_) { |
last_true_block_ = builder_->current_block(); |
} |
- if (first_true_block_ == NULL) { |
+ if (last_true_block_ == NULL || last_true_block_->IsFinished()) { |
+ ASSERT(did_else_); |
// Return on true. Nothing to do, just continue the false block. |
- } else if (first_false_block_ == NULL) { |
+ } else if (first_false_block_ == NULL || |
+ (did_else_ && builder_->current_block()->IsFinished())) { |
// Deopt on false. Nothing to do except switching to the true block. |
builder_->set_current_block(last_true_block_); |
} else { |
@@ -906,6 +907,24 @@ HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
header_block_ = builder->CreateLoopHeaderBlock(); |
body_block_ = NULL; |
exit_block_ = NULL; |
+ exit_trampoline_block_ = NULL; |
+ increment_amount_ = builder_->graph()->GetConstant1(); |
+} |
+ |
+ |
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
+ HValue* context, |
+ LoopBuilder::Direction direction, |
+ HValue* increment_amount) |
+ : builder_(builder), |
+ context_(context), |
+ direction_(direction), |
+ finished_(false) { |
+ header_block_ = builder->CreateLoopHeaderBlock(); |
+ body_block_ = NULL; |
+ exit_block_ = NULL; |
+ exit_trampoline_block_ = NULL; |
+ increment_amount_ = increment_amount; |
} |
@@ -921,12 +940,14 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( |
HEnvironment* body_env = env->Copy(); |
HEnvironment* exit_env = env->Copy(); |
- body_block_ = builder_->CreateBasicBlock(body_env); |
- exit_block_ = builder_->CreateBasicBlock(exit_env); |
// Remove the phi from the expression stack |
body_env->Pop(); |
+ exit_env->Pop(); |
+ body_block_ = builder_->CreateBasicBlock(body_env); |
+ exit_block_ = builder_->CreateBasicBlock(exit_env); |
builder_->set_current_block(header_block_); |
+ env->Pop(); |
HCompareNumericAndBranch* compare = |
new(zone()) HCompareNumericAndBranch(phi_, terminating, token); |
compare->SetSuccessorAt(0, body_block_); |
@@ -950,15 +971,26 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( |
} |
+void HGraphBuilder::LoopBuilder::Break() { |
+ if (exit_trampoline_block_ == NULL) { |
+ // Its the first time we saw a break. |
+ HEnvironment* env = exit_block_->last_environment()->Copy(); |
+ exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
+ exit_block_->GotoNoSimulate(exit_trampoline_block_); |
+ } |
+ |
+ builder_->current_block()->GotoNoSimulate(exit_trampoline_block_); |
+} |
+ |
+ |
void HGraphBuilder::LoopBuilder::EndBody() { |
ASSERT(!finished_); |
if (direction_ == kPostIncrement || direction_ == kPostDecrement) { |
- HValue* one = builder_->graph()->GetConstant1(); |
if (direction_ == kPostIncrement) { |
- increment_ = HAdd::New(zone(), context_, phi_, one); |
+ increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); |
} else { |
- increment_ = HSub::New(zone(), context_, phi_, one); |
+ increment_ = HSub::New(zone(), context_, phi_, increment_amount_); |
} |
increment_->ClearFlag(HValue::kCanOverflow); |
builder_->AddInstruction(increment_); |
@@ -970,9 +1002,11 @@ void HGraphBuilder::LoopBuilder::EndBody() { |
last_block->GotoNoSimulate(header_block_); |
header_block_->loop_information()->RegisterBackEdge(last_block); |
- builder_->set_current_block(exit_block_); |
- // Pop the phi from the expression stack |
- builder_->environment()->Pop(); |
+ if (exit_trampoline_block_ != NULL) { |
+ builder_->set_current_block(exit_trampoline_block_); |
+ } else { |
+ builder_->set_current_block(exit_block_); |
+ } |
finished_ = true; |
} |