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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 : AstContext(owner, Expression::kValue) {} | 87 : AstContext(owner, Expression::kValue) {} |
88 ~AstValueContext() final; | 88 ~AstValueContext() final; |
89 void ProduceValue(Node* value) final; | 89 void ProduceValue(Node* value) final; |
90 Node* ConsumeValue() final; | 90 Node* ConsumeValue() final; |
91 }; | 91 }; |
92 | 92 |
93 | 93 |
94 // Context to evaluate expression for a condition value (and side effects). | 94 // Context to evaluate expression for a condition value (and side effects). |
95 class AstGraphBuilder::AstTestContext final : public AstContext { | 95 class AstGraphBuilder::AstTestContext final : public AstContext { |
96 public: | 96 public: |
97 explicit AstTestContext(AstGraphBuilder* owner) | 97 AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) |
98 : AstContext(owner, Expression::kTest) {} | 98 : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} |
99 ~AstTestContext() final; | 99 ~AstTestContext() final; |
100 void ProduceValue(Node* value) final; | 100 void ProduceValue(Node* value) final; |
101 Node* ConsumeValue() final; | 101 Node* ConsumeValue() final; |
| 102 |
| 103 private: |
| 104 TypeFeedbackId const feedback_id_; |
102 }; | 105 }; |
103 | 106 |
104 | 107 |
105 // Scoped class tracking context objects created by the visitor. Represents | 108 // Scoped class tracking context objects created by the visitor. Represents |
106 // mutations of the context chain within the function body and allows to | 109 // mutations of the context chain within the function body and allows to |
107 // change the current {scope} and {context} during visitation. | 110 // change the current {scope} and {context} during visitation. |
108 class AstGraphBuilder::ContextScope BASE_EMBEDDED { | 111 class AstGraphBuilder::ContextScope BASE_EMBEDDED { |
109 public: | 112 public: |
110 ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context) | 113 ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context) |
111 : builder_(builder), | 114 : builder_(builder), |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 // The value is ignored. | 923 // The value is ignored. |
921 } | 924 } |
922 | 925 |
923 | 926 |
924 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | 927 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
925 environment()->Push(value); | 928 environment()->Push(value); |
926 } | 929 } |
927 | 930 |
928 | 931 |
929 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { | 932 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) { |
930 environment()->Push(owner()->BuildToBoolean(value)); | 933 environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); |
931 } | 934 } |
932 | 935 |
933 | 936 |
934 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; } | 937 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; } |
935 | 938 |
936 | 939 |
937 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { | 940 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { |
938 return environment()->Pop(); | 941 return environment()->Pop(); |
939 } | 942 } |
940 | 943 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 AstEffectContext for_effect(this); | 1030 AstEffectContext for_effect(this); |
1028 if (!CheckStackOverflow()) { | 1031 if (!CheckStackOverflow()) { |
1029 expr->Accept(this); | 1032 expr->Accept(this); |
1030 } else { | 1033 } else { |
1031 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1034 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1032 } | 1035 } |
1033 } | 1036 } |
1034 | 1037 |
1035 | 1038 |
1036 void AstGraphBuilder::VisitForTest(Expression* expr) { | 1039 void AstGraphBuilder::VisitForTest(Expression* expr) { |
1037 AstTestContext for_condition(this); | 1040 AstTestContext for_condition(this, expr->test_id()); |
1038 if (!CheckStackOverflow()) { | 1041 if (!CheckStackOverflow()) { |
1039 expr->Accept(this); | 1042 expr->Accept(this); |
1040 } else { | 1043 } else { |
1041 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1044 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
1042 } | 1045 } |
1043 } | 1046 } |
1044 | 1047 |
1045 | 1048 |
1046 void AstGraphBuilder::Visit(Expression* expr) { | 1049 void AstGraphBuilder::Visit(Expression* expr) { |
1047 // Reuses enclosing AstContext. | 1050 // Reuses enclosing AstContext. |
(...skipping 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 operand = environment()->Pop(); | 3007 operand = environment()->Pop(); |
3005 } | 3008 } |
3006 Node* value = NewNode(javascript()->TypeOf(), operand); | 3009 Node* value = NewNode(javascript()->TypeOf(), operand); |
3007 ast_context()->ProduceValue(value); | 3010 ast_context()->ProduceValue(value); |
3008 } | 3011 } |
3009 | 3012 |
3010 | 3013 |
3011 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 3014 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
3012 VisitForValue(expr->expression()); | 3015 VisitForValue(expr->expression()); |
3013 Node* operand = environment()->Pop(); | 3016 Node* operand = environment()->Pop(); |
3014 Node* input = BuildToBoolean(operand); | 3017 Node* input = BuildToBoolean(operand, expr->expression()->test_id()); |
3015 Node* value = NewNode(common()->Select(kMachAnyTagged), input, | 3018 Node* value = NewNode(common()->Select(kMachAnyTagged), input, |
3016 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); | 3019 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); |
3017 ast_context()->ProduceValue(value); | 3020 ast_context()->ProduceValue(value); |
3018 } | 3021 } |
3019 | 3022 |
3020 | 3023 |
3021 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { | 3024 void AstGraphBuilder::VisitComma(BinaryOperation* expr) { |
3022 VisitForEffect(expr->left()); | 3025 VisitForEffect(expr->left()); |
3023 Visit(expr->right()); | 3026 Visit(expr->right()); |
3024 ast_context()->ReplaceValue(); | 3027 ast_context()->ReplaceValue(); |
3025 } | 3028 } |
3026 | 3029 |
3027 | 3030 |
3028 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { | 3031 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { |
3029 bool is_logical_and = expr->op() == Token::AND; | 3032 bool is_logical_and = expr->op() == Token::AND; |
3030 IfBuilder compare_if(this); | 3033 IfBuilder compare_if(this); |
3031 VisitForValue(expr->left()); | 3034 VisitForValue(expr->left()); |
3032 Node* condition = environment()->Top(); | 3035 Node* condition = environment()->Top(); |
3033 compare_if.If(BuildToBoolean(condition)); | 3036 compare_if.If(BuildToBoolean(condition, expr->left()->test_id())); |
3034 compare_if.Then(); | 3037 compare_if.Then(); |
3035 if (is_logical_and) { | 3038 if (is_logical_and) { |
3036 environment()->Pop(); | 3039 environment()->Pop(); |
3037 Visit(expr->right()); | 3040 Visit(expr->right()); |
3038 } else if (ast_context()->IsEffect()) { | 3041 } else if (ast_context()->IsEffect()) { |
3039 environment()->Pop(); | 3042 environment()->Pop(); |
3040 } else if (ast_context()->IsTest()) { | 3043 } else if (ast_context()->IsTest()) { |
3041 environment()->Poke(0, jsgraph()->TrueConstant()); | 3044 environment()->Poke(0, jsgraph()->TrueConstant()); |
3042 } | 3045 } |
3043 compare_if.Else(); | 3046 compare_if.Else(); |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3675 Node* shared = BuildLoadImmutableObjectField( | 3678 Node* shared = BuildLoadImmutableObjectField( |
3676 closure, JSFunction::kSharedFunctionInfoOffset); | 3679 closure, JSFunction::kSharedFunctionInfoOffset); |
3677 Node* vector = BuildLoadImmutableObjectField( | 3680 Node* vector = BuildLoadImmutableObjectField( |
3678 shared, SharedFunctionInfo::kFeedbackVectorOffset); | 3681 shared, SharedFunctionInfo::kFeedbackVectorOffset); |
3679 feedback_vector_.set(vector); | 3682 feedback_vector_.set(vector); |
3680 } | 3683 } |
3681 return feedback_vector_.get(); | 3684 return feedback_vector_.get(); |
3682 } | 3685 } |
3683 | 3686 |
3684 | 3687 |
3685 Node* AstGraphBuilder::BuildToBoolean(Node* input) { | 3688 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) { |
3686 if (Node* node = TryFastToBoolean(input)) return node; | 3689 if (Node* node = TryFastToBoolean(input)) return node; |
3687 return NewNode(javascript()->ToBoolean(), input); | 3690 ToBooleanHints hints; |
| 3691 if (!type_hint_analysis_ || |
| 3692 !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) { |
| 3693 hints = ToBooleanHint::kAny; |
| 3694 } |
| 3695 return NewNode(javascript()->ToBoolean(hints), input); |
3688 } | 3696 } |
3689 | 3697 |
3690 | 3698 |
3691 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { | 3699 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { |
3692 if (Node* node = TryFastToName(input)) return node; | 3700 if (Node* node = TryFastToName(input)) return node; |
3693 Node* name = NewNode(javascript()->ToName(), input); | 3701 Node* name = NewNode(javascript()->ToName(), input); |
3694 PrepareFrameState(name, bailout_id); | 3702 PrepareFrameState(name, bailout_id); |
3695 return name; | 3703 return name; |
3696 } | 3704 } |
3697 | 3705 |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4317 // Phi does not exist yet, introduce one. | 4325 // Phi does not exist yet, introduce one. |
4318 value = NewPhi(inputs, value, control); | 4326 value = NewPhi(inputs, value, control); |
4319 value->ReplaceInput(inputs - 1, other); | 4327 value->ReplaceInput(inputs - 1, other); |
4320 } | 4328 } |
4321 return value; | 4329 return value; |
4322 } | 4330 } |
4323 | 4331 |
4324 } // namespace compiler | 4332 } // namespace compiler |
4325 } // namespace internal | 4333 } // namespace internal |
4326 } // namespace v8 | 4334 } // namespace v8 |
OLD | NEW |