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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 // them after again leaving that block. Special tokens are used to identify | 212 // them after again leaving that block. Special tokens are used to identify |
213 // paths going through the finally-block to dispatch after leaving the block. | 213 // paths going through the finally-block to dispatch after leaving the block. |
214 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { | 214 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
215 public: | 215 public: |
216 explicit DeferredCommands(AstGraphBuilder* owner) | 216 explicit DeferredCommands(AstGraphBuilder* owner) |
217 : owner_(owner), deferred_(owner->local_zone()) {} | 217 : owner_(owner), deferred_(owner->local_zone()) {} |
218 | 218 |
219 // One recorded control-flow command. | 219 // One recorded control-flow command. |
220 struct Entry { | 220 struct Entry { |
221 Command command; // The command type being applied on this path. | 221 Command command; // The command type being applied on this path. |
222 Statement* statement; // The target statement for the command or {NULL}. | 222 Statement* statement; // The target statement for the command or {nullptr}. |
223 Node* token; // A token identifying this particular path. | 223 Node* token; // A token identifying this particular path. |
224 }; | 224 }; |
225 | 225 |
226 // Records a control-flow command while entering the finally-block. This also | 226 // Records a control-flow command while entering the finally-block. This also |
227 // generates a new dispatch token that identifies one particular path. | 227 // generates a new dispatch token that identifies one particular path. |
228 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) { | 228 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) { |
229 Node* token = NewPathTokenForDeferredCommand(); | 229 Node* token = NewPathTokenForDeferredCommand(); |
230 deferred_.push_back({cmd, stmt, token}); | 230 deferred_.push_back({cmd, stmt, token}); |
231 return token; | 231 return token; |
232 } | 232 } |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 const Operator* op = common()->Parameter(index, "%new.target"); | 505 const Operator* op = common()->Parameter(index, "%new.target"); |
506 Node* node = NewNode(op, graph()->start()); | 506 Node* node = NewNode(op, graph()->start()); |
507 new_target_.set(node); | 507 new_target_.set(node); |
508 } | 508 } |
509 return new_target_.get(); | 509 return new_target_.get(); |
510 } | 510 } |
511 | 511 |
512 | 512 |
513 bool AstGraphBuilder::CreateGraph(bool stack_check) { | 513 bool AstGraphBuilder::CreateGraph(bool stack_check) { |
514 Scope* scope = info()->scope(); | 514 Scope* scope = info()->scope(); |
515 DCHECK(graph() != NULL); | 515 DCHECK_NOT_NULL(graph()); |
516 | 516 |
517 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 517 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
518 // parameters (including the receiver) plus new target, number of arguments, | 518 // parameters (including the receiver) plus new target, number of arguments, |
519 // context and closure. | 519 // context and closure. |
520 int actual_parameter_count = info()->num_parameters_including_this() + 4; | 520 int actual_parameter_count = info()->num_parameters_including_this() + 4; |
521 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 521 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
522 | 522 |
523 // Initialize the top-level environment. | 523 // Initialize the top-level environment. |
524 Environment env(this, scope, graph()->start()); | 524 Environment env(this, scope, graph()->start()); |
525 set_environment(&env); | 525 set_environment(&env); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 BitVector* assigned, bool is_osr) { | 822 BitVector* assigned, bool is_osr) { |
823 PrepareForLoop(assigned, is_osr); | 823 PrepareForLoop(assigned, is_osr); |
824 return CopyAndShareLiveness(); | 824 return CopyAndShareLiveness(); |
825 } | 825 } |
826 | 826 |
827 | 827 |
828 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 828 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
829 int offset, int count) { | 829 int offset, int count) { |
830 bool should_update = false; | 830 bool should_update = false; |
831 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 831 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
832 if (*state_values == NULL || (*state_values)->InputCount() != count) { | 832 if (*state_values == nullptr || (*state_values)->InputCount() != count) { |
833 should_update = true; | 833 should_update = true; |
834 } else { | 834 } else { |
835 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); | 835 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); |
836 for (int i = 0; i < count; i++) { | 836 for (int i = 0; i < count; i++) { |
837 if ((*state_values)->InputAt(i) != env_values[i]) { | 837 if ((*state_values)->InputAt(i) != env_values[i]) { |
838 should_update = true; | 838 should_update = true; |
839 break; | 839 break; |
840 } | 840 } |
841 } | 841 } |
842 } | 842 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | 932 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
933 environment()->Push(value); | 933 environment()->Push(value); |
934 } | 934 } |
935 | 935 |
936 | 936 |
937 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { | 937 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { |
938 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); | 938 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); |
939 } | 939 } |
940 | 940 |
941 | 941 |
942 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; } | 942 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } |
943 | 943 |
944 | 944 |
945 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { | 945 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { |
946 return environment()->Pop(); | 946 return environment()->Pop(); |
947 } | 947 } |
948 | 948 |
949 | 949 |
950 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { | 950 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { |
951 return environment()->Pop(); | 951 return environment()->Pop(); |
952 } | 952 } |
953 | 953 |
954 | 954 |
955 Scope* AstGraphBuilder::current_scope() const { | 955 Scope* AstGraphBuilder::current_scope() const { |
956 return execution_context_->scope(); | 956 return execution_context_->scope(); |
957 } | 957 } |
958 | 958 |
959 | 959 |
960 Node* AstGraphBuilder::current_context() const { | 960 Node* AstGraphBuilder::current_context() const { |
961 return environment()->Context(); | 961 return environment()->Context(); |
962 } | 962 } |
963 | 963 |
964 | 964 |
965 void AstGraphBuilder::ControlScope::PerformCommand(Command command, | 965 void AstGraphBuilder::ControlScope::PerformCommand(Command command, |
966 Statement* target, | 966 Statement* target, |
967 Node* value) { | 967 Node* value) { |
968 Environment* env = environment()->CopyAsUnreachable(); | 968 Environment* env = environment()->CopyAsUnreachable(); |
969 ControlScope* current = this; | 969 ControlScope* current = this; |
970 while (current != NULL) { | 970 while (current != nullptr) { |
971 environment()->TrimStack(current->stack_height()); | 971 environment()->TrimStack(current->stack_height()); |
972 environment()->TrimContextChain(current->context_length()); | 972 environment()->TrimContextChain(current->context_length()); |
973 if (current->Execute(command, target, value)) break; | 973 if (current->Execute(command, target, value)) break; |
974 current = current->outer_; | 974 current = current->outer_; |
975 } | 975 } |
976 builder()->set_environment(env); | 976 builder()->set_environment(env); |
977 DCHECK(current != NULL); // Always handled (unless stack is malformed). | 977 DCHECK_NOT_NULL(current); // Always handled (unless stack is malformed). |
978 } | 978 } |
979 | 979 |
980 | 980 |
981 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { | 981 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { |
982 PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant()); | 982 PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant()); |
983 } | 983 } |
984 | 984 |
985 | 985 |
986 void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) { | 986 void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) { |
987 PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant()); | 987 PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant()); |
988 } | 988 } |
989 | 989 |
990 | 990 |
991 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) { | 991 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) { |
992 PerformCommand(CMD_RETURN, nullptr, return_value); | 992 PerformCommand(CMD_RETURN, nullptr, return_value); |
993 } | 993 } |
994 | 994 |
995 | 995 |
996 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) { | 996 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) { |
997 PerformCommand(CMD_THROW, nullptr, exception_value); | 997 PerformCommand(CMD_THROW, nullptr, exception_value); |
998 } | 998 } |
999 | 999 |
1000 | 1000 |
1001 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) { | 1001 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) { |
1002 if (expr == NULL) { | 1002 if (expr == nullptr) { |
1003 return environment()->Push(jsgraph()->NullConstant()); | 1003 return environment()->Push(jsgraph()->NullConstant()); |
1004 } | 1004 } |
1005 VisitForValue(expr); | 1005 VisitForValue(expr); |
1006 } | 1006 } |
1007 | 1007 |
1008 | 1008 |
1009 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) { | 1009 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) { |
1010 if (expr == NULL) { | 1010 if (expr == nullptr) { |
1011 return environment()->Push(jsgraph()->TheHoleConstant()); | 1011 return environment()->Push(jsgraph()->TheHoleConstant()); |
1012 } | 1012 } |
1013 VisitForValue(expr); | 1013 VisitForValue(expr); |
1014 } | 1014 } |
1015 | 1015 |
1016 | 1016 |
1017 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { | 1017 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { |
1018 for (int i = 0; i < exprs->length(); ++i) { | 1018 for (int i = 0; i < exprs->length(); ++i) { |
1019 VisitForValue(exprs->at(i)); | 1019 VisitForValue(exprs->at(i)); |
1020 } | 1020 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 | 1134 |
1135 | 1135 |
1136 void AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) { | 1136 void AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) { |
1137 UNREACHABLE(); | 1137 UNREACHABLE(); |
1138 } | 1138 } |
1139 | 1139 |
1140 | 1140 |
1141 void AstGraphBuilder::VisitBlock(Block* stmt) { | 1141 void AstGraphBuilder::VisitBlock(Block* stmt) { |
1142 BlockBuilder block(this); | 1142 BlockBuilder block(this); |
1143 ControlScopeForBreakable scope(this, stmt, &block); | 1143 ControlScopeForBreakable scope(this, stmt, &block); |
1144 if (stmt->labels() != NULL) block.BeginBlock(); | 1144 if (stmt->labels() != nullptr) block.BeginBlock(); |
1145 if (stmt->scope() == NULL) { | 1145 if (stmt->scope() == nullptr) { |
1146 // Visit statements in the same scope, no declarations. | 1146 // Visit statements in the same scope, no declarations. |
1147 VisitStatements(stmt->statements()); | 1147 VisitStatements(stmt->statements()); |
1148 } else { | 1148 } else { |
1149 // Visit declarations and statements in a block scope. | 1149 // Visit declarations and statements in a block scope. |
1150 if (stmt->scope()->NeedsContext()) { | 1150 if (stmt->scope()->NeedsContext()) { |
1151 Node* context = BuildLocalBlockContext(stmt->scope()); | 1151 Node* context = BuildLocalBlockContext(stmt->scope()); |
1152 ContextScope scope(this, stmt->scope(), context); | 1152 ContextScope scope(this, stmt->scope(), context); |
1153 VisitDeclarations(stmt->scope()->declarations()); | 1153 VisitDeclarations(stmt->scope()->declarations()); |
1154 VisitStatements(stmt->statements()); | 1154 VisitStatements(stmt->statements()); |
1155 } else { | 1155 } else { |
1156 VisitDeclarations(stmt->scope()->declarations()); | 1156 VisitDeclarations(stmt->scope()->declarations()); |
1157 VisitStatements(stmt->statements()); | 1157 VisitStatements(stmt->statements()); |
1158 } | 1158 } |
1159 } | 1159 } |
1160 if (stmt->labels() != NULL) block.EndBlock(); | 1160 if (stmt->labels() != nullptr) block.EndBlock(); |
1161 } | 1161 } |
1162 | 1162 |
1163 | 1163 |
1164 void AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 1164 void AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { |
1165 VisitForEffect(stmt->expression()); | 1165 VisitForEffect(stmt->expression()); |
1166 } | 1166 } |
1167 | 1167 |
1168 | 1168 |
1169 void AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | 1169 void AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { |
1170 // Do nothing. | 1170 // Do nothing. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 VisitIterationBody(stmt, &while_loop); | 1291 VisitIterationBody(stmt, &while_loop); |
1292 while_loop.EndBody(); | 1292 while_loop.EndBody(); |
1293 while_loop.EndLoop(); | 1293 while_loop.EndLoop(); |
1294 } | 1294 } |
1295 | 1295 |
1296 | 1296 |
1297 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { | 1297 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { |
1298 LoopBuilder for_loop(this); | 1298 LoopBuilder for_loop(this); |
1299 VisitIfNotNull(stmt->init()); | 1299 VisitIfNotNull(stmt->init()); |
1300 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1300 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1301 if (stmt->cond() != NULL) { | 1301 if (stmt->cond() != nullptr) { |
1302 VisitForTest(stmt->cond()); | 1302 VisitForTest(stmt->cond()); |
1303 Node* condition = environment()->Pop(); | 1303 Node* condition = environment()->Pop(); |
1304 for_loop.BreakUnless(condition); | 1304 for_loop.BreakUnless(condition); |
1305 } else { | 1305 } else { |
1306 for_loop.BreakUnless(jsgraph()->TrueConstant()); | 1306 for_loop.BreakUnless(jsgraph()->TrueConstant()); |
1307 } | 1307 } |
1308 VisitIterationBody(stmt, &for_loop); | 1308 VisitIterationBody(stmt, &for_loop); |
1309 for_loop.EndBody(); | 1309 for_loop.EndBody(); |
1310 VisitIfNotNull(stmt->next()); | 1310 VisitIfNotNull(stmt->next()); |
1311 for_loop.EndLoop(); | 1311 for_loop.EndLoop(); |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2105 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2105 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2106 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2106 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2107 VisitForValue(property->key()); | 2107 VisitForValue(property->key()); |
2108 break; | 2108 break; |
2109 } | 2109 } |
2110 | 2110 |
2111 BailoutId before_store_id = BailoutId::None(); | 2111 BailoutId before_store_id = BailoutId::None(); |
2112 // Evaluate the value and potentially handle compound assignments by loading | 2112 // Evaluate the value and potentially handle compound assignments by loading |
2113 // the left-hand side value and performing a binary operation. | 2113 // the left-hand side value and performing a binary operation. |
2114 if (expr->is_compound()) { | 2114 if (expr->is_compound()) { |
2115 Node* old_value = NULL; | 2115 Node* old_value = nullptr; |
2116 switch (assign_type) { | 2116 switch (assign_type) { |
2117 case VARIABLE: { | 2117 case VARIABLE: { |
2118 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2118 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
2119 VectorSlotPair pair = | 2119 VectorSlotPair pair = |
2120 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2120 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2121 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2121 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2122 old_value = | 2122 old_value = |
2123 BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair, | 2123 BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair, |
2124 OutputFrameStateCombine::Push()); | 2124 OutputFrameStateCombine::Push()); |
2125 break; | 2125 break; |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2633 Property* property = expr->expression()->AsProperty(); | 2633 Property* property = expr->expression()->AsProperty(); |
2634 LhsKind assign_type = Property::GetAssignType(property); | 2634 LhsKind assign_type = Property::GetAssignType(property); |
2635 | 2635 |
2636 // Reserve space for result of postfix operation. | 2636 // Reserve space for result of postfix operation. |
2637 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); | 2637 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); |
2638 if (is_postfix && assign_type != VARIABLE) { | 2638 if (is_postfix && assign_type != VARIABLE) { |
2639 environment()->Push(jsgraph()->ZeroConstant()); | 2639 environment()->Push(jsgraph()->ZeroConstant()); |
2640 } | 2640 } |
2641 | 2641 |
2642 // Evaluate LHS expression and get old value. | 2642 // Evaluate LHS expression and get old value. |
2643 Node* old_value = NULL; | 2643 Node* old_value = nullptr; |
2644 int stack_depth = -1; | 2644 int stack_depth = -1; |
2645 switch (assign_type) { | 2645 switch (assign_type) { |
2646 case VARIABLE: { | 2646 case VARIABLE: { |
2647 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2647 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2648 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2648 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2649 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2649 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2650 old_value = | 2650 old_value = |
2651 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, | 2651 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, |
2652 pair, OutputFrameStateCombine::Push()); | 2652 pair, OutputFrameStateCombine::Push()); |
2653 stack_depth = 0; | 2653 stack_depth = 0; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2859 case Token::GTE: | 2859 case Token::GTE: |
2860 op = javascript()->GreaterThanOrEqual(language_mode()); | 2860 op = javascript()->GreaterThanOrEqual(language_mode()); |
2861 break; | 2861 break; |
2862 case Token::INSTANCEOF: | 2862 case Token::INSTANCEOF: |
2863 op = javascript()->InstanceOf(); | 2863 op = javascript()->InstanceOf(); |
2864 break; | 2864 break; |
2865 case Token::IN: | 2865 case Token::IN: |
2866 op = javascript()->HasProperty(); | 2866 op = javascript()->HasProperty(); |
2867 break; | 2867 break; |
2868 default: | 2868 default: |
2869 op = NULL; | 2869 op = nullptr; |
2870 UNREACHABLE(); | 2870 UNREACHABLE(); |
2871 } | 2871 } |
2872 VisitForValue(expr->left()); | 2872 VisitForValue(expr->left()); |
2873 VisitForValue(expr->right()); | 2873 VisitForValue(expr->right()); |
2874 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2874 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
2875 Node* right = environment()->Pop(); | 2875 Node* right = environment()->Pop(); |
2876 Node* left = environment()->Pop(); | 2876 Node* left = environment()->Pop(); |
2877 Node* value = NewNode(op, left, right); | 2877 Node* value = NewNode(op, left, right); |
2878 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2878 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2879 ast_context()->ProduceValue(value); | 2879 ast_context()->ProduceValue(value); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2931 Node* flags = jsgraph()->Constant(encoded_flags); | 2931 Node* flags = jsgraph()->Constant(encoded_flags); |
2932 Node* pairs = jsgraph()->Constant(data); | 2932 Node* pairs = jsgraph()->Constant(data); |
2933 const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 2); | 2933 const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 2); |
2934 Node* call = NewNode(op, pairs, flags); | 2934 Node* call = NewNode(op, pairs, flags); |
2935 PrepareFrameState(call, BailoutId::Declarations()); | 2935 PrepareFrameState(call, BailoutId::Declarations()); |
2936 globals()->clear(); | 2936 globals()->clear(); |
2937 } | 2937 } |
2938 | 2938 |
2939 | 2939 |
2940 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { | 2940 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { |
2941 if (stmt == NULL) return; | 2941 if (stmt == nullptr) return; |
2942 Visit(stmt); | 2942 Visit(stmt); |
2943 } | 2943 } |
2944 | 2944 |
2945 | 2945 |
2946 void AstGraphBuilder::VisitInScope(Statement* stmt, Scope* s, Node* context) { | 2946 void AstGraphBuilder::VisitInScope(Statement* stmt, Scope* s, Node* context) { |
2947 ContextScope scope(this, s, context); | 2947 ContextScope scope(this, s, context); |
2948 DCHECK(s->declarations()->is_empty()); | 2948 DCHECK(s->declarations()->is_empty()); |
2949 Visit(stmt); | 2949 Visit(stmt); |
2950 } | 2950 } |
2951 | 2951 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3199 // Allocate a new local context. | 3199 // Allocate a new local context. |
3200 Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate()); | 3200 Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate()); |
3201 const Operator* op = javascript()->CreateBlockContext(scope_info); | 3201 const Operator* op = javascript()->CreateBlockContext(scope_info); |
3202 Node* local_context = NewNode(op, GetFunctionClosureForContext()); | 3202 Node* local_context = NewNode(op, GetFunctionClosureForContext()); |
3203 | 3203 |
3204 return local_context; | 3204 return local_context; |
3205 } | 3205 } |
3206 | 3206 |
3207 | 3207 |
3208 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 3208 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { |
3209 if (arguments == NULL) return NULL; | 3209 if (arguments == nullptr) return nullptr; |
3210 | 3210 |
3211 // Allocate and initialize a new arguments object. | 3211 // Allocate and initialize a new arguments object. |
3212 CreateArgumentsParameters::Type type = | 3212 CreateArgumentsParameters::Type type = |
3213 is_strict(language_mode()) || !info()->has_simple_parameters() | 3213 is_strict(language_mode()) || !info()->has_simple_parameters() |
3214 ? CreateArgumentsParameters::kUnmappedArguments | 3214 ? CreateArgumentsParameters::kUnmappedArguments |
3215 : CreateArgumentsParameters::kMappedArguments; | 3215 : CreateArgumentsParameters::kMappedArguments; |
3216 const Operator* op = javascript()->CreateArguments(type, 0); | 3216 const Operator* op = javascript()->CreateArguments(type, 0); |
3217 Node* object = NewNode(op, GetFunctionClosure()); | 3217 Node* object = NewNode(op, GetFunctionClosure()); |
3218 PrepareFrameState(object, BailoutId::None()); | 3218 PrepareFrameState(object, BailoutId::None()); |
3219 | 3219 |
3220 // Assign the object to the {arguments} variable. This should never lazy | 3220 // Assign the object to the {arguments} variable. This should never lazy |
3221 // deopt, so it is fine to send invalid bailout id. | 3221 // deopt, so it is fine to send invalid bailout id. |
3222 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 3222 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
3223 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3223 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3224 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), | 3224 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), |
3225 BailoutId::None(), states); | 3225 BailoutId::None(), states); |
3226 return object; | 3226 return object; |
3227 } | 3227 } |
3228 | 3228 |
3229 | 3229 |
3230 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { | 3230 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { |
3231 if (rest == NULL) return NULL; | 3231 if (rest == nullptr) return nullptr; |
3232 | 3232 |
3233 // Allocate and initialize a new arguments object. | 3233 // Allocate and initialize a new arguments object. |
3234 CreateArgumentsParameters::Type type = CreateArgumentsParameters::kRestArray; | 3234 CreateArgumentsParameters::Type type = CreateArgumentsParameters::kRestArray; |
3235 const Operator* op = javascript()->CreateArguments(type, index); | 3235 const Operator* op = javascript()->CreateArguments(type, index); |
3236 Node* object = NewNode(op, GetFunctionClosure()); | 3236 Node* object = NewNode(op, GetFunctionClosure()); |
3237 PrepareFrameState(object, BailoutId::None()); | 3237 PrepareFrameState(object, BailoutId::None()); |
3238 | 3238 |
3239 // Assign the object to the {rest} variable. This should never lazy | 3239 // Assign the object to the {rest} variable. This should never lazy |
3240 // deopt, so it is fine to send invalid bailout id. | 3240 // deopt, so it is fine to send invalid bailout id. |
3241 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3241 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 feedback, combine, typeof_mode)) { | 3405 feedback, combine, typeof_mode)) { |
3406 return node; | 3406 return node; |
3407 } | 3407 } |
3408 const Operator* op = javascript()->LoadDynamic(name, typeof_mode); | 3408 const Operator* op = javascript()->LoadDynamic(name, typeof_mode); |
3409 Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3409 Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context()); |
3410 states.AddToNode(value, bailout_id, combine); | 3410 states.AddToNode(value, bailout_id, combine); |
3411 return value; | 3411 return value; |
3412 } | 3412 } |
3413 } | 3413 } |
3414 UNREACHABLE(); | 3414 UNREACHABLE(); |
3415 return NULL; | 3415 return nullptr; |
3416 } | 3416 } |
3417 | 3417 |
3418 | 3418 |
3419 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, | 3419 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, |
3420 BailoutId bailout_id, | 3420 BailoutId bailout_id, |
3421 OutputFrameStateCombine combine) { | 3421 OutputFrameStateCombine combine) { |
3422 switch (variable->location()) { | 3422 switch (variable->location()) { |
3423 case VariableLocation::GLOBAL: | 3423 case VariableLocation::GLOBAL: |
3424 case VariableLocation::UNALLOCATED: { | 3424 case VariableLocation::UNALLOCATED: { |
3425 // Global var, const, or let variable. | 3425 // Global var, const, or let variable. |
(...skipping 14 matching lines...) Expand all Loading... |
3440 // Dynamic lookup of context variable (anywhere in the chain). | 3440 // Dynamic lookup of context variable (anywhere in the chain). |
3441 Node* name = jsgraph()->Constant(variable->name()); | 3441 Node* name = jsgraph()->Constant(variable->name()); |
3442 const Operator* op = | 3442 const Operator* op = |
3443 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); | 3443 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); |
3444 Node* result = NewNode(op, current_context(), name); | 3444 Node* result = NewNode(op, current_context(), name); |
3445 PrepareFrameState(result, bailout_id, combine); | 3445 PrepareFrameState(result, bailout_id, combine); |
3446 return result; | 3446 return result; |
3447 } | 3447 } |
3448 } | 3448 } |
3449 UNREACHABLE(); | 3449 UNREACHABLE(); |
3450 return NULL; | 3450 return nullptr; |
3451 } | 3451 } |
3452 | 3452 |
3453 | 3453 |
3454 Node* AstGraphBuilder::BuildVariableAssignment( | 3454 Node* AstGraphBuilder::BuildVariableAssignment( |
3455 Variable* variable, Node* value, Token::Value op, | 3455 Variable* variable, Node* value, Token::Value op, |
3456 const VectorSlotPair& feedback, BailoutId bailout_id, | 3456 const VectorSlotPair& feedback, BailoutId bailout_id, |
3457 FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) { | 3457 FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) { |
3458 Node* the_hole = jsgraph()->TheHoleConstant(); | 3458 Node* the_hole = jsgraph()->TheHoleConstant(); |
3459 VariableMode mode = variable->mode(); | 3459 VariableMode mode = variable->mode(); |
3460 switch (variable->location()) { | 3460 switch (variable->location()) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3568 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 3568 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for |
3569 // initializations of const declarations. | 3569 // initializations of const declarations. |
3570 const Operator* op = | 3570 const Operator* op = |
3571 javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4); | 3571 javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4); |
3572 Node* store = NewNode(op, value, current_context(), name, language); | 3572 Node* store = NewNode(op, value, current_context(), name, language); |
3573 PrepareFrameState(store, bailout_id, combine); | 3573 PrepareFrameState(store, bailout_id, combine); |
3574 return store; | 3574 return store; |
3575 } | 3575 } |
3576 } | 3576 } |
3577 UNREACHABLE(); | 3577 UNREACHABLE(); |
3578 return NULL; | 3578 return nullptr; |
3579 } | 3579 } |
3580 | 3580 |
3581 | 3581 |
3582 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, | 3582 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, |
3583 const VectorSlotPair& feedback) { | 3583 const VectorSlotPair& feedback) { |
3584 const Operator* op = javascript()->LoadProperty(language_mode(), feedback); | 3584 const Operator* op = javascript()->LoadProperty(language_mode(), feedback); |
3585 Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); | 3585 Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); |
3586 return node; | 3586 return node; |
3587 } | 3587 } |
3588 | 3588 |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3865 js_op = javascript()->Multiply(language_mode(), hints); | 3865 js_op = javascript()->Multiply(language_mode(), hints); |
3866 break; | 3866 break; |
3867 case Token::DIV: | 3867 case Token::DIV: |
3868 js_op = javascript()->Divide(language_mode(), hints); | 3868 js_op = javascript()->Divide(language_mode(), hints); |
3869 break; | 3869 break; |
3870 case Token::MOD: | 3870 case Token::MOD: |
3871 js_op = javascript()->Modulus(language_mode(), hints); | 3871 js_op = javascript()->Modulus(language_mode(), hints); |
3872 break; | 3872 break; |
3873 default: | 3873 default: |
3874 UNREACHABLE(); | 3874 UNREACHABLE(); |
3875 js_op = NULL; | 3875 js_op = nullptr; |
3876 } | 3876 } |
3877 return NewNode(js_op, left, right); | 3877 return NewNode(js_op, left, right); |
3878 } | 3878 } |
3879 | 3879 |
3880 | 3880 |
3881 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { | 3881 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { |
3882 // Optimize global constants like "undefined", "Infinity", and "NaN". | 3882 // Optimize global constants like "undefined", "Infinity", and "NaN". |
3883 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); | 3883 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); |
3884 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); | 3884 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); |
3885 return nullptr; | 3885 return nullptr; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4048 DCHECK_EQ(IrOpcode::kDead, | 4048 DCHECK_EQ(IrOpcode::kDead, |
4049 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 4049 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
4050 NodeProperties::ReplaceFrameStateInput( | 4050 NodeProperties::ReplaceFrameStateInput( |
4051 node, 0, environment()->Checkpoint(ast_id, combine)); | 4051 node, 0, environment()->Checkpoint(ast_id, combine)); |
4052 } | 4052 } |
4053 } | 4053 } |
4054 | 4054 |
4055 | 4055 |
4056 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 4056 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
4057 IterationStatement* stmt) { | 4057 IterationStatement* stmt) { |
4058 if (loop_assignment_analysis_ == NULL) return NULL; | 4058 if (loop_assignment_analysis_ == nullptr) return nullptr; |
4059 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 4059 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); |
4060 } | 4060 } |
4061 | 4061 |
4062 | 4062 |
4063 Node** AstGraphBuilder::EnsureInputBufferSize(int size) { | 4063 Node** AstGraphBuilder::EnsureInputBufferSize(int size) { |
4064 if (size > input_buffer_size_) { | 4064 if (size > input_buffer_size_) { |
4065 size = size + kInputBufferSizeIncrement + input_buffer_size_; | 4065 size = size + kInputBufferSizeIncrement + input_buffer_size_; |
4066 input_buffer_ = local_zone()->NewArray<Node*>(size); | 4066 input_buffer_ = local_zone()->NewArray<Node*>(size); |
4067 input_buffer_size_ = size; | 4067 input_buffer_size_ = size; |
4068 } | 4068 } |
4069 return input_buffer_; | 4069 return input_buffer_; |
4070 } | 4070 } |
4071 | 4071 |
4072 | 4072 |
4073 Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 4073 Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
4074 Node** value_inputs, bool incomplete) { | 4074 Node** value_inputs, bool incomplete) { |
4075 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 4075 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
4076 | 4076 |
4077 bool has_context = OperatorProperties::HasContextInput(op); | 4077 bool has_context = OperatorProperties::HasContextInput(op); |
4078 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); | 4078 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); |
4079 bool has_control = op->ControlInputCount() == 1; | 4079 bool has_control = op->ControlInputCount() == 1; |
4080 bool has_effect = op->EffectInputCount() == 1; | 4080 bool has_effect = op->EffectInputCount() == 1; |
4081 | 4081 |
4082 DCHECK(op->ControlInputCount() < 2); | 4082 DCHECK(op->ControlInputCount() < 2); |
4083 DCHECK(op->EffectInputCount() < 2); | 4083 DCHECK(op->EffectInputCount() < 2); |
4084 | 4084 |
4085 Node* result = NULL; | 4085 Node* result = nullptr; |
4086 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) { | 4086 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) { |
4087 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); | 4087 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); |
4088 } else { | 4088 } else { |
4089 bool inside_try_scope = try_nesting_level_ > 0; | 4089 bool inside_try_scope = try_nesting_level_ > 0; |
4090 int input_count_with_deps = value_input_count; | 4090 int input_count_with_deps = value_input_count; |
4091 if (has_context) ++input_count_with_deps; | 4091 if (has_context) ++input_count_with_deps; |
4092 input_count_with_deps += frame_state_count; | 4092 input_count_with_deps += frame_state_count; |
4093 if (has_control) ++input_count_with_deps; | 4093 if (has_control) ++input_count_with_deps; |
4094 if (has_effect) ++input_count_with_deps; | 4094 if (has_effect) ++input_count_with_deps; |
4095 Node** buffer = EnsureInputBufferSize(input_count_with_deps); | 4095 Node** buffer = EnsureInputBufferSize(input_count_with_deps); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 // Phi does not exist yet, introduce one. | 4357 // Phi does not exist yet, introduce one. |
4358 value = NewPhi(inputs, value, control); | 4358 value = NewPhi(inputs, value, control); |
4359 value->ReplaceInput(inputs - 1, other); | 4359 value->ReplaceInput(inputs - 1, other); |
4360 } | 4360 } |
4361 return value; | 4361 return value; |
4362 } | 4362 } |
4363 | 4363 |
4364 } // namespace compiler | 4364 } // namespace compiler |
4365 } // namespace internal | 4365 } // namespace internal |
4366 } // namespace v8 | 4366 } // namespace v8 |
OLD | NEW |