| 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 |