| 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/js-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
| 6 | 6 |
| 7 #include "src/ast/modules.h" | 7 #include "src/ast/modules.h" |
| 8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compilation-dependencies.h" | 10 #include "src/compilation-dependencies.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 return true; | 40 return true; |
| 41 case CompareOperationHint::kNumber: | 41 case CompareOperationHint::kNumber: |
| 42 *hint = NumberOperationHint::kNumber; | 42 *hint = NumberOperationHint::kNumber; |
| 43 return true; | 43 return true; |
| 44 case CompareOperationHint::kNumberOrOddball: | 44 case CompareOperationHint::kNumberOrOddball: |
| 45 *hint = NumberOperationHint::kNumberOrOddball; | 45 *hint = NumberOperationHint::kNumberOrOddball; |
| 46 return true; | 46 return true; |
| 47 case CompareOperationHint::kAny: | 47 case CompareOperationHint::kAny: |
| 48 case CompareOperationHint::kNone: | 48 case CompareOperationHint::kNone: |
| 49 case CompareOperationHint::kString: | 49 case CompareOperationHint::kString: |
| 50 case CompareOperationHint::kSymbol: |
| 50 case CompareOperationHint::kReceiver: | 51 case CompareOperationHint::kReceiver: |
| 51 case CompareOperationHint::kInternalizedString: | 52 case CompareOperationHint::kInternalizedString: |
| 52 break; | 53 break; |
| 53 } | 54 } |
| 54 } | 55 } |
| 55 return false; | 56 return false; |
| 56 } | 57 } |
| 57 | 58 |
| 58 bool IsInternalizedStringCompareOperation() { | 59 bool IsInternalizedStringCompareOperation() { |
| 59 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { | 60 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 78 bool IsStringCompareOperation() { | 79 bool IsStringCompareOperation() { |
| 79 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { | 80 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { |
| 80 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 81 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
| 81 return (CompareOperationHintOf(node_->op()) == | 82 return (CompareOperationHintOf(node_->op()) == |
| 82 CompareOperationHint::kString) && | 83 CompareOperationHint::kString) && |
| 83 BothInputsMaybe(Type::String()); | 84 BothInputsMaybe(Type::String()); |
| 84 } | 85 } |
| 85 return false; | 86 return false; |
| 86 } | 87 } |
| 87 | 88 |
| 89 bool IsSymbolCompareOperation() { |
| 90 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { |
| 91 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
| 92 return (CompareOperationHintOf(node_->op()) == |
| 93 CompareOperationHint::kSymbol) && |
| 94 BothInputsMaybe(Type::Symbol()); |
| 95 } |
| 96 return false; |
| 97 } |
| 98 |
| 88 // Check if a string addition will definitely result in creating a ConsString, | 99 // Check if a string addition will definitely result in creating a ConsString, |
| 89 // i.e. if the combined length of the resulting string exceeds the ConsString | 100 // i.e. if the combined length of the resulting string exceeds the ConsString |
| 90 // minimum length. | 101 // minimum length. |
| 91 bool ShouldCreateConsString() { | 102 bool ShouldCreateConsString() { |
| 92 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); | 103 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); |
| 93 DCHECK(OneInputIs(Type::String())); | 104 DCHECK(OneInputIs(Type::String())); |
| 94 if (BothInputsAre(Type::String()) || | 105 if (BothInputsAre(Type::String()) || |
| 95 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && | 106 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && |
| 96 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { | 107 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { |
| 97 HeapObjectBinopMatcher m(node_); | 108 HeapObjectBinopMatcher m(node_); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 CheckLeftInputToReceiver(); | 141 CheckLeftInputToReceiver(); |
| 131 } | 142 } |
| 132 if (!right_type()->Is(Type::Receiver())) { | 143 if (!right_type()->Is(Type::Receiver())) { |
| 133 Node* right_input = graph()->NewNode(simplified()->CheckReceiver(), | 144 Node* right_input = graph()->NewNode(simplified()->CheckReceiver(), |
| 134 right(), effect(), control()); | 145 right(), effect(), control()); |
| 135 node_->ReplaceInput(1, right_input); | 146 node_->ReplaceInput(1, right_input); |
| 136 update_effect(right_input); | 147 update_effect(right_input); |
| 137 } | 148 } |
| 138 } | 149 } |
| 139 | 150 |
| 151 // Checks that both inputs are Symbol, and if we don't know |
| 152 // statically that one side is already a Symbol, insert a |
| 153 // CheckSymbol node. |
| 154 void CheckInputsToSymbol() { |
| 155 if (!left_type()->Is(Type::Symbol())) { |
| 156 Node* left_input = graph()->NewNode(simplified()->CheckSymbol(), left(), |
| 157 effect(), control()); |
| 158 node_->ReplaceInput(0, left_input); |
| 159 update_effect(left_input); |
| 160 } |
| 161 if (!right_type()->Is(Type::Symbol())) { |
| 162 Node* right_input = graph()->NewNode(simplified()->CheckSymbol(), right(), |
| 163 effect(), control()); |
| 164 node_->ReplaceInput(1, right_input); |
| 165 update_effect(right_input); |
| 166 } |
| 167 } |
| 168 |
| 140 // Checks that both inputs are String, and if we don't know | 169 // Checks that both inputs are String, and if we don't know |
| 141 // statically that one side is already a String, insert a | 170 // statically that one side is already a String, insert a |
| 142 // CheckString node. | 171 // CheckString node. |
| 143 void CheckInputsToString() { | 172 void CheckInputsToString() { |
| 144 if (!left_type()->Is(Type::String())) { | 173 if (!left_type()->Is(Type::String())) { |
| 145 Node* left_input = graph()->NewNode(simplified()->CheckString(), left(), | 174 Node* left_input = graph()->NewNode(simplified()->CheckString(), left(), |
| 146 effect(), control()); | 175 effect(), control()); |
| 147 node_->ReplaceInput(0, left_input); | 176 node_->ReplaceInput(0, left_input); |
| 148 update_effect(left_input); | 177 update_effect(left_input); |
| 149 } | 178 } |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 r.BothInputsAre(Type::Unsigned32())) { | 918 r.BothInputsAre(Type::Unsigned32())) { |
| 890 return r.ChangeToPureOperator(simplified()->NumberEqual()); | 919 return r.ChangeToPureOperator(simplified()->NumberEqual()); |
| 891 } else if (r.BothInputsAre(Type::Number())) { | 920 } else if (r.BothInputsAre(Type::Number())) { |
| 892 return r.ChangeToPureOperator(simplified()->NumberEqual()); | 921 return r.ChangeToPureOperator(simplified()->NumberEqual()); |
| 893 } else if (r.IsReceiverCompareOperation()) { | 922 } else if (r.IsReceiverCompareOperation()) { |
| 894 r.CheckInputsToReceiver(); | 923 r.CheckInputsToReceiver(); |
| 895 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); | 924 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 896 } else if (r.IsStringCompareOperation()) { | 925 } else if (r.IsStringCompareOperation()) { |
| 897 r.CheckInputsToString(); | 926 r.CheckInputsToString(); |
| 898 return r.ChangeToPureOperator(simplified()->StringEqual()); | 927 return r.ChangeToPureOperator(simplified()->StringEqual()); |
| 928 } else if (r.IsSymbolCompareOperation()) { |
| 929 r.CheckInputsToSymbol(); |
| 930 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 899 } | 931 } |
| 900 return NoChange(); | 932 return NoChange(); |
| 901 } | 933 } |
| 902 | 934 |
| 903 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) { | 935 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) { |
| 904 JSBinopReduction r(this, node); | 936 JSBinopReduction r(this, node); |
| 905 if (r.left() == r.right()) { | 937 if (r.left() == r.right()) { |
| 906 // x === x is always true if x != NaN | 938 // x === x is always true if x != NaN |
| 907 Node* replacement = graph()->NewNode( | 939 Node* replacement = graph()->NewNode( |
| 908 simplified()->BooleanNot(), | 940 simplified()->BooleanNot(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 return r.ChangeToPureOperator(simplified()->NumberEqual()); | 978 return r.ChangeToPureOperator(simplified()->NumberEqual()); |
| 947 } else if (r.IsReceiverCompareOperation()) { | 979 } else if (r.IsReceiverCompareOperation()) { |
| 948 // For strict equality, it's enough to know that one input is a Receiver, | 980 // For strict equality, it's enough to know that one input is a Receiver, |
| 949 // as a strict equality comparison with a Receiver can only yield true if | 981 // as a strict equality comparison with a Receiver can only yield true if |
| 950 // both sides refer to the same Receiver than. | 982 // both sides refer to the same Receiver than. |
| 951 r.CheckLeftInputToReceiver(); | 983 r.CheckLeftInputToReceiver(); |
| 952 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); | 984 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 953 } else if (r.IsStringCompareOperation()) { | 985 } else if (r.IsStringCompareOperation()) { |
| 954 r.CheckInputsToString(); | 986 r.CheckInputsToString(); |
| 955 return r.ChangeToPureOperator(simplified()->StringEqual()); | 987 return r.ChangeToPureOperator(simplified()->StringEqual()); |
| 988 } else if (r.IsSymbolCompareOperation()) { |
| 989 r.CheckInputsToSymbol(); |
| 990 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 956 } | 991 } |
| 957 return NoChange(); | 992 return NoChange(); |
| 958 } | 993 } |
| 959 | 994 |
| 960 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 995 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 961 Node* const input = node->InputAt(0); | 996 Node* const input = node->InputAt(0); |
| 962 Type* const input_type = NodeProperties::GetType(input); | 997 Type* const input_type = NodeProperties::GetType(input); |
| 963 if (input_type->Is(Type::Boolean())) { | 998 if (input_type->Is(Type::Boolean())) { |
| 964 // JSToBoolean(x:boolean) => x | 999 // JSToBoolean(x:boolean) => x |
| 965 return Replace(input); | 1000 return Replace(input); |
| (...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 } | 2327 } |
| 2293 | 2328 |
| 2294 | 2329 |
| 2295 CompilationDependencies* JSTypedLowering::dependencies() const { | 2330 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2296 return dependencies_; | 2331 return dependencies_; |
| 2297 } | 2332 } |
| 2298 | 2333 |
| 2299 } // namespace compiler | 2334 } // namespace compiler |
| 2300 } // namespace internal | 2335 } // namespace internal |
| 2301 } // namespace v8 | 2336 } // namespace v8 |
| OLD | NEW |