OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 Node* node, BailoutId id_after, | 424 Node* node, BailoutId id_after, |
425 OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) { | 425 OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) { |
426 int count = OperatorProperties::GetFrameStateInputCount(node->op()); | 426 int count = OperatorProperties::GetFrameStateInputCount(node->op()); |
427 DCHECK_LE(count, 2); | 427 DCHECK_LE(count, 2); |
428 | 428 |
429 if (count >= 1) { | 429 if (count >= 1) { |
430 // Add the frame state for after the operation. | 430 // Add the frame state for after the operation. |
431 DCHECK_EQ(IrOpcode::kDead, | 431 DCHECK_EQ(IrOpcode::kDead, |
432 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 432 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
433 | 433 |
| 434 bool node_has_exception = NodeProperties::IsExceptionalCall(node); |
| 435 |
434 Node* frame_state_after = | 436 Node* frame_state_after = |
435 id_after == BailoutId::None() | 437 id_after == BailoutId::None() |
436 ? builder_->jsgraph()->EmptyFrameState() | 438 ? builder_->jsgraph()->EmptyFrameState() |
437 : builder_->environment()->Checkpoint(id_after, combine); | 439 : builder_->environment()->Checkpoint(id_after, combine, |
| 440 node_has_exception); |
438 | 441 |
439 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); | 442 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); |
440 } | 443 } |
441 | 444 |
442 if (count >= 2) { | 445 if (count >= 2) { |
443 // Add the frame state for before the operation. | 446 // Add the frame state for before the operation. |
444 DCHECK_EQ(IrOpcode::kDead, | 447 DCHECK_EQ(IrOpcode::kDead, |
445 NodeProperties::GetFrameStateInput(node, 1)->opcode()); | 448 NodeProperties::GetFrameStateInput(node, 1)->opcode()); |
446 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); | 449 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); |
447 } | 450 } |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 } | 865 } |
863 | 866 |
864 | 867 |
865 void AstGraphBuilder::Environment::UpdateStateValuesWithCache( | 868 void AstGraphBuilder::Environment::UpdateStateValuesWithCache( |
866 Node** state_values, int offset, int count) { | 869 Node** state_values, int offset, int count) { |
867 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 870 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
868 *state_values = builder_->state_values_cache_.GetNodeForValues( | 871 *state_values = builder_->state_values_cache_.GetNodeForValues( |
869 env_values, static_cast<size_t>(count)); | 872 env_values, static_cast<size_t>(count)); |
870 } | 873 } |
871 | 874 |
872 | 875 Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id, |
873 Node* AstGraphBuilder::Environment::Checkpoint( | 876 OutputFrameStateCombine combine, |
874 BailoutId ast_id, OutputFrameStateCombine combine) { | 877 bool owner_has_exception) { |
875 if (!builder()->info()->is_deoptimization_enabled()) { | 878 if (!builder()->info()->is_deoptimization_enabled()) { |
876 return builder()->jsgraph()->EmptyFrameState(); | 879 return builder()->jsgraph()->EmptyFrameState(); |
877 } | 880 } |
878 | 881 |
879 UpdateStateValues(¶meters_node_, 0, parameters_count()); | 882 UpdateStateValues(¶meters_node_, 0, parameters_count()); |
880 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count()); | 883 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count()); |
881 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), | 884 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), |
882 stack_height()); | 885 stack_height()); |
883 | 886 |
884 const Operator* op = common()->FrameState( | 887 const Operator* op = common()->FrameState( |
885 ast_id, combine, builder()->frame_state_function_info()); | 888 ast_id, combine, builder()->frame_state_function_info()); |
886 | 889 |
887 Node* result = graph()->NewNode(op, parameters_node_, locals_node_, | 890 Node* result = graph()->NewNode(op, parameters_node_, locals_node_, |
888 stack_node_, builder()->current_context(), | 891 stack_node_, builder()->current_context(), |
889 builder()->GetFunctionClosure(), | 892 builder()->GetFunctionClosure(), |
890 builder()->graph()->start()); | 893 builder()->graph()->start()); |
891 | 894 |
892 DCHECK(IsLivenessBlockConsistent()); | 895 DCHECK(IsLivenessBlockConsistent()); |
893 if (liveness_block() != nullptr) { | 896 if (liveness_block() != nullptr) { |
894 liveness_block()->Checkpoint(result); | 897 // If the owning node has an exception, register the checkpoint to the |
| 898 // predecessor so that the checkpoint is used for both the normal and the |
| 899 // exceptional paths. Yes, this is a terrible hack and we might want |
| 900 // to use an explicit frame state for the exceptional path. |
| 901 if (owner_has_exception) { |
| 902 liveness_block()->GetPredecessor()->Checkpoint(result); |
| 903 } else { |
| 904 liveness_block()->Checkpoint(result); |
| 905 } |
895 } | 906 } |
896 return result; | 907 return result; |
897 } | 908 } |
898 | 909 |
899 | 910 |
900 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() { | 911 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() { |
901 return FLAG_analyze_environment_liveness && | 912 return FLAG_analyze_environment_liveness && |
902 builder()->info()->is_deoptimization_enabled(); | 913 builder()->info()->is_deoptimization_enabled(); |
903 } | 914 } |
904 | 915 |
(...skipping 3130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4035 } | 4046 } |
4036 | 4047 |
4037 | 4048 |
4038 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, | 4049 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, |
4039 OutputFrameStateCombine combine) { | 4050 OutputFrameStateCombine combine) { |
4040 if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) { | 4051 if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) { |
4041 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); | 4052 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); |
4042 | 4053 |
4043 DCHECK_EQ(IrOpcode::kDead, | 4054 DCHECK_EQ(IrOpcode::kDead, |
4044 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 4055 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
| 4056 bool node_has_exception = NodeProperties::IsExceptionalCall(node); |
4045 NodeProperties::ReplaceFrameStateInput( | 4057 NodeProperties::ReplaceFrameStateInput( |
4046 node, 0, environment()->Checkpoint(ast_id, combine)); | 4058 node, 0, |
| 4059 environment()->Checkpoint(ast_id, combine, node_has_exception)); |
4047 } | 4060 } |
4048 } | 4061 } |
4049 | 4062 |
4050 | 4063 |
4051 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 4064 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
4052 IterationStatement* stmt) { | 4065 IterationStatement* stmt) { |
4053 if (loop_assignment_analysis_ == nullptr) return nullptr; | 4066 if (loop_assignment_analysis_ == nullptr) return nullptr; |
4054 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 4067 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); |
4055 } | 4068 } |
4056 | 4069 |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4352 // Phi does not exist yet, introduce one. | 4365 // Phi does not exist yet, introduce one. |
4353 value = NewPhi(inputs, value, control); | 4366 value = NewPhi(inputs, value, control); |
4354 value->ReplaceInput(inputs - 1, other); | 4367 value->ReplaceInput(inputs - 1, other); |
4355 } | 4368 } |
4356 return value; | 4369 return value; |
4357 } | 4370 } |
4358 | 4371 |
4359 } // namespace compiler | 4372 } // namespace compiler |
4360 } // namespace internal | 4373 } // namespace internal |
4361 } // namespace v8 | 4374 } // namespace v8 |
OLD | NEW |