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/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
11 #include "src/compiler/simplified-operator.h" | 11 #include "src/compiler/simplified-operator.h" |
12 #include "src/compiler/typer.h" | 12 #include "src/compiler/typer.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 class Typer::Decorator : public GraphDecorator { | 18 class Typer::Decorator : public GraphDecorator { |
19 public: | 19 public: |
20 explicit Decorator(Typer* typer) : typer_(typer) {} | 20 explicit Decorator(Typer* typer) : typer_(typer) {} |
21 virtual void Decorate(Node* node); | 21 virtual void Decorate(Node* node); |
22 | 22 |
23 private: | 23 private: |
24 Typer* typer_; | 24 Typer* typer_; |
25 }; | 25 }; |
26 | 26 |
27 | 27 |
28 Typer::Typer(Graph* graph, MaybeHandle<Context> context) | 28 Typer::Typer(Graph* graph, MaybeHandle<Context> context) |
29 : graph_(graph), context_(context), decorator_(NULL) { | 29 : graph_(graph), |
30 context_(context), | |
31 decorator_(NULL), | |
32 weaken_min_limits_(graph->zone()), | |
33 weaken_max_limits_(graph->zone()) { | |
30 Zone* zone = this->zone(); | 34 Zone* zone = this->zone(); |
31 Factory* f = zone->isolate()->factory(); | 35 Factory* f = zone->isolate()->factory(); |
32 | 36 |
33 Handle<Object> zero = f->NewNumber(0); | 37 Handle<Object> zero = f->NewNumber(0); |
34 Handle<Object> one = f->NewNumber(1); | 38 Handle<Object> one = f->NewNumber(1); |
35 Handle<Object> positive_infinity = f->NewNumber(+V8_INFINITY); | 39 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); |
36 Handle<Object> negative_infinity = f->NewNumber(-V8_INFINITY); | 40 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); |
37 | 41 |
38 negative_signed32 = Type::Union( | 42 negative_signed32 = Type::Union( |
39 Type::SignedSmall(), Type::OtherSigned32(), zone); | 43 Type::SignedSmall(), Type::OtherSigned32(), zone); |
40 non_negative_signed32 = Type::Union( | 44 non_negative_signed32 = Type::Union( |
41 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); | 45 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); |
42 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); | 46 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); |
43 singleton_false = Type::Constant(f->false_value(), zone); | 47 singleton_false = Type::Constant(f->false_value(), zone); |
44 singleton_true = Type::Constant(f->true_value(), zone); | 48 singleton_true = Type::Constant(f->true_value(), zone); |
45 singleton_zero = Type::Range(zero, zero, zone); | 49 singleton_zero = Type::Range(zero, zero, zone); |
46 singleton_one = Type::Range(one, one, zone); | 50 singleton_one = Type::Range(one, one, zone); |
47 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); | 51 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); |
48 zeroish = Type::Union( | 52 zeroish = Type::Union( |
49 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); | 53 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); |
50 falsish = Type::Union(Type::Undetectable(), | 54 falsish = Type::Union(Type::Undetectable(), |
51 Type::Union(zeroish, undefined_or_null, zone), zone); | 55 Type::Union(zeroish, undefined_or_null, zone), zone); |
52 integer = Type::Range(negative_infinity, positive_infinity, zone); | 56 integer = Type::Range(minusinfinity, infinity, zone); |
57 weakint = Type::Union( | |
58 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); | |
53 | 59 |
54 Type* number = Type::Number(); | 60 Type* number = Type::Number(); |
55 Type* signed32 = Type::Signed32(); | 61 Type* signed32 = Type::Signed32(); |
56 Type* unsigned32 = Type::Unsigned32(); | 62 Type* unsigned32 = Type::Unsigned32(); |
57 Type* integral32 = Type::Integral32(); | 63 Type* integral32 = Type::Integral32(); |
58 Type* object = Type::Object(); | 64 Type* object = Type::Object(); |
59 Type* undefined = Type::Undefined(); | 65 Type* undefined = Type::Undefined(); |
60 Type* weakint = Type::Union( | |
61 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); | |
62 | 66 |
63 number_fun0_ = Type::Function(number, zone); | 67 number_fun0_ = Type::Function(number, zone); |
64 number_fun1_ = Type::Function(number, number, zone); | 68 number_fun1_ = Type::Function(number, number, zone); |
65 number_fun2_ = Type::Function(number, number, number, zone); | 69 number_fun2_ = Type::Function(number, number, number, zone); |
66 weakint_fun1_ = Type::Function(weakint, number, zone); | 70 weakint_fun1_ = Type::Function(weakint, number, zone); |
67 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); | 71 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); |
68 clz32_fun_ = Type::Function( | 72 clz32_fun_ = Type::Function( |
69 Type::Range(zero, f->NewNumber(32), zone), number, zone); | 73 Type::Range(zero, f->NewNumber(32), zone), number, zone); |
70 random_fun_ = Type::Function(Type::Union( | 74 random_fun_ = Type::Function(Type::Union( |
71 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); | 75 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 array_buffer_fun_ = Type::Function(buffer, unsigned32, zone); | 110 array_buffer_fun_ = Type::Function(buffer, unsigned32, zone); |
107 int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone); | 111 int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone); |
108 int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone); | 112 int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone); |
109 int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone); | 113 int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone); |
110 uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone); | 114 uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone); |
111 uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone); | 115 uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone); |
112 uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone); | 116 uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone); |
113 float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone); | 117 float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone); |
114 float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone); | 118 float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone); |
115 | 119 |
120 const int limits_count = 20; | |
121 | |
122 weaken_min_limits_.reserve(limits_count + 1); | |
123 weaken_max_limits_.reserve(limits_count + 1); | |
124 | |
125 double limit = 1 << 30; | |
126 weaken_min_limits_.push_back(f->NewNumber(0)); | |
127 weaken_max_limits_.push_back(f->NewNumber(0)); | |
128 for (int i = 0; i < limits_count; i++) { | |
129 weaken_min_limits_.push_back(f->NewNumber(-limit)); | |
130 weaken_max_limits_.push_back(f->NewNumber(limit - 1)); | |
131 limit *= 2; | |
132 } | |
133 | |
116 decorator_ = new (zone) Decorator(this); | 134 decorator_ = new (zone) Decorator(this); |
117 graph_->AddDecorator(decorator_); | 135 graph_->AddDecorator(decorator_); |
118 } | 136 } |
119 | 137 |
120 | 138 |
121 Typer::~Typer() { | 139 Typer::~Typer() { |
122 graph_->RemoveDecorator(decorator_); | 140 graph_->RemoveDecorator(decorator_); |
123 } | 141 } |
124 | 142 |
125 | 143 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 | 176 |
159 Type* TypeConstant(Handle<Object> value); | 177 Type* TypeConstant(Handle<Object> value); |
160 | 178 |
161 protected: | 179 protected: |
162 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); | 180 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); |
163 DECLARE_METHOD(Start) | 181 DECLARE_METHOD(Start) |
164 VALUE_OP_LIST(DECLARE_METHOD) | 182 VALUE_OP_LIST(DECLARE_METHOD) |
165 #undef DECLARE_METHOD | 183 #undef DECLARE_METHOD |
166 | 184 |
167 Bounds BoundsOrNone(Node* node) { | 185 Bounds BoundsOrNone(Node* node) { |
168 return NodeProperties::IsTyped(node) | 186 return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node) |
169 ? NodeProperties::GetBounds(node) : Bounds(Type::None(zone())); | 187 : Bounds(Type::None()); |
170 } | 188 } |
171 | 189 |
172 Bounds Operand(Node* node, int i) { | 190 Bounds Operand(Node* node, int i) { |
173 Node* operand_node = NodeProperties::GetValueInput(node, i); | 191 Node* operand_node = NodeProperties::GetValueInput(node, i); |
174 return BoundsOrNone(operand_node); | 192 return BoundsOrNone(operand_node); |
175 } | 193 } |
176 | 194 |
177 Bounds ContextOperand(Node* node) { | 195 Bounds ContextOperand(Node* node) { |
178 Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node)); | 196 Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node)); |
179 DCHECK(result.upper->Maybe(Type::Internal())); | 197 DCHECK(result.upper->Maybe(Type::Internal())); |
180 // TODO(rossberg): More precisely, instead of the above assertion, we should | 198 // TODO(rossberg): More precisely, instead of the above assertion, we should |
181 // back-propagate the constraint that it has to be a subtype of Internal. | 199 // back-propagate the constraint that it has to be a subtype of Internal. |
182 return result; | 200 return result; |
183 } | 201 } |
184 | 202 |
203 Type* MaybeWeaken(Type* current, Type* previous); | |
204 | |
185 Zone* zone() { return typer_->zone(); } | 205 Zone* zone() { return typer_->zone(); } |
186 Isolate* isolate() { return typer_->isolate(); } | 206 Isolate* isolate() { return typer_->isolate(); } |
187 Graph* graph() { return typer_->graph(); } | 207 Graph* graph() { return typer_->graph(); } |
188 MaybeHandle<Context> context() { return typer_->context(); } | 208 MaybeHandle<Context> context() { return typer_->context(); } |
189 | 209 |
190 private: | 210 private: |
191 Typer* typer_; | 211 Typer* typer_; |
192 MaybeHandle<Context> context_; | 212 MaybeHandle<Context> context_; |
193 | 213 |
194 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); | 214 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); |
195 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); | 215 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); |
196 | 216 |
197 Bounds TypeUnaryOp(Node* node, UnaryTyperFun); | 217 Bounds TypeUnaryOp(Node* node, UnaryTyperFun); |
198 Bounds TypeBinaryOp(Node* node, BinaryTyperFun); | 218 Bounds TypeBinaryOp(Node* node, BinaryTyperFun); |
199 | 219 |
220 Type* Weaken(Type::RangeType* previous, Type::RangeType* current); | |
221 | |
200 static Type* Invert(Type*, Typer*); | 222 static Type* Invert(Type*, Typer*); |
201 static Type* FalsifyUndefined(Type*, Typer*); | 223 static Type* FalsifyUndefined(Type*, Typer*); |
224 static Type* Rangify(Type*, Typer*); | |
202 | 225 |
203 static Type* ToPrimitive(Type*, Typer*); | 226 static Type* ToPrimitive(Type*, Typer*); |
204 static Type* ToBoolean(Type*, Typer*); | 227 static Type* ToBoolean(Type*, Typer*); |
205 static Type* ToNumber(Type*, Typer*); | 228 static Type* ToNumber(Type*, Typer*); |
206 static Type* ToString(Type*, Typer*); | 229 static Type* ToString(Type*, Typer*); |
207 static Type* NumberToInt32(Type*, Typer*); | 230 static Type* NumberToInt32(Type*, Typer*); |
208 static Type* NumberToUint32(Type*, Typer*); | 231 static Type* NumberToUint32(Type*, Typer*); |
209 | 232 |
210 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); | 233 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); |
211 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); | 234 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 }; | 268 }; |
246 | 269 |
247 | 270 |
248 class Typer::NarrowVisitor : public Typer::Visitor { | 271 class Typer::NarrowVisitor : public Typer::Visitor { |
249 public: | 272 public: |
250 explicit NarrowVisitor(Typer* typer) : Visitor(typer) {} | 273 explicit NarrowVisitor(Typer* typer) : Visitor(typer) {} |
251 | 274 |
252 GenericGraphVisit::Control Pre(Node* node) { | 275 GenericGraphVisit::Control Pre(Node* node) { |
253 if (OperatorProperties::HasValueOutput(node->op())) { | 276 if (OperatorProperties::HasValueOutput(node->op())) { |
254 Bounds previous = NodeProperties::GetBounds(node); | 277 Bounds previous = NodeProperties::GetBounds(node); |
255 Bounds bounds = TypeNode(node); | 278 Bounds current = TypeNode(node); |
256 NodeProperties::SetBounds(node, Bounds::Both(bounds, previous, zone())); | 279 NodeProperties::SetBounds(node, Bounds::Both(current, previous, zone())); |
257 DCHECK(bounds.Narrows(previous)); | 280 DCHECK(current.Narrows(previous)); |
258 // Stop when nothing changed (but allow re-entry in case it does later). | 281 // Stop when nothing changed (but allow re-entry in case it does later). |
259 return previous.Narrows(bounds) | 282 return previous.Narrows(current) ? GenericGraphVisit::DEFER |
260 ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; | 283 : GenericGraphVisit::REENTER; |
261 } else { | 284 } else { |
262 return GenericGraphVisit::SKIP; | 285 return GenericGraphVisit::SKIP; |
263 } | 286 } |
264 } | 287 } |
265 | 288 |
266 GenericGraphVisit::Control Post(Node* node) { | 289 GenericGraphVisit::Control Post(Node* node) { |
267 return GenericGraphVisit::REENTER; | 290 return GenericGraphVisit::REENTER; |
268 } | 291 } |
269 }; | 292 }; |
270 | 293 |
271 | 294 |
272 class Typer::WidenVisitor : public Typer::Visitor { | 295 class Typer::WidenVisitor : public Typer::Visitor { |
273 public: | 296 public: |
274 explicit WidenVisitor(Typer* typer) : Visitor(typer) {} | 297 explicit WidenVisitor(Typer* typer) : Visitor(typer) {} |
275 | 298 |
276 GenericGraphVisit::Control Pre(Node* node) { | 299 GenericGraphVisit::Control Pre(Node* node) { |
277 if (OperatorProperties::HasValueOutput(node->op())) { | 300 if (OperatorProperties::HasValueOutput(node->op())) { |
278 Bounds previous = BoundsOrNone(node); | 301 Bounds previous = BoundsOrNone(node); |
279 Bounds bounds = TypeNode(node); | 302 Bounds current = TypeNode(node); |
280 DCHECK(previous.lower->Is(bounds.lower)); | 303 |
281 DCHECK(previous.upper->Is(bounds.upper)); | 304 // Speed up termination in the presence of range types: |
282 NodeProperties::SetBounds(node, bounds); | 305 current.upper = MaybeWeaken(current.upper, previous.upper); |
306 current.lower = MaybeWeaken(current.lower, previous.lower); | |
307 | |
308 DCHECK(previous.lower->Is(current.lower)); | |
309 DCHECK(previous.upper->Is(current.upper)); | |
310 | |
311 NodeProperties::SetBounds(node, current); | |
283 // Stop when nothing changed (but allow re-entry in case it does later). | 312 // Stop when nothing changed (but allow re-entry in case it does later). |
284 return bounds.Narrows(previous) | 313 return previous.Narrows(current) && current.Narrows(previous) |
285 ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; | 314 ? GenericGraphVisit::DEFER |
315 : GenericGraphVisit::REENTER; | |
286 } else { | 316 } else { |
287 return GenericGraphVisit::SKIP; | 317 return GenericGraphVisit::SKIP; |
288 } | 318 } |
289 } | 319 } |
290 | 320 |
291 GenericGraphVisit::Control Post(Node* node) { | 321 GenericGraphVisit::Control Post(Node* node) { |
292 return GenericGraphVisit::REENTER; | 322 return GenericGraphVisit::REENTER; |
293 } | 323 } |
294 }; | 324 }; |
295 | 325 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 return type; | 404 return type; |
375 } | 405 } |
376 | 406 |
377 | 407 |
378 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) { | 408 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) { |
379 if (type->Is(Type::Undefined())) return t->singleton_false; | 409 if (type->Is(Type::Undefined())) return t->singleton_false; |
380 return type; | 410 return type; |
381 } | 411 } |
382 | 412 |
383 | 413 |
414 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { | |
415 if (type->IsRange()) return type; // Shortcut. | |
416 if (!type->Is(t->integer)) return type; // Give up. | |
417 Factory* f = t->isolate()->factory(); | |
418 return Type::Range(f->NewNumber(type->Min()), f->NewNumber(type->Max()), | |
419 t->zone()); | |
420 } | |
421 | |
422 | |
384 // Type conversion. | 423 // Type conversion. |
385 | 424 |
386 | 425 |
387 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { | 426 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { |
388 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { | 427 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { |
389 return type; | 428 return type; |
390 } | 429 } |
391 return Type::Primitive(); | 430 return Type::Primitive(); |
392 } | 431 } |
393 | 432 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 | 487 |
449 // Common operators. | 488 // Common operators. |
450 | 489 |
451 | 490 |
452 Bounds Typer::Visitor::TypeParameter(Node* node) { | 491 Bounds Typer::Visitor::TypeParameter(Node* node) { |
453 return Bounds::Unbounded(zone()); | 492 return Bounds::Unbounded(zone()); |
454 } | 493 } |
455 | 494 |
456 | 495 |
457 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { | 496 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { |
458 Factory* f = zone()->isolate()->factory(); | 497 Factory* f = isolate()->factory(); |
459 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); | 498 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); |
460 return Bounds(Type::Intersect( | 499 return Bounds(Type::Intersect( |
461 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone())); | 500 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone())); |
462 } | 501 } |
463 | 502 |
464 | 503 |
465 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { | 504 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { |
466 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? | 505 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? |
467 } | 506 } |
468 | 507 |
469 | 508 |
470 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { | 509 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { |
471 return Bounds(Type::Intersect( | 510 return Bounds(Type::Intersect( |
472 Type::Of(OpParameter<float>(node), zone()), | 511 Type::Of(OpParameter<float>(node), zone()), |
473 Type::UntaggedFloat32(), zone())); | 512 Type::UntaggedFloat32(), zone())); |
474 } | 513 } |
475 | 514 |
476 | 515 |
477 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { | 516 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { |
478 return Bounds(Type::Intersect( | 517 return Bounds(Type::Intersect( |
479 Type::Of(OpParameter<double>(node), zone()), | 518 Type::Of(OpParameter<double>(node), zone()), |
480 Type::UntaggedFloat64(), zone())); | 519 Type::UntaggedFloat64(), zone())); |
481 } | 520 } |
482 | 521 |
483 | 522 |
484 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { | 523 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { |
485 Factory* f = zone()->isolate()->factory(); | 524 Factory* f = isolate()->factory(); |
486 return Bounds(Type::Constant( | 525 return Bounds(Type::Constant( |
487 f->NewNumber(OpParameter<double>(node)), zone())); | 526 f->NewNumber(OpParameter<double>(node)), zone())); |
488 } | 527 } |
489 | 528 |
490 | 529 |
491 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { | 530 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { |
492 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); | 531 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); |
493 } | 532 } |
494 | 533 |
495 | 534 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( | 691 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( |
653 Type* lhs, Type* rhs, Typer* t) { | 692 Type* lhs, Type* rhs, Typer* t) { |
654 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); | 693 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); |
655 } | 694 } |
656 | 695 |
657 | 696 |
658 // JS bitwise operators. | 697 // JS bitwise operators. |
659 | 698 |
660 | 699 |
661 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 700 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
662 Factory* f = t->zone()->isolate()->factory(); | 701 Factory* f = t->isolate()->factory(); |
663 lhs = NumberToInt32(ToNumber(lhs, t), t); | 702 lhs = NumberToInt32(ToNumber(lhs, t), t); |
664 rhs = NumberToInt32(ToNumber(rhs, t), t); | 703 rhs = NumberToInt32(ToNumber(rhs, t), t); |
665 double lmin = lhs->Min(); | 704 double lmin = lhs->Min(); |
666 double rmin = rhs->Min(); | 705 double rmin = rhs->Min(); |
667 double lmax = lhs->Max(); | 706 double lmax = lhs->Max(); |
668 double rmax = rhs->Max(); | 707 double rmax = rhs->Max(); |
669 // Or-ing any two values results in a value no smaller than their minimum. | 708 // Or-ing any two values results in a value no smaller than their minimum. |
670 // Even no smaller than their maximum if both values are non-negative. | 709 // Even no smaller than their maximum if both values are non-negative. |
671 Handle<Object> min = f->NewNumber( | 710 Handle<Object> min = f->NewNumber( |
672 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); | 711 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); |
673 if (lmax < 0 || rmax < 0) { | 712 if (lmax < 0 || rmax < 0) { |
674 // Or-ing two values of which at least one is negative results in a negative | 713 // Or-ing two values of which at least one is negative results in a negative |
675 // value. | 714 // value. |
676 Handle<Object> max = f->NewNumber(-1); | 715 Handle<Object> max = f->NewNumber(-1); |
677 return Type::Range(min, max, t->zone()); | 716 return Type::Range(min, max, t->zone()); |
678 } | 717 } |
679 Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); | 718 Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); |
680 return Type::Range(min, max, t->zone()); | 719 return Type::Range(min, max, t->zone()); |
681 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | 720 // TODO(neis): Be precise for singleton inputs, here and elsewhere. |
682 } | 721 } |
683 | 722 |
684 | 723 |
685 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { | 724 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |
686 Factory* f = t->zone()->isolate()->factory(); | 725 Factory* f = t->isolate()->factory(); |
687 lhs = NumberToInt32(ToNumber(lhs, t), t); | 726 lhs = NumberToInt32(ToNumber(lhs, t), t); |
688 rhs = NumberToInt32(ToNumber(rhs, t), t); | 727 rhs = NumberToInt32(ToNumber(rhs, t), t); |
689 double lmin = lhs->Min(); | 728 double lmin = lhs->Min(); |
690 double rmin = rhs->Min(); | 729 double rmin = rhs->Min(); |
691 double lmax = lhs->Max(); | 730 double lmax = lhs->Max(); |
692 double rmax = rhs->Max(); | 731 double rmax = rhs->Max(); |
693 // And-ing any two values results in a value no larger than their maximum. | 732 // And-ing any two values results in a value no larger than their maximum. |
694 // Even no larger than their minimum if both values are non-negative. | 733 // Even no larger than their minimum if both values are non-negative. |
695 Handle<Object> max = f->NewNumber( | 734 Handle<Object> max = f->NewNumber( |
696 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); | 735 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); |
(...skipping 27 matching lines...) Expand all Loading... | |
724 } | 763 } |
725 | 764 |
726 | 765 |
727 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { | 766 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { |
728 return Type::Signed32(); | 767 return Type::Signed32(); |
729 } | 768 } |
730 | 769 |
731 | 770 |
732 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { | 771 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { |
733 lhs = NumberToInt32(ToNumber(lhs, t), t); | 772 lhs = NumberToInt32(ToNumber(lhs, t), t); |
734 Factory* f = t->zone()->isolate()->factory(); | 773 Factory* f = t->isolate()->factory(); |
735 if (lhs->Min() >= 0) { | 774 if (lhs->Min() >= 0) { |
736 // Right-shifting a non-negative value cannot make it negative, nor larger. | 775 // Right-shifting a non-negative value cannot make it negative, nor larger. |
737 Handle<Object> min = f->NewNumber(0); | 776 Handle<Object> min = f->NewNumber(0); |
738 Handle<Object> max = f->NewNumber(lhs->Max()); | 777 Handle<Object> max = f->NewNumber(lhs->Max()); |
739 return Type::Range(min, max, t->zone()); | 778 return Type::Range(min, max, t->zone()); |
740 } | 779 } |
741 if (lhs->Max() < 0) { | 780 if (lhs->Max() < 0) { |
742 // Right-shifting a negative value cannot make it non-negative, nor smaller. | 781 // Right-shifting a negative value cannot make it non-negative, nor smaller. |
743 Handle<Object> min = f->NewNumber(lhs->Min()); | 782 Handle<Object> min = f->NewNumber(lhs->Min()); |
744 Handle<Object> max = f->NewNumber(-1); | 783 Handle<Object> max = f->NewNumber(-1); |
745 return Type::Range(min, max, t->zone()); | 784 return Type::Range(min, max, t->zone()); |
746 } | 785 } |
747 return Type::Signed32(); | 786 return Type::Signed32(); |
748 } | 787 } |
749 | 788 |
750 | 789 |
751 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { | 790 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { |
752 lhs = NumberToUint32(ToNumber(lhs, t), t); | 791 lhs = NumberToUint32(ToNumber(lhs, t), t); |
753 Factory* f = t->zone()->isolate()->factory(); | 792 Factory* f = t->isolate()->factory(); |
754 // Logical right-shifting any value cannot make it larger. | 793 // Logical right-shifting any value cannot make it larger. |
755 Handle<Object> min = f->NewNumber(0); | 794 Handle<Object> min = f->NewNumber(0); |
756 Handle<Object> max = f->NewNumber(lhs->Max()); | 795 Handle<Object> max = f->NewNumber(lhs->Max()); |
757 return Type::Range(min, max, t->zone()); | 796 return Type::Range(min, max, t->zone()); |
758 } | 797 } |
759 | 798 |
760 | 799 |
761 // JS arithmetic operators. | 800 // JS arithmetic operators. |
762 | 801 |
763 | 802 |
803 // Returns the array's least element, ignoring NaN. | |
804 // There must be at least one non-NaN element. | |
805 // Any -0 is converted to 0. | |
806 static double array_min(double a[], size_t n) { | |
807 DCHECK(n != 0); | |
808 double x = +V8_INFINITY; | |
809 for (size_t i = 0; i < n; ++i) { | |
810 if (!std::isnan(a[i])) { | |
811 x = std::min(a[i], x); | |
812 } | |
813 } | |
814 DCHECK(!std::isnan(x)); | |
815 return x == 0 ? 0 : x; // -0 -> 0 | |
816 } | |
817 | |
818 | |
819 // Returns the array's greatest element, ignoring NaN. | |
820 // There must be at least one non-NaN element. | |
821 // Any -0 is converted to 0. | |
822 static double array_max(double a[], size_t n) { | |
823 DCHECK(n != 0); | |
824 double x = -V8_INFINITY; | |
825 for (size_t i = 0; i < n; ++i) { | |
826 if (!std::isnan(a[i])) { | |
827 x = std::max(a[i], x); | |
828 } | |
829 } | |
830 DCHECK(!std::isnan(x)); | |
831 return x == 0 ? 0 : x; // -0 -> 0 | |
832 } | |
833 | |
834 | |
835 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, | |
836 Typer* t) { | |
837 double results[4]; | |
838 results[0] = lhs->Min()->Number() + rhs->Min()->Number(); | |
839 results[1] = lhs->Min()->Number() + rhs->Max()->Number(); | |
840 results[2] = lhs->Max()->Number() + rhs->Min()->Number(); | |
841 results[3] = lhs->Max()->Number() + rhs->Max()->Number(); | |
842 // Since none of the inputs can be -0, the result cannot be -0 either. | |
843 // However, it can be nan (the sum of two infinities of opposite sign). | |
844 // On the other hand, if none of the "results" above is nan, then the actual | |
845 // result cannot be nan either. | |
846 int nans = 0; | |
847 for (int i = 0; i < 4; ++i) { | |
848 if (std::isnan(results[i])) ++nans; | |
849 } | |
850 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa | |
851 Factory* f = t->isolate()->factory(); | |
852 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | |
853 f->NewNumber(array_max(results, 4)), t->zone()); | |
854 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); | |
855 // Examples: | |
856 // [-inf, -inf] + [+inf, +inf] = NaN | |
857 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN | |
858 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN | |
859 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN | |
860 } | |
861 | |
862 | |
764 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { | 863 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { |
765 lhs = ToPrimitive(lhs, t); | 864 lhs = ToPrimitive(lhs, t); |
766 rhs = ToPrimitive(rhs, t); | 865 rhs = ToPrimitive(rhs, t); |
767 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { | 866 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { |
768 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { | 867 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { |
769 return Type::String(); | 868 return Type::String(); |
770 } else { | 869 } else { |
771 return Type::NumberOrString(); | 870 return Type::NumberOrString(); |
772 } | 871 } |
773 } | 872 } |
774 lhs = ToNumber(lhs, t); | 873 lhs = Rangify(ToNumber(lhs, t), t); |
775 rhs = ToNumber(rhs, t); | 874 rhs = Rangify(ToNumber(rhs, t), t); |
776 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 875 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
777 // TODO(neis): Do some analysis. | 876 if (lhs->IsRange() && rhs->IsRange()) { |
877 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); | |
878 } | |
778 // TODO(neis): Deal with numeric bitsets here and elsewhere. | 879 // TODO(neis): Deal with numeric bitsets here and elsewhere. |
779 return Type::Number(); | 880 return Type::Number(); |
780 } | 881 } |
781 | 882 |
782 | 883 |
884 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, | |
885 Type::RangeType* rhs, Typer* t) { | |
886 double results[4]; | |
887 results[0] = lhs->Min()->Number() - rhs->Min()->Number(); | |
888 results[1] = lhs->Min()->Number() - rhs->Max()->Number(); | |
889 results[2] = lhs->Max()->Number() - rhs->Min()->Number(); | |
890 results[3] = lhs->Max()->Number() - rhs->Max()->Number(); | |
891 // Since none of the inputs can be -0, the result cannot be -0. | |
892 // However, it can be nan (the subtraction of two infinities of same sign). | |
893 // On the other hand, if none of the "results" above is nan, then the actual | |
894 // result cannot be nan either. | |
895 int nans = 0; | |
896 for (int i = 0; i < 4; ++i) { | |
897 if (std::isnan(results[i])) ++nans; | |
898 } | |
899 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign) | |
900 Factory* f = t->isolate()->factory(); | |
901 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | |
902 f->NewNumber(array_max(results, 4)), t->zone()); | |
903 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); | |
904 // Examples: | |
905 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN | |
906 // [-inf, -inf] - [-inf, -inf] = NaN | |
907 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN | |
908 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN | |
909 } | |
910 | |
911 | |
783 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { | 912 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { |
784 lhs = ToNumber(lhs, t); | 913 lhs = Rangify(ToNumber(lhs, t), t); |
785 rhs = ToNumber(rhs, t); | 914 rhs = Rangify(ToNumber(rhs, t), t); |
786 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 915 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
787 // TODO(neis): Do some analysis. | 916 if (lhs->IsRange() && rhs->IsRange()) { |
917 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); | |
918 } | |
788 return Type::Number(); | 919 return Type::Number(); |
789 } | 920 } |
790 | 921 |
791 | 922 |
923 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, | |
924 Type::RangeType* rhs, Typer* t) { | |
925 double results[4]; | |
926 double lmin = lhs->Min()->Number(); | |
927 double lmax = lhs->Max()->Number(); | |
928 double rmin = rhs->Min()->Number(); | |
929 double rmax = rhs->Max()->Number(); | |
930 results[0] = lmin * rmin; | |
931 results[1] = lmin * rmax; | |
932 results[2] = lmax * rmin; | |
933 results[3] = lmax * rmax; | |
934 // If the result may be nan, we give up on calculating a precise type, because | |
935 // the discontinuity makes it too complicated. Note that even if none of the | |
936 // "results" above is nan, the actual result may still be, so we have to do a | |
937 // different check: | |
938 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && | |
939 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | |
940 (rhs->Maybe(t->singleton_zero) && | |
941 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | |
942 if (maybe_nan) return t->weakint; // Giving up. | |
943 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || | |
944 (rhs->Maybe(t->singleton_zero) && lmin < 0); | |
945 Factory* f = t->isolate()->factory(); | |
946 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | |
947 f->NewNumber(array_max(results, 4)), t->zone()); | |
948 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) | |
949 : range; | |
950 } | |
951 | |
952 | |
792 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 953 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
793 lhs = ToNumber(lhs, t); | 954 lhs = Rangify(ToNumber(lhs, t), t); |
794 rhs = ToNumber(rhs, t); | 955 rhs = Rangify(ToNumber(rhs, t), t); |
795 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 956 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
796 // TODO(neis): Do some analysis. | 957 if (lhs->IsRange() && rhs->IsRange()) { |
958 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); | |
959 } | |
797 return Type::Number(); | 960 return Type::Number(); |
798 } | 961 } |
799 | 962 |
800 | 963 |
801 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 964 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
802 lhs = ToNumber(lhs, t); | 965 lhs = ToNumber(lhs, t); |
803 rhs = ToNumber(rhs, t); | 966 rhs = ToNumber(rhs, t); |
804 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 967 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
805 // TODO(neis): Do some analysis. | 968 // Division is tricky, so all we do is try ruling out nan. |
806 return Type::Number(); | 969 // TODO(neis): try ruling out -0 as well? |
970 bool maybe_nan = | |
971 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | |
972 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | |
973 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | |
974 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | |
807 } | 975 } |
808 | 976 |
809 | 977 |
810 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 978 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
811 lhs = ToNumber(lhs, t); | 979 lhs = ToNumber(lhs, t); |
812 rhs = ToNumber(rhs, t); | 980 rhs = ToNumber(rhs, t); |
813 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 981 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
814 // TODO(neis): Do some analysis. | 982 // Division is tricky, so all we do is try ruling out nan. |
815 return Type::Number(); | 983 // TODO(neis): try ruling out -0 as well? |
984 bool maybe_nan = | |
985 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | |
986 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | |
987 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | |
988 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | |
816 } | 989 } |
817 | 990 |
818 | 991 |
819 // JS unary operators. | 992 // JS unary operators. |
820 | 993 |
821 | 994 |
822 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { | 995 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { |
823 return Invert(ToBoolean(type, t), t); | 996 return Invert(ToBoolean(type, t), t); |
824 } | 997 } |
825 | 998 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { | 1056 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { |
884 return TypeBinaryOp(node, JSLoadPropertyTyper); | 1057 return TypeBinaryOp(node, JSLoadPropertyTyper); |
885 } | 1058 } |
886 | 1059 |
887 | 1060 |
888 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { | 1061 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { |
889 return Bounds::Unbounded(zone()); | 1062 return Bounds::Unbounded(zone()); |
890 } | 1063 } |
891 | 1064 |
892 | 1065 |
1066 Type* Typer::Visitor::MaybeWeaken(Type* current, Type* previous) { | |
rossberg
2014/10/23 13:44:27
Is there any reason left not to merge the Weaken f
Jarin
2014/10/23 13:54:59
Done.
| |
1067 if (current->IsRange() && previous->IsRange()) { | |
1068 return Weaken(previous->AsRange(), current->AsRange()); | |
1069 } | |
1070 return current; | |
1071 } | |
1072 | |
1073 | |
1074 // Returns a somewhat larger range. This is used to speed up | |
1075 // the fixpoint calculation in case there appears to be a loop | |
1076 // in the graph. In the current implementation, we are | |
1077 // increasing the limits to the closest power of two. | |
1078 Type* Typer::Visitor::Weaken(Type::RangeType* previous, | |
1079 Type::RangeType* current) { | |
1080 double current_min = current->Min()->Number(); | |
1081 double current_max = current->Max()->Number(); | |
1082 | |
1083 Handle<Object> new_min = current->Min(); | |
1084 Handle<Object> new_max = current->Max(); | |
1085 | |
1086 // Find the closest lower entry in the list of allowed | |
1087 // minima (or negative infinity if there is no such entry). | |
1088 if (current_min != previous->Min()->Number()) { | |
1089 new_min = typer_->integer->AsRange()->Min(); | |
1090 for (const auto val : typer_->weaken_min_limits_) { | |
1091 if (val->Number() <= current_min) { | |
1092 new_min = val; | |
1093 break; | |
1094 } | |
1095 } | |
1096 } | |
1097 | |
1098 // Find the closest greater entry in the list of allowed | |
1099 // maxima (or infinity if there is no such entry). | |
1100 if (current_max != previous->Max()->Number()) { | |
1101 new_max = typer_->integer->AsRange()->Max(); | |
1102 for (const auto val : typer_->weaken_max_limits_) { | |
1103 if (val->Number() >= current_max) { | |
1104 new_max = val; | |
1105 break; | |
1106 } | |
1107 } | |
1108 } | |
1109 | |
1110 return Type::Range(new_min, new_max, typer_->zone()); | |
1111 } | |
1112 | |
1113 | |
893 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { | 1114 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { |
894 UNREACHABLE(); | 1115 UNREACHABLE(); |
895 return Bounds(); | 1116 return Bounds(); |
896 } | 1117 } |
897 | 1118 |
898 | 1119 |
899 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { | 1120 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { |
900 UNREACHABLE(); | 1121 UNREACHABLE(); |
901 return Bounds(); | 1122 return Bounds(); |
902 } | 1123 } |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1635 return typer_->float64_array_fun_; | 1856 return typer_->float64_array_fun_; |
1636 } | 1857 } |
1637 } | 1858 } |
1638 } | 1859 } |
1639 return Type::Constant(value, zone()); | 1860 return Type::Constant(value, zone()); |
1640 } | 1861 } |
1641 | 1862 |
1642 } | 1863 } |
1643 } | 1864 } |
1644 } // namespace v8::internal::compiler | 1865 } // namespace v8::internal::compiler |
OLD | NEW |