Chromium Code Reviews| 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)); |
| } |
| } |