| 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 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
| 7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/js-operator.h" | 10 #include "src/compiler/js-operator.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 namespace internal { | 26 namespace internal { |
| 27 namespace compiler { | 27 namespace compiler { |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 const ExternalArrayType kExternalArrayTypes[] = { | 31 const ExternalArrayType kExternalArrayTypes[] = { |
| 32 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, | 32 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, |
| 33 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, | 33 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, |
| 34 kExternalFloat32Array, kExternalFloat64Array}; | 34 kExternalFloat32Array, kExternalFloat64Array}; |
| 35 | 35 |
| 36 | |
| 37 const double kFloat64Values[] = { | |
| 38 -V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212, | |
| 39 -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100, | |
| 40 -1.67813e+72, -2.3382e+55, -3.179e+30, -1.441e+09, -1.0647e+09, | |
| 41 -7.99361e+08, -5.77375e+08, -2.20984e+08, -32757, -13171, -9970, -3984, | |
| 42 -107, -105, -92, -77, -61, -0.000208163, -1.86685e-06, -1.17296e-10, | |
| 43 -9.26358e-11, -5.08004e-60, -1.74753e-65, -1.06561e-71, -5.67879e-79, | |
| 44 -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263, | |
| 45 -4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278, -2.03855e-282, | |
| 46 -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0, 0.0, 2.22507e-308, | |
| 47 1.30127e-270, 7.62898e-260, 4.00313e-249, 3.16829e-233, 1.85244e-228, | |
| 48 2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94, 1.35292e-90, | |
| 49 2.85394e-83, 1.78323e-77, 5.4967e-57, 1.03207e-25, 4.57401e-25, 1.58738e-05, | |
| 50 2, 125, 2310, 9636, 14802, 17168, 28945, 29305, 4.81336e+07, 1.41207e+08, | |
| 51 4.65962e+08, 1.40499e+09, 2.12648e+09, 8.80006e+30, 1.4446e+45, 1.12164e+54, | |
| 52 2.48188e+89, 6.71121e+102, 3.074e+112, 4.9699e+152, 5.58383e+166, | |
| 53 4.30654e+172, 7.08824e+185, 9.6586e+214, 2.028e+223, 6.63277e+243, | |
| 54 1.56192e+261, 1.23202e+269, 5.72883e+289, 8.5798e+290, 1.40256e+294, | |
| 55 1.79769e+308, V8_INFINITY}; | |
| 56 | |
| 57 | |
| 58 const size_t kIndices[] = {0, 1, 42, 100, 1024}; | 36 const size_t kIndices[] = {0, 1, 42, 100, 1024}; |
| 59 | 37 |
| 60 | |
| 61 const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0, -42.0, | |
| 62 -1.0, 0.0, 1.0, 42.0, | |
| 63 1000.0, INT_MAX, UINT_MAX, V8_INFINITY}; | |
| 64 | |
| 65 | |
| 66 Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(), | 38 Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(), |
| 67 Type::Number(), Type::String(), Type::Object()}; | 39 Type::Number(), Type::String(), Type::Object()}; |
| 68 | 40 |
| 69 STATIC_ASSERT(LANGUAGE_END == 2); | 41 STATIC_ASSERT(LANGUAGE_END == 2); |
| 70 const LanguageMode kLanguageModes[] = {SLOPPY, STRICT}; | 42 const LanguageMode kLanguageModes[] = {SLOPPY, STRICT}; |
| 71 | 43 |
| 72 } // namespace | 44 } // namespace |
| 73 | 45 |
| 74 | 46 |
| 75 class JSTypedLoweringTest : public TypedGraphTest { | 47 class JSTypedLoweringTest : public TypedGraphTest { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 105 | 77 |
| 106 JSOperatorBuilder* javascript() { return &javascript_; } | 78 JSOperatorBuilder* javascript() { return &javascript_; } |
| 107 | 79 |
| 108 private: | 80 private: |
| 109 JSOperatorBuilder javascript_; | 81 JSOperatorBuilder javascript_; |
| 110 CompilationDependencies deps_; | 82 CompilationDependencies deps_; |
| 111 }; | 83 }; |
| 112 | 84 |
| 113 | 85 |
| 114 // ----------------------------------------------------------------------------- | 86 // ----------------------------------------------------------------------------- |
| 115 // Constant propagation | |
| 116 | |
| 117 | |
| 118 TEST_F(JSTypedLoweringTest, ParameterWithMinusZero) { | |
| 119 { | |
| 120 Reduction r = Reduce( | |
| 121 Parameter(Type::Constant(factory()->minus_zero_value(), zone()))); | |
| 122 ASSERT_TRUE(r.Changed()); | |
| 123 EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0)); | |
| 124 } | |
| 125 { | |
| 126 Reduction r = Reduce(Parameter(Type::MinusZero())); | |
| 127 ASSERT_TRUE(r.Changed()); | |
| 128 EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0)); | |
| 129 } | |
| 130 { | |
| 131 Reduction r = Reduce(Parameter( | |
| 132 Type::Union(Type::MinusZero(), | |
| 133 Type::Constant(factory()->NewNumber(0), zone()), zone()))); | |
| 134 EXPECT_FALSE(r.Changed()); | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 | |
| 139 TEST_F(JSTypedLoweringTest, ParameterWithNull) { | |
| 140 Handle<HeapObject> null = factory()->null_value(); | |
| 141 { | |
| 142 Reduction r = Reduce(Parameter(Type::Constant(null, zone()))); | |
| 143 ASSERT_TRUE(r.Changed()); | |
| 144 EXPECT_THAT(r.replacement(), IsHeapConstant(null)); | |
| 145 } | |
| 146 { | |
| 147 Reduction r = Reduce(Parameter(Type::Null())); | |
| 148 ASSERT_TRUE(r.Changed()); | |
| 149 EXPECT_THAT(r.replacement(), IsHeapConstant(null)); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 | |
| 154 TEST_F(JSTypedLoweringTest, ParameterWithNaN) { | |
| 155 const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(), | |
| 156 std::numeric_limits<double>::quiet_NaN(), | |
| 157 std::numeric_limits<double>::signaling_NaN()}; | |
| 158 TRACED_FOREACH(double, nan, kNaNs) { | |
| 159 Handle<Object> constant = factory()->NewNumber(nan); | |
| 160 Reduction r = Reduce(Parameter(Type::Constant(constant, zone()))); | |
| 161 ASSERT_TRUE(r.Changed()); | |
| 162 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN())); | |
| 163 } | |
| 164 { | |
| 165 Reduction r = | |
| 166 Reduce(Parameter(Type::Constant(factory()->nan_value(), zone()))); | |
| 167 ASSERT_TRUE(r.Changed()); | |
| 168 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN())); | |
| 169 } | |
| 170 { | |
| 171 Reduction r = Reduce(Parameter(Type::NaN())); | |
| 172 ASSERT_TRUE(r.Changed()); | |
| 173 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN())); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 | |
| 178 TEST_F(JSTypedLoweringTest, ParameterWithPlainNumber) { | |
| 179 TRACED_FOREACH(double, value, kFloat64Values) { | |
| 180 Handle<Object> constant = factory()->NewNumber(value); | |
| 181 Reduction r = Reduce(Parameter(Type::Constant(constant, zone()))); | |
| 182 ASSERT_TRUE(r.Changed()); | |
| 183 EXPECT_THAT(r.replacement(), IsNumberConstant(value)); | |
| 184 } | |
| 185 TRACED_FOREACH(double, value, kIntegerValues) { | |
| 186 Reduction r = Reduce(Parameter(Type::Range(value, value, zone()))); | |
| 187 ASSERT_TRUE(r.Changed()); | |
| 188 EXPECT_THAT(r.replacement(), IsNumberConstant(value)); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 | |
| 193 TEST_F(JSTypedLoweringTest, ParameterWithUndefined) { | |
| 194 Handle<HeapObject> undefined = factory()->undefined_value(); | |
| 195 { | |
| 196 Reduction r = Reduce(Parameter(Type::Undefined())); | |
| 197 ASSERT_TRUE(r.Changed()); | |
| 198 EXPECT_THAT(r.replacement(), IsHeapConstant(undefined)); | |
| 199 } | |
| 200 { | |
| 201 Reduction r = Reduce(Parameter(Type::Constant(undefined, zone()))); | |
| 202 ASSERT_TRUE(r.Changed()); | |
| 203 EXPECT_THAT(r.replacement(), IsHeapConstant(undefined)); | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 | |
| 208 // ----------------------------------------------------------------------------- | |
| 209 // JSToBoolean | 87 // JSToBoolean |
| 210 | 88 |
| 211 | 89 |
| 212 TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) { | 90 TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) { |
| 213 Node* input = Parameter(Type::Boolean(), 0); | 91 Node* input = Parameter(Type::Boolean(), 0); |
| 214 Node* context = Parameter(Type::Any(), 1); | 92 Node* context = Parameter(Type::Any(), 1); |
| 215 Reduction r = Reduce(graph()->NewNode( | 93 Reduction r = Reduce(graph()->NewNode( |
| 216 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); | 94 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); |
| 217 ASSERT_TRUE(r.Changed()); | 95 ASSERT_TRUE(r.Changed()); |
| 218 EXPECT_EQ(input, r.replacement()); | 96 EXPECT_EQ(input, r.replacement()); |
| 219 } | 97 } |
| 220 | 98 |
| 221 | 99 |
| 222 TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) { | |
| 223 Node* input = Parameter( | |
| 224 Type::Union( | |
| 225 Type::MinusZero(), | |
| 226 Type::Union( | |
| 227 Type::NaN(), | |
| 228 Type::Union( | |
| 229 Type::Null(), | |
| 230 Type::Union( | |
| 231 Type::Undefined(), | |
| 232 Type::Union( | |
| 233 Type::Undetectable(), | |
| 234 Type::Union( | |
| 235 Type::Constant(factory()->false_value(), zone()), | |
| 236 Type::Range(0.0, 0.0, zone()), zone()), | |
| 237 zone()), | |
| 238 zone()), | |
| 239 zone()), | |
| 240 zone()), | |
| 241 zone()), | |
| 242 0); | |
| 243 Node* context = Parameter(Type::Any(), 1); | |
| 244 Reduction r = Reduce(graph()->NewNode( | |
| 245 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); | |
| 246 ASSERT_TRUE(r.Changed()); | |
| 247 EXPECT_THAT(r.replacement(), IsFalseConstant()); | |
| 248 } | |
| 249 | |
| 250 | |
| 251 TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) { | |
| 252 Node* input = Parameter( | |
| 253 Type::Union( | |
| 254 Type::Constant(factory()->true_value(), zone()), | |
| 255 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()), | |
| 256 zone()), | |
| 257 0); | |
| 258 Node* context = Parameter(Type::Any(), 1); | |
| 259 Reduction r = Reduce(graph()->NewNode( | |
| 260 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); | |
| 261 ASSERT_TRUE(r.Changed()); | |
| 262 EXPECT_THAT(r.replacement(), IsTrueConstant()); | |
| 263 } | |
| 264 | |
| 265 | |
| 266 TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) { | |
| 267 Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0); | |
| 268 Node* context = Parameter(Type::Any(), 1); | |
| 269 Reduction r = Reduce(graph()->NewNode( | |
| 270 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); | |
| 271 ASSERT_TRUE(r.Changed()); | |
| 272 EXPECT_THAT(r.replacement(), IsTrueConstant()); | |
| 273 } | |
| 274 | |
| 275 | |
| 276 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { | 100 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { |
| 277 Node* input = Parameter(Type::OrderedNumber(), 0); | 101 Node* input = Parameter(Type::OrderedNumber(), 0); |
| 278 Node* context = Parameter(Type::Any(), 1); | 102 Node* context = Parameter(Type::Any(), 1); |
| 279 Reduction r = Reduce(graph()->NewNode( | 103 Reduction r = Reduce(graph()->NewNode( |
| 280 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); | 104 javascript()->ToBoolean(ToBooleanHint::kAny), input, context)); |
| 281 ASSERT_TRUE(r.Changed()); | 105 ASSERT_TRUE(r.Changed()); |
| 282 EXPECT_THAT(r.replacement(), | 106 EXPECT_THAT(r.replacement(), |
| 283 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0.0)))); | 107 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0.0)))); |
| 284 } | 108 } |
| 285 | 109 |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 EmptyFrameState(), effect, control)); | 1022 EmptyFrameState(), effect, control)); |
| 1199 ASSERT_TRUE(r.Changed()); | 1023 ASSERT_TRUE(r.Changed()); |
| 1200 EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseXor( | 1024 EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseXor( |
| 1201 NumberOperationHint::kNumberOrOddball, lhs, | 1025 NumberOperationHint::kNumberOrOddball, lhs, |
| 1202 rhs, effect, control)); | 1026 rhs, effect, control)); |
| 1203 } | 1027 } |
| 1204 | 1028 |
| 1205 } // namespace compiler | 1029 } // namespace compiler |
| 1206 } // namespace internal | 1030 } // namespace internal |
| 1207 } // namespace v8 | 1031 } // namespace v8 |
| OLD | NEW |