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 |