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/base/flags.h" | 5 #include "src/base/flags.h" |
6 #include "src/bootstrapper.h" | 6 #include "src/bootstrapper.h" |
7 #include "src/compiler/graph-reducer.h" | 7 #include "src/compiler/graph-reducer.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.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 #define NATIVE_TYPES(V) \ | 18 #define NATIVE_TYPES(V) \ |
19 V(Int8) \ | 19 V(Int8) \ |
20 V(Uint8) \ | 20 V(Uint8) \ |
21 V(Int16) \ | 21 V(Int16) \ |
22 V(Uint16) \ | 22 V(Uint16) \ |
23 V(Int32) \ | 23 V(Int32) \ |
24 V(Uint32) \ | 24 V(Uint32) \ |
25 V(Float32) \ | 25 V(Float32) \ |
26 V(Float64) | 26 V(Float64) |
27 | 27 |
28 enum LazyCachedType { | 28 enum LazyCachedType { |
| 29 kInteger, |
| 30 kWeakint, |
| 31 kWeakintFunc1, |
| 32 kRandomFunc0, |
29 kAnyFunc0, | 33 kAnyFunc0, |
30 kAnyFunc1, | 34 kAnyFunc1, |
31 kAnyFunc2, | 35 kAnyFunc2, |
32 kAnyFunc3, | 36 kAnyFunc3, |
33 kNumberFunc0, | 37 kNumberFunc0, |
34 kNumberFunc1, | 38 kNumberFunc1, |
35 kNumberFunc2, | 39 kNumberFunc2, |
36 kImulFunc, | 40 kImulFunc, |
37 kClz32Func, | 41 kClz32Func, |
38 kArrayBufferFunc, | 42 kArrayBufferFunc, |
39 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 43 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
40 k##Type, k##Type##Array, k##Type##ArrayFunc, | 44 k##Type, k##Type##Array, k##Type##ArrayFunc, |
41 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 45 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
42 #undef TYPED_ARRAY_CASE | 46 #undef TYPED_ARRAY_CASE |
43 kNumLazyCachedTypes | 47 kNumLazyCachedTypes |
44 }; | 48 }; |
45 | 49 |
46 | 50 |
47 // Constructs and caches types lazily. | 51 // Constructs and caches types lazily. |
48 // TODO(turbofan): these types could be globally cached or cached per isolate. | 52 // TODO(turbofan): these types could be globally cached or cached per isolate. |
49 class LazyTypeCache final : public ZoneObject { | 53 class LazyTypeCache final : public ZoneObject { |
50 public: | 54 public: |
51 explicit LazyTypeCache(Isolate* isolate, Zone* zone) | 55 explicit LazyTypeCache(Isolate* isolate, Zone* zone) |
52 : isolate_(isolate), zone_(zone) { | 56 : isolate_(isolate), zone_(zone) { |
53 memset(cache_, 0, sizeof(cache_)); | 57 memset(cache_, 0, sizeof(cache_)); |
54 } | 58 } |
55 | 59 |
56 inline Type* Get(LazyCachedType type) { | 60 V8_INLINE Type* Get(LazyCachedType type) { |
57 int index = static_cast<int>(type); | 61 int const index = static_cast<int>(type); |
58 DCHECK(index < kNumLazyCachedTypes); | 62 DCHECK_LT(index, kNumLazyCachedTypes); |
59 if (cache_[index] == NULL) cache_[index] = Create(type); | 63 if (cache_[index] == NULL) cache_[index] = Create(type); |
60 return cache_[index]; | 64 return cache_[index]; |
61 } | 65 } |
62 | 66 |
63 private: | 67 private: |
64 Type* Create(LazyCachedType type) { | 68 Type* Create(LazyCachedType type) { |
65 switch (type) { | 69 switch (type) { |
66 case kInt8: | 70 case kInt8: |
67 return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8()); | 71 return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8()); |
68 case kUint8: | 72 case kUint8: |
69 return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8()); | 73 return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8()); |
70 case kInt16: | 74 case kInt16: |
71 return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16()); | 75 return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16()); |
72 case kUint16: | 76 case kUint16: |
73 return CreateNative(CreateRange<uint16_t>(), | 77 return CreateNative(CreateRange<uint16_t>(), |
74 Type::UntaggedUnsigned16()); | 78 Type::UntaggedUnsigned16()); |
75 case kInt32: | 79 case kInt32: |
76 return CreateNative(Type::Signed32(), Type::UntaggedSigned32()); | 80 return CreateNative(Type::Signed32(), Type::UntaggedSigned32()); |
77 case kUint32: | 81 case kUint32: |
78 return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32()); | 82 return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32()); |
79 case kFloat32: | 83 case kFloat32: |
80 return CreateNative(Type::Number(), Type::UntaggedFloat32()); | 84 return CreateNative(Type::Number(), Type::UntaggedFloat32()); |
81 case kFloat64: | 85 case kFloat64: |
82 return CreateNative(Type::Number(), Type::UntaggedFloat64()); | 86 return CreateNative(Type::Number(), Type::UntaggedFloat64()); |
83 case kUint8Clamped: | 87 case kUint8Clamped: |
84 return Get(kUint8); | 88 return Get(kUint8); |
| 89 case kInteger: |
| 90 return CreateRange(-V8_INFINITY, V8_INFINITY); |
| 91 case kWeakint: |
| 92 return Type::Union(Get(kInteger), Type::MinusZeroOrNaN(), zone()); |
| 93 case kWeakintFunc1: |
| 94 return Type::Function(Get(kWeakint), Type::Number(), zone()); |
| 95 case kRandomFunc0: |
| 96 return Type::Function(Type::OrderedNumber(), zone()); |
85 case kAnyFunc0: | 97 case kAnyFunc0: |
86 return Type::Function(Type::Any(), zone()); | 98 return Type::Function(Type::Any(), zone()); |
87 case kAnyFunc1: | 99 case kAnyFunc1: |
88 return Type::Function(Type::Any(), Type::Any(), zone()); | 100 return Type::Function(Type::Any(), Type::Any(), zone()); |
89 case kAnyFunc2: | 101 case kAnyFunc2: |
90 return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone()); | 102 return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone()); |
91 case kAnyFunc3: | 103 case kAnyFunc3: |
92 return Type::Function(Type::Any(), Type::Any(), Type::Any(), | 104 return Type::Function(Type::Any(), Type::Any(), Type::Any(), |
93 Type::Any(), zone()); | 105 Type::Any(), zone()); |
94 case kNumberFunc0: | 106 case kNumberFunc0: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 }; | 176 }; |
165 | 177 |
166 | 178 |
167 Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context) | 179 Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context) |
168 : isolate_(isolate), | 180 : isolate_(isolate), |
169 graph_(graph), | 181 graph_(graph), |
170 context_(context), | 182 context_(context), |
171 decorator_(NULL), | 183 decorator_(NULL), |
172 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) { | 184 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) { |
173 Zone* zone = this->zone(); | 185 Zone* zone = this->zone(); |
174 Factory* f = isolate->factory(); | 186 Factory* const factory = isolate->factory(); |
175 | 187 |
176 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); | 188 Type* infinity = Type::Constant(factory->infinity_value(), zone); |
177 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); | 189 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); |
| 190 Type* truncating_to_zero = |
| 191 Type::Union(Type::Union(infinity, minus_infinity, zone), |
| 192 Type::MinusZeroOrNaN(), zone); |
178 | 193 |
179 Type* number = Type::Number(); | 194 singleton_false_ = Type::Constant(factory->false_value(), zone); |
180 Type* signed32 = Type::Signed32(); | 195 singleton_true_ = Type::Constant(factory->true_value(), zone); |
181 Type* unsigned32 = Type::Unsigned32(); | 196 singleton_zero_ = Type::Range(0.0, 0.0, zone); |
182 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); | 197 singleton_one_ = Type::Range(1.0, 1.0, zone); |
183 Type* truncating_to_zero = | 198 zero_or_one_ = Type::Range(0.0, 1.0, zone); |
184 Type::Union(Type::Union(Type::Constant(infinity, zone), | 199 zeroish_ = Type::Union(singleton_zero_, Type::MinusZeroOrNaN(), zone); |
185 Type::Constant(minusinfinity, zone), zone), | 200 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); |
186 nan_or_minuszero, zone); | 201 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); |
187 | 202 falsish_ = |
188 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone); | 203 Type::Union(Type::Undetectable(), |
189 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); | 204 Type::Union(Type::Union(singleton_false_, zeroish_, zone), |
190 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone); | 205 Type::NullOrUndefined(), zone), |
191 singleton_false = Type::Constant(f->false_value(), zone); | 206 zone); |
192 singleton_true = Type::Constant(f->true_value(), zone); | 207 truish_ = Type::Union( |
193 singleton_zero = Type::Range(0.0, 0.0, zone); | 208 singleton_true_, |
194 singleton_one = Type::Range(1.0, 1.0, zone); | |
195 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); | |
196 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone); | |
197 signed32ish = Type::Union(signed32, truncating_to_zero, zone); | |
198 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone); | |
199 falsish = Type::Union(Type::Undetectable(), | |
200 Type::Union(Type::Union(singleton_false, zeroish, zone), | |
201 undefined_or_null, zone), | |
202 zone); | |
203 truish = Type::Union( | |
204 singleton_true, | |
205 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); | 209 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); |
206 integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone); | |
207 weakint = Type::Union(integer, nan_or_minuszero, zone); | |
208 | |
209 number_fun0_ = Type::Function(number, zone); | |
210 number_fun1_ = Type::Function(number, number, zone); | |
211 number_fun2_ = Type::Function(number, number, number, zone); | |
212 | |
213 weakint_fun1_ = Type::Function(weakint, number, zone); | |
214 random_fun_ = Type::Function(Type::OrderedNumber(), zone); | |
215 | 210 |
216 decorator_ = new (zone) Decorator(this); | 211 decorator_ = new (zone) Decorator(this); |
217 graph_->AddDecorator(decorator_); | 212 graph_->AddDecorator(decorator_); |
218 } | 213 } |
219 | 214 |
220 | 215 |
221 Typer::~Typer() { | 216 Typer::~Typer() { |
222 graph_->RemoveDecorator(decorator_); | 217 graph_->RemoveDecorator(decorator_); |
223 } | 218 } |
224 | 219 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 : f(left.lower, right.lower, typer_)) | 488 : f(left.lower, right.lower, typer_)) |
494 : Type::None(); | 489 : Type::None(); |
495 // TODO(neis): Figure out what to do with lower bound. | 490 // TODO(neis): Figure out what to do with lower bound. |
496 return Bounds(lower, upper); | 491 return Bounds(lower, upper); |
497 } | 492 } |
498 | 493 |
499 | 494 |
500 Type* Typer::Visitor::Invert(Type* type, Typer* t) { | 495 Type* Typer::Visitor::Invert(Type* type, Typer* t) { |
501 DCHECK(type->Is(Type::Boolean())); | 496 DCHECK(type->Is(Type::Boolean())); |
502 DCHECK(type->IsInhabited()); | 497 DCHECK(type->IsInhabited()); |
503 if (type->Is(t->singleton_false)) return t->singleton_true; | 498 if (type->Is(t->singleton_false_)) return t->singleton_true_; |
504 if (type->Is(t->singleton_true)) return t->singleton_false; | 499 if (type->Is(t->singleton_true_)) return t->singleton_false_; |
505 return type; | 500 return type; |
506 } | 501 } |
507 | 502 |
508 | 503 |
509 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert( | 504 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert( |
510 ComparisonOutcome outcome, Typer* t) { | 505 ComparisonOutcome outcome, Typer* t) { |
511 ComparisonOutcome result(0); | 506 ComparisonOutcome result(0); |
512 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; | 507 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; |
513 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; | 508 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; |
514 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; | 509 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; |
515 return result; | 510 return result; |
516 } | 511 } |
517 | 512 |
518 | 513 |
519 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { | 514 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { |
520 if ((outcome & kComparisonFalse) != 0 || | 515 if ((outcome & kComparisonFalse) != 0 || |
521 (outcome & kComparisonUndefined) != 0) { | 516 (outcome & kComparisonUndefined) != 0) { |
522 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() | 517 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() |
523 : t->singleton_false; | 518 : t->singleton_false_; |
524 } | 519 } |
525 // Type should be non empty, so we know it should be true. | 520 // Type should be non empty, so we know it should be true. |
526 DCHECK((outcome & kComparisonTrue) != 0); | 521 DCHECK((outcome & kComparisonTrue) != 0); |
527 return t->singleton_true; | 522 return t->singleton_true_; |
528 } | 523 } |
529 | 524 |
530 | 525 |
531 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { | 526 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { |
532 if (type->IsRange()) return type; // Shortcut. | 527 if (type->IsRange()) return type; // Shortcut. |
533 if (!type->Is(t->integer) && !type->Is(Type::Integral32())) { | 528 if (!type->Is(t->cache_->Get(kInteger))) { |
534 return type; // Give up on non-integer types. | 529 return type; // Give up on non-integer types. |
535 } | 530 } |
536 double min = type->Min(); | 531 double min = type->Min(); |
537 double max = type->Max(); | 532 double max = type->Max(); |
538 // Handle the degenerate case of empty bitset types (such as | 533 // Handle the degenerate case of empty bitset types (such as |
539 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). | 534 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). |
540 if (std::isnan(min)) { | 535 if (std::isnan(min)) { |
541 DCHECK(std::isnan(max)); | 536 DCHECK(std::isnan(max)); |
542 return type; | 537 return type; |
543 } | 538 } |
544 return Type::Range(min, max, t->zone()); | 539 return Type::Range(min, max, t->zone()); |
545 } | 540 } |
546 | 541 |
547 | 542 |
548 // Type conversion. | 543 // Type conversion. |
549 | 544 |
550 | 545 |
551 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { | 546 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { |
552 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { | 547 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { |
553 return type; | 548 return type; |
554 } | 549 } |
555 return Type::Primitive(); | 550 return Type::Primitive(); |
556 } | 551 } |
557 | 552 |
558 | 553 |
559 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { | 554 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { |
560 if (type->Is(Type::Boolean())) return type; | 555 if (type->Is(Type::Boolean())) return type; |
561 if (type->Is(t->falsish)) return t->singleton_false; | 556 if (type->Is(t->falsish_)) return t->singleton_false_; |
562 if (type->Is(t->truish)) return t->singleton_true; | 557 if (type->Is(t->truish_)) return t->singleton_true_; |
563 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { | 558 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { |
564 return t->singleton_true; // Ruled out nan, -0 and +0. | 559 return t->singleton_true_; // Ruled out nan, -0 and +0. |
565 } | 560 } |
566 return Type::Boolean(); | 561 return Type::Boolean(); |
567 } | 562 } |
568 | 563 |
569 | 564 |
570 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { | 565 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
571 if (type->Is(Type::Number())) return type; | 566 if (type->Is(Type::Number())) return type; |
572 if (type->Is(Type::Null())) return t->singleton_zero; | 567 if (type->Is(Type::NullOrUndefined())) { |
573 if (type->Is(Type::Undefined())) return Type::NaN(); | 568 if (type->Is(Type::Null())) return t->singleton_zero_; |
574 if (type->Is(t->undefined_or_null)) { | 569 if (type->Is(Type::Undefined())) return Type::NaN(); |
575 return Type::Union(Type::NaN(), t->singleton_zero, t->zone()); | 570 return Type::Union(Type::NaN(), t->singleton_zero_, t->zone()); |
576 } | 571 } |
577 if (type->Is(t->undefined_or_number)) { | 572 if (type->Is(Type::NumberOrUndefined())) { |
578 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 573 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
579 Type::NaN(), t->zone()); | 574 Type::NaN(), t->zone()); |
580 } | 575 } |
581 if (type->Is(t->singleton_false)) return t->singleton_zero; | 576 if (type->Is(t->singleton_false_)) return t->singleton_zero_; |
582 if (type->Is(t->singleton_true)) return t->singleton_one; | 577 if (type->Is(t->singleton_true_)) return t->singleton_one_; |
583 if (type->Is(Type::Boolean())) return t->zero_or_one; | 578 if (type->Is(Type::Boolean())) return t->zero_or_one_; |
584 if (type->Is(t->boolean_or_number)) { | 579 if (type->Is(Type::BooleanOrNumber())) { |
585 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 580 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
586 t->zero_or_one, t->zone()); | 581 t->zero_or_one_, t->zone()); |
587 } | 582 } |
588 return Type::Number(); | 583 return Type::Number(); |
589 } | 584 } |
590 | 585 |
591 | 586 |
592 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 587 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
593 if (type->Is(Type::String())) return type; | 588 if (type->Is(Type::String())) return type; |
594 return Type::String(); | 589 return Type::String(); |
595 } | 590 } |
596 | 591 |
597 | 592 |
598 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { | 593 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { |
599 // TODO(neis): DCHECK(type->Is(Type::Number())); | 594 // TODO(neis): DCHECK(type->Is(Type::Number())); |
600 if (type->Is(Type::Signed32())) return type; | 595 if (type->Is(Type::Signed32())) return type; |
601 if (type->Is(t->zeroish)) return t->singleton_zero; | 596 if (type->Is(t->zeroish_)) return t->singleton_zero_; |
602 if (type->Is(t->signed32ish)) { | 597 if (type->Is(t->signed32ish_)) { |
603 return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()), | 598 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), |
604 Type::Signed32(), t->zone()); | 599 Type::Signed32(), t->zone()); |
605 } | 600 } |
606 return Type::Signed32(); | 601 return Type::Signed32(); |
607 } | 602 } |
608 | 603 |
609 | 604 |
610 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { | 605 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { |
611 // TODO(neis): DCHECK(type->Is(Type::Number())); | 606 // TODO(neis): DCHECK(type->Is(Type::Number())); |
612 if (type->Is(Type::Unsigned32())) return type; | 607 if (type->Is(Type::Unsigned32())) return type; |
613 if (type->Is(t->zeroish)) return t->singleton_zero; | 608 if (type->Is(t->zeroish_)) return t->singleton_zero_; |
614 if (type->Is(t->unsigned32ish)) { | 609 if (type->Is(t->unsigned32ish_)) { |
615 return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()), | 610 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), |
616 Type::Unsigned32(), t->zone()); | 611 Type::Unsigned32(), t->zone()); |
617 } | 612 } |
618 return Type::Unsigned32(); | 613 return Type::Unsigned32(); |
619 } | 614 } |
620 | 615 |
621 | 616 |
622 // ----------------------------------------------------------------------------- | 617 // ----------------------------------------------------------------------------- |
623 | 618 |
624 | 619 |
625 // Control operators. | 620 // Control operators. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 | 764 |
770 Bounds Typer::Visitor::TypeDead(Node* node) { | 765 Bounds Typer::Visitor::TypeDead(Node* node) { |
771 return Bounds::Unbounded(zone()); | 766 return Bounds::Unbounded(zone()); |
772 } | 767 } |
773 | 768 |
774 | 769 |
775 // JS comparison operators. | 770 // JS comparison operators. |
776 | 771 |
777 | 772 |
778 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 773 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
779 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; | 774 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; |
780 if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) { | 775 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { |
781 return t->singleton_true; | 776 return t->singleton_true_; |
782 } | 777 } |
783 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && | 778 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |
784 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { | 779 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |
785 return t->singleton_false; | 780 return t->singleton_false_; |
786 } | 781 } |
787 if (lhs->IsConstant() && rhs->Is(lhs)) { | 782 if (lhs->IsConstant() && rhs->Is(lhs)) { |
788 // Types are equal and are inhabited only by a single semantic value, | 783 // Types are equal and are inhabited only by a single semantic value, |
789 // which is not nan due to the earlier check. | 784 // which is not nan due to the earlier check. |
790 // TODO(neis): Extend this to Range(x,x), MinusZero, ...? | 785 // TODO(neis): Extend this to Range(x,x), MinusZero, ...? |
791 return t->singleton_true; | 786 return t->singleton_true_; |
792 } | 787 } |
793 return Type::Boolean(); | 788 return Type::Boolean(); |
794 } | 789 } |
795 | 790 |
796 | 791 |
797 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 792 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
798 return Invert(JSEqualTyper(lhs, rhs, t), t); | 793 return Invert(JSEqualTyper(lhs, rhs, t), t); |
799 } | 794 } |
800 | 795 |
801 | 796 |
802 static Type* JSType(Type* type) { | 797 static Type* JSType(Type* type) { |
803 if (type->Is(Type::Boolean())) return Type::Boolean(); | 798 if (type->Is(Type::Boolean())) return Type::Boolean(); |
804 if (type->Is(Type::String())) return Type::String(); | 799 if (type->Is(Type::String())) return Type::String(); |
805 if (type->Is(Type::Number())) return Type::Number(); | 800 if (type->Is(Type::Number())) return Type::Number(); |
806 if (type->Is(Type::Undefined())) return Type::Undefined(); | 801 if (type->Is(Type::Undefined())) return Type::Undefined(); |
807 if (type->Is(Type::Null())) return Type::Null(); | 802 if (type->Is(Type::Null())) return Type::Null(); |
808 if (type->Is(Type::Symbol())) return Type::Symbol(); | 803 if (type->Is(Type::Symbol())) return Type::Symbol(); |
809 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object" | 804 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object" |
810 return Type::Any(); | 805 return Type::Any(); |
811 } | 806 } |
812 | 807 |
813 | 808 |
814 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 809 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
815 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false; | 810 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_; |
816 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; | 811 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; |
817 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && | 812 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |
818 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { | 813 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |
819 return t->singleton_false; | 814 return t->singleton_false_; |
820 } | 815 } |
821 if (lhs->IsConstant() && rhs->Is(lhs)) { | 816 if (lhs->IsConstant() && rhs->Is(lhs)) { |
822 // Types are equal and are inhabited only by a single semantic value, | 817 // Types are equal and are inhabited only by a single semantic value, |
823 // which is not nan due to the earlier check. | 818 // which is not nan due to the earlier check. |
824 return t->singleton_true; | 819 return t->singleton_true_; |
825 } | 820 } |
826 return Type::Boolean(); | 821 return Type::Boolean(); |
827 } | 822 } |
828 | 823 |
829 | 824 |
830 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 825 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
831 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); | 826 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); |
832 } | 827 } |
833 | 828 |
834 | 829 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 double rmin = rhs->Min(); | 1150 double rmin = rhs->Min(); |
1156 double rmax = rhs->Max(); | 1151 double rmax = rhs->Max(); |
1157 results[0] = lmin * rmin; | 1152 results[0] = lmin * rmin; |
1158 results[1] = lmin * rmax; | 1153 results[1] = lmin * rmax; |
1159 results[2] = lmax * rmin; | 1154 results[2] = lmax * rmin; |
1160 results[3] = lmax * rmax; | 1155 results[3] = lmax * rmax; |
1161 // If the result may be nan, we give up on calculating a precise type, because | 1156 // If the result may be nan, we give up on calculating a precise type, because |
1162 // the discontinuity makes it too complicated. Note that even if none of the | 1157 // the discontinuity makes it too complicated. Note that even if none of the |
1163 // "results" above is nan, the actual result may still be, so we have to do a | 1158 // "results" above is nan, the actual result may still be, so we have to do a |
1164 // different check: | 1159 // different check: |
1165 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && | 1160 bool maybe_nan = (lhs->Maybe(t->singleton_zero_) && |
1166 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | 1161 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || |
1167 (rhs->Maybe(t->singleton_zero) && | 1162 (rhs->Maybe(t->singleton_zero_) && |
1168 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | 1163 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); |
1169 if (maybe_nan) return t->weakint; // Giving up. | 1164 if (maybe_nan) return t->cache_->Get(kWeakint); // Giving up. |
1170 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || | 1165 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero_) && rmin < 0) || |
1171 (rhs->Maybe(t->singleton_zero) && lmin < 0); | 1166 (rhs->Maybe(t->singleton_zero_) && lmin < 0); |
1172 Type* range = | 1167 Type* range = |
1173 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); | 1168 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
1174 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) | 1169 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) |
1175 : range; | 1170 : range; |
1176 } | 1171 } |
1177 | 1172 |
1178 | 1173 |
1179 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 1174 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
1180 lhs = Rangify(ToNumber(lhs, t), t); | 1175 lhs = Rangify(ToNumber(lhs, t), t); |
1181 rhs = Rangify(ToNumber(rhs, t), t); | 1176 rhs = Rangify(ToNumber(rhs, t), t); |
1182 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1177 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1183 if (lhs->IsRange() && rhs->IsRange()) { | 1178 if (lhs->IsRange() && rhs->IsRange()) { |
1184 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); | 1179 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); |
1185 } | 1180 } |
1186 return Type::Number(); | 1181 return Type::Number(); |
1187 } | 1182 } |
1188 | 1183 |
1189 | 1184 |
1190 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 1185 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
1191 lhs = ToNumber(lhs, t); | 1186 lhs = ToNumber(lhs, t); |
1192 rhs = ToNumber(rhs, t); | 1187 rhs = ToNumber(rhs, t); |
1193 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1188 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1194 // Division is tricky, so all we do is try ruling out nan. | 1189 // Division is tricky, so all we do is try ruling out nan. |
1195 // TODO(neis): try ruling out -0 as well? | 1190 // TODO(neis): try ruling out -0 as well? |
1196 bool maybe_nan = | 1191 bool maybe_nan = |
1197 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1192 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || |
1198 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1193 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
1199 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1194 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
1200 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1195 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
1201 } | 1196 } |
1202 | 1197 |
1203 | 1198 |
1204 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | 1199 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, |
1205 Type::RangeType* rhs, Typer* t) { | 1200 Type::RangeType* rhs, Typer* t) { |
1206 double lmin = lhs->Min(); | 1201 double lmin = lhs->Min(); |
1207 double lmax = lhs->Max(); | 1202 double lmax = lhs->Max(); |
(...skipping 24 matching lines...) Expand all Loading... |
1232 result = Type::Union(result, Type::MinusZero(), t->zone()); | 1227 result = Type::Union(result, Type::MinusZero(), t->zone()); |
1233 return result; | 1228 return result; |
1234 } | 1229 } |
1235 | 1230 |
1236 | 1231 |
1237 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1232 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
1238 lhs = ToNumber(lhs, t); | 1233 lhs = ToNumber(lhs, t); |
1239 rhs = ToNumber(rhs, t); | 1234 rhs = ToNumber(rhs, t); |
1240 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1235 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1241 | 1236 |
1242 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1237 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || |
1243 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { | 1238 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { |
1244 // Result maybe NaN. | 1239 // Result maybe NaN. |
1245 return Type::Number(); | 1240 return Type::Number(); |
1246 } | 1241 } |
1247 | 1242 |
1248 lhs = Rangify(lhs, t); | 1243 lhs = Rangify(lhs, t); |
1249 rhs = Rangify(rhs, t); | 1244 rhs = Rangify(rhs, t); |
1250 if (lhs->IsRange() && rhs->IsRange()) { | 1245 if (lhs->IsRange() && rhs->IsRange()) { |
1251 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); | 1246 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); |
1252 } | 1247 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 static const double kWeakenMaxLimits[] = { | 1355 static const double kWeakenMaxLimits[] = { |
1361 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, | 1356 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, |
1362 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, | 1357 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, |
1363 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, | 1358 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, |
1364 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, | 1359 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, |
1365 70368744177663.0, 140737488355327.0, 281474976710655.0, | 1360 70368744177663.0, 140737488355327.0, 281474976710655.0, |
1366 562949953421311.0}; | 1361 562949953421311.0}; |
1367 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); | 1362 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); |
1368 | 1363 |
1369 // If the types have nothing to do with integers, return the types. | 1364 // If the types have nothing to do with integers, return the types. |
1370 if (!previous_type->Maybe(typer_->integer)) { | 1365 Type* const integer = typer_->cache_->Get(kInteger); |
| 1366 if (!previous_type->Maybe(integer)) { |
1371 return current_type; | 1367 return current_type; |
1372 } | 1368 } |
1373 DCHECK(current_type->Maybe(typer_->integer)); | 1369 DCHECK(current_type->Maybe(integer)); |
1374 | 1370 |
1375 Type* current_integer = | 1371 Type* current_integer = Type::Intersect(current_type, integer, zone()); |
1376 Type::Intersect(current_type, typer_->integer, zone()); | 1372 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); |
1377 Type* previous_integer = | |
1378 Type::Intersect(previous_type, typer_->integer, zone()); | |
1379 | 1373 |
1380 // Once we start weakening a node, we should always weaken. | 1374 // Once we start weakening a node, we should always weaken. |
1381 if (!IsWeakened(node->id())) { | 1375 if (!IsWeakened(node->id())) { |
1382 // Only weaken if there is range involved; we should converge quickly | 1376 // Only weaken if there is range involved; we should converge quickly |
1383 // for all other types (the exception is a union of many constants, | 1377 // for all other types (the exception is a union of many constants, |
1384 // but we currently do not increase the number of constants in unions). | 1378 // but we currently do not increase the number of constants in unions). |
1385 Type::RangeType* previous = previous_integer->GetRange(); | 1379 Type::RangeType* previous = previous_integer->GetRange(); |
1386 Type::RangeType* current = current_integer->GetRange(); | 1380 Type::RangeType* current = current_integer->GetRange(); |
1387 if (current == nullptr || previous == nullptr) { | 1381 if (current == nullptr || previous == nullptr) { |
1388 return current_type; | 1382 return current_type; |
1389 } | 1383 } |
1390 // Range is involved => we are weakening. | 1384 // Range is involved => we are weakening. |
1391 SetWeakened(node->id()); | 1385 SetWeakened(node->id()); |
1392 } | 1386 } |
1393 | 1387 |
1394 double current_min = current_integer->Min(); | 1388 double current_min = current_integer->Min(); |
1395 double new_min = current_min; | 1389 double new_min = current_min; |
1396 // Find the closest lower entry in the list of allowed | 1390 // Find the closest lower entry in the list of allowed |
1397 // minima (or negative infinity if there is no such entry). | 1391 // minima (or negative infinity if there is no such entry). |
1398 if (current_min != previous_integer->Min()) { | 1392 if (current_min != previous_integer->Min()) { |
1399 new_min = typer_->integer->AsRange()->Min(); | 1393 new_min = -V8_INFINITY; |
1400 for (double const min : kWeakenMinLimits) { | 1394 for (double const min : kWeakenMinLimits) { |
1401 if (min <= current_min) { | 1395 if (min <= current_min) { |
1402 new_min = min; | 1396 new_min = min; |
1403 break; | 1397 break; |
1404 } | 1398 } |
1405 } | 1399 } |
1406 } | 1400 } |
1407 | 1401 |
1408 double current_max = current_integer->Max(); | 1402 double current_max = current_integer->Max(); |
1409 double new_max = current_max; | 1403 double new_max = current_max; |
1410 // Find the closest greater entry in the list of allowed | 1404 // Find the closest greater entry in the list of allowed |
1411 // maxima (or infinity if there is no such entry). | 1405 // maxima (or infinity if there is no such entry). |
1412 if (current_max != previous_integer->Max()) { | 1406 if (current_max != previous_integer->Max()) { |
1413 new_max = typer_->integer->AsRange()->Max(); | 1407 new_max = V8_INFINITY; |
1414 for (double const max : kWeakenMaxLimits) { | 1408 for (double const max : kWeakenMaxLimits) { |
1415 if (max >= current_max) { | 1409 if (max >= current_max) { |
1416 new_max = max; | 1410 new_max = max; |
1417 break; | 1411 break; |
1418 } | 1412 } |
1419 } | 1413 } |
1420 } | 1414 } |
1421 | 1415 |
1422 return Type::Union(current_type, | 1416 return Type::Union(current_type, |
1423 Type::Range(new_min, new_max, typer_->zone()), | 1417 Type::Range(new_min, new_max, typer_->zone()), |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2329 | 2323 |
2330 | 2324 |
2331 // Heap constants. | 2325 // Heap constants. |
2332 | 2326 |
2333 | 2327 |
2334 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { | 2328 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { |
2335 if (value->IsJSFunction()) { | 2329 if (value->IsJSFunction()) { |
2336 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { | 2330 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { |
2337 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { | 2331 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { |
2338 case kMathRandom: | 2332 case kMathRandom: |
2339 return typer_->random_fun_; | 2333 return typer_->cache_->Get(kRandomFunc0); |
2340 case kMathFloor: | 2334 case kMathFloor: |
2341 return typer_->weakint_fun1_; | |
2342 case kMathRound: | 2335 case kMathRound: |
2343 return typer_->weakint_fun1_; | |
2344 case kMathCeil: | 2336 case kMathCeil: |
2345 return typer_->weakint_fun1_; | 2337 return typer_->cache_->Get(kWeakintFunc1); |
2346 // Unary math functions. | 2338 // Unary math functions. |
2347 case kMathAbs: // TODO(rossberg): can't express overloading | 2339 case kMathAbs: // TODO(rossberg): can't express overloading |
2348 case kMathLog: | 2340 case kMathLog: |
2349 case kMathExp: | 2341 case kMathExp: |
2350 case kMathSqrt: | 2342 case kMathSqrt: |
2351 case kMathCos: | 2343 case kMathCos: |
2352 case kMathSin: | 2344 case kMathSin: |
2353 case kMathTan: | 2345 case kMathTan: |
2354 case kMathAcos: | 2346 case kMathAcos: |
2355 case kMathAsin: | 2347 case kMathAsin: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2413 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2422 #undef TYPED_ARRAY_CASE | 2414 #undef TYPED_ARRAY_CASE |
2423 } | 2415 } |
2424 } | 2416 } |
2425 return Type::Constant(value, zone()); | 2417 return Type::Constant(value, zone()); |
2426 } | 2418 } |
2427 | 2419 |
2428 } // namespace compiler | 2420 } // namespace compiler |
2429 } // namespace internal | 2421 } // namespace internal |
2430 } // namespace v8 | 2422 } // namespace v8 |
OLD | NEW |