Index: src/compiler/ast-graph-builder.cc |
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
index d640fadaa9f6656f2ac3102ff276cd695bb2e6fa..ab488e111d0b24bf4b183e88ba1a03d089968a7b 100644 |
--- a/src/compiler/ast-graph-builder.cc |
+++ b/src/compiler/ast-graph-builder.cc |
@@ -409,6 +409,19 @@ class AstGraphBuilder::ControlScopeForFinally : public ControlScope { |
TryFinallyBuilder* control_; |
}; |
+namespace { |
+ |
+bool NodeHasExceptionUse(Node* node) { |
Michael Starzinger
2016/02/12 09:32:40
Please use NodeProperties::IsExceptionalCall inste
Jarin
2016/02/12 09:58:32
Done.
|
+ if (node->op()->HasProperty(Operator::kNoThrow)) return false; |
+ for (Node* const user : node->uses()) { |
+ if (user->opcode() == IrOpcode::kIfException) { |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+} // namespace |
// Helper for generating before and after frame states. |
class AstGraphBuilder::FrameStateBeforeAndAfter { |
@@ -431,10 +444,13 @@ class AstGraphBuilder::FrameStateBeforeAndAfter { |
DCHECK_EQ(IrOpcode::kDead, |
NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
+ bool node_has_exception = NodeHasExceptionUse(node); |
+ |
Node* frame_state_after = |
id_after == BailoutId::None() |
? builder_->jsgraph()->EmptyFrameState() |
- : builder_->environment()->Checkpoint(id_after, combine); |
+ : builder_->environment()->Checkpoint(id_after, combine, |
+ node_has_exception); |
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); |
} |
@@ -869,9 +885,9 @@ void AstGraphBuilder::Environment::UpdateStateValuesWithCache( |
env_values, static_cast<size_t>(count)); |
} |
- |
-Node* AstGraphBuilder::Environment::Checkpoint( |
- BailoutId ast_id, OutputFrameStateCombine combine) { |
+Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id, |
+ OutputFrameStateCombine combine, |
+ bool owner_has_exception) { |
if (!builder()->info()->is_deoptimization_enabled()) { |
return builder()->jsgraph()->EmptyFrameState(); |
} |
@@ -891,7 +907,15 @@ Node* AstGraphBuilder::Environment::Checkpoint( |
DCHECK(IsLivenessBlockConsistent()); |
if (liveness_block() != nullptr) { |
- liveness_block()->Checkpoint(result); |
+ // If the owning node has an exception, register the checkpoint to the |
+ // predecessor so that the checkpoint is used for both the normal and the |
+ // exceptional paths. Yes, this is a terrible hack and we might want |
+ // to use an explicit frame state for the exceptional path. |
+ if (owner_has_exception) { |
+ liveness_block()->GetPredecessor()->Checkpoint(result); |
+ } else { |
+ liveness_block()->Checkpoint(result); |
+ } |
} |
return result; |
} |
@@ -4045,8 +4069,10 @@ void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, |
DCHECK_EQ(IrOpcode::kDead, |
NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
+ bool node_has_exception = NodeHasExceptionUse(node); |
NodeProperties::ReplaceFrameStateInput( |
- node, 0, environment()->Checkpoint(ast_id, combine)); |
+ node, 0, |
+ environment()->Checkpoint(ast_id, combine, node_has_exception)); |
} |
} |