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