Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/typer.cc

Issue 1209513002: [turbofan] Make TyperCache global and thread safe. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/typer.h"
6
5 #include "src/base/flags.h" 7 #include "src/base/flags.h"
8 #include "src/base/lazy-instance.h"
6 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
7 #include "src/compiler/graph-reducer.h" 10 #include "src/compiler/graph-reducer.h"
8 #include "src/compiler/js-operator.h" 11 #include "src/compiler/js-operator.h"
9 #include "src/compiler/node.h" 12 #include "src/compiler/node.h"
10 #include "src/compiler/node-properties.h" 13 #include "src/compiler/node-properties.h"
11 #include "src/compiler/simplified-operator.h" 14 #include "src/compiler/simplified-operator.h"
12 #include "src/compiler/typer.h"
13 15
14 namespace v8 { 16 namespace v8 {
15 namespace internal { 17 namespace internal {
16 namespace compiler { 18 namespace compiler {
17 19
18 #define NATIVE_TYPES(V) \ 20 class TyperCache final {
19 V(Int8) \ 21 private:
20 V(Uint8) \ 22 // This has to be first for the initialization magic to work.
21 V(Int16) \ 23 Zone zone_;
22 V(Uint16) \
23 V(Int32) \
24 V(Uint32) \
25 V(Float32) \
26 V(Float64)
27 24
28 enum LazyCachedType { 25 public:
29 kInteger, 26 TyperCache() = default;
30 kWeakint,
31 kWeakintFunc1,
32 kRandomFunc0,
33 kAnyFunc0,
34 kAnyFunc1,
35 kAnyFunc2,
36 kAnyFunc3,
37 kNumberFunc0,
38 kNumberFunc1,
39 kNumberFunc2,
40 kImulFunc,
41 kClz32Func,
42 kArrayBufferFunc,
43 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
44 k##Type, k##Type##Array, k##Type##ArrayFunc,
45 TYPED_ARRAYS(TYPED_ARRAY_CASE)
46 #undef TYPED_ARRAY_CASE
47 kNumLazyCachedTypes
48 };
49 27
28 Type* const kInt8 =
29 CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
30 Type* const kUint8 =
31 CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
32 Type* const kUint8Clamped = kUint8;
33 Type* const kInt16 =
34 CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
35 Type* const kUint16 =
36 CreateNative(CreateRange<uint16_t>(), Type::UntaggedUnsigned16());
37 Type* const kInt32 = CreateNative(Type::Signed32(), Type::UntaggedSigned32());
38 Type* const kUint32 =
39 CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
40 Type* const kFloat32 = CreateNative(Type::Number(), Type::UntaggedFloat32());
41 Type* const kFloat64 = CreateNative(Type::Number(), Type::UntaggedFloat64());
50 42
51 // Constructs and caches types lazily. 43 Type* const kSingletonZero = CreateRange(0.0, 0.0);
52 // TODO(turbofan): these types could be globally cached or cached per isolate. 44 Type* const kSingletonOne = CreateRange(1.0, 1.0);
53 class LazyTypeCache final : public ZoneObject { 45 Type* const kZeroOrOne = CreateRange(0.0, 1.0);
54 public: 46 Type* const kZeroish =
55 explicit LazyTypeCache(Isolate* isolate, Zone* zone) 47 Type::Union(kSingletonZero, Type::MinusZeroOrNaN(), zone());
56 : isolate_(isolate), zone_(zone) { 48 Type* const kInteger = CreateRange(-V8_INFINITY, V8_INFINITY);
57 memset(cache_, 0, sizeof(cache_)); 49 Type* const kWeakint = Type::Union(kInteger, Type::MinusZeroOrNaN(), zone());
58 } 50 Type* const kWeakintFunc1 = Type::Function(kWeakint, Type::Number(), zone());
59 51
60 V8_INLINE Type* Get(LazyCachedType type) { 52 Type* const kRandomFunc0 = Type::Function(Type::OrderedNumber(), zone());
61 int const index = static_cast<int>(type); 53 Type* const kAnyFunc0 = Type::Function(Type::Any(), zone());
62 DCHECK_LT(index, kNumLazyCachedTypes); 54 Type* const kAnyFunc1 = Type::Function(Type::Any(), Type::Any(), zone());
63 if (cache_[index] == NULL) cache_[index] = Create(type); 55 Type* const kAnyFunc2 =
64 return cache_[index]; 56 Type::Function(Type::Any(), Type::Any(), Type::Any(), zone());
65 } 57 Type* const kAnyFunc3 = Type::Function(Type::Any(), Type::Any(), Type::Any(),
58 Type::Any(), zone());
59 Type* const kNumberFunc0 = Type::Function(Type::Number(), zone());
60 Type* const kNumberFunc1 =
61 Type::Function(Type::Number(), Type::Number(), zone());
62 Type* const kNumberFunc2 =
63 Type::Function(Type::Number(), Type::Number(), Type::Number(), zone());
64 Type* const kImulFunc = Type::Function(Type::Signed32(), Type::Integral32(),
65 Type::Integral32(), zone());
66 Type* const kClz32Func =
67 Type::Function(CreateRange(0, 32), Type::Number(), zone());
68 Type* const kArrayBufferFunc =
69 Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
70
71 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
72 Type* const k##TypeName##Array = CreateArray(k##TypeName); \
73 Type* const k##TypeName##ArrayFunc = CreateArrayFunction(k##TypeName##Array);
74 TYPED_ARRAYS(TYPED_ARRAY)
75 #undef TYPED_ARRAY
66 76
67 private: 77 private:
68 Type* Create(LazyCachedType type) { 78 Type* CreateArray(Type* element) { return Type::Array(element, zone()); }
69 switch (type) {
70 case kInt8:
71 return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
72 case kUint8:
73 return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
74 case kInt16:
75 return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
76 case kUint16:
77 return CreateNative(CreateRange<uint16_t>(),
78 Type::UntaggedUnsigned16());
79 case kInt32:
80 return CreateNative(Type::Signed32(), Type::UntaggedSigned32());
81 case kUint32:
82 return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
83 case kFloat32:
84 return CreateNative(Type::Number(), Type::UntaggedFloat32());
85 case kFloat64:
86 return CreateNative(Type::Number(), Type::UntaggedFloat64());
87 case kUint8Clamped:
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());
97 case kAnyFunc0:
98 return Type::Function(Type::Any(), zone());
99 case kAnyFunc1:
100 return Type::Function(Type::Any(), Type::Any(), zone());
101 case kAnyFunc2:
102 return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone());
103 case kAnyFunc3:
104 return Type::Function(Type::Any(), Type::Any(), Type::Any(),
105 Type::Any(), zone());
106 case kNumberFunc0:
107 return Type::Function(Type::Number(), zone());
108 case kNumberFunc1:
109 return Type::Function(Type::Number(), Type::Number(), zone());
110 case kNumberFunc2:
111 return Type::Function(Type::Number(), Type::Number(), Type::Number(),
112 zone());
113 case kImulFunc:
114 return Type::Function(Type::Signed32(), Type::Integral32(),
115 Type::Integral32(), zone());
116 case kClz32Func:
117 return Type::Function(CreateRange(0, 32), Type::Number(), zone());
118 case kArrayBufferFunc:
119 return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
120 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
121 case k##Type##Array: \
122 return CreateArray(Get(k##Type)); \
123 case k##Type##ArrayFunc: \
124 return CreateArrayFunction(Get(k##Type##Array));
125 TYPED_ARRAYS(TYPED_ARRAY_CASE)
126 #undef TYPED_ARRAY_CASE
127 case kNumLazyCachedTypes:
128 break;
129 }
130 UNREACHABLE();
131 return NULL;
132 }
133 79
134 Type* CreateArray(Type* element) const { 80 Type* CreateArrayFunction(Type* array) {
135 return Type::Array(element, zone());
136 }
137
138 Type* CreateArrayFunction(Type* array) const {
139 Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone()); 81 Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
140 Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone()); 82 Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
141 Type* arg3 = arg2; 83 Type* arg3 = arg2;
142 return Type::Function(array, arg1, arg2, arg3, zone()); 84 return Type::Function(array, arg1, arg2, arg3, zone());
143 } 85 }
144 86
145 Type* CreateNative(Type* semantic, Type* representation) const { 87 Type* CreateNative(Type* semantic, Type* representation) {
146 return Type::Intersect(semantic, representation, zone()); 88 return Type::Intersect(semantic, representation, zone());
147 } 89 }
148 90
149 template <typename T> 91 template <typename T>
150 Type* CreateRange() const { 92 Type* CreateRange() {
151 return CreateRange(std::numeric_limits<T>::min(), 93 return CreateRange(std::numeric_limits<T>::min(),
152 std::numeric_limits<T>::max()); 94 std::numeric_limits<T>::max());
153 } 95 }
154 96
155 Type* CreateRange(double min, double max) const { 97 Type* CreateRange(double min, double max) {
156 return Type::Range(min, max, zone()); 98 return Type::Range(min, max, zone());
157 } 99 }
158 100
159 Factory* factory() const { return isolate()->factory(); } 101 Zone* zone() { return &zone_; }
160 Isolate* isolate() const { return isolate_; } 102 };
161 Zone* zone() const { return zone_; }
162 103
163 Type* cache_[kNumLazyCachedTypes]; 104
164 Isolate* isolate_; 105 namespace {
165 Zone* zone_; 106
166 }; 107 base::LazyInstance<TyperCache>::type kCache = LAZY_INSTANCE_INITIALIZER;
108
109 } // namespace
167 110
168 111
169 class Typer::Decorator final : public GraphDecorator { 112 class Typer::Decorator final : public GraphDecorator {
170 public: 113 public:
171 explicit Decorator(Typer* typer) : typer_(typer) {} 114 explicit Decorator(Typer* typer) : typer_(typer) {}
172 void Decorate(Node* node) final; 115 void Decorate(Node* node) final;
173 116
174 private: 117 private:
175 Typer* typer_; 118 Typer* const typer_;
176 }; 119 };
177 120
178 121
179 Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type, 122 Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type,
180 MaybeHandle<Context> context) 123 MaybeHandle<Context> context)
181 : isolate_(isolate), 124 : isolate_(isolate),
182 graph_(graph), 125 graph_(graph),
183 function_type_(function_type), 126 function_type_(function_type),
184 context_(context), 127 context_(context),
185 decorator_(NULL), 128 decorator_(nullptr),
186 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) { 129 cache_(kCache.Get()) {
187 Zone* zone = this->zone(); 130 Zone* zone = this->zone();
188 Factory* const factory = isolate->factory(); 131 Factory* const factory = isolate->factory();
189 132
190 Type* infinity = Type::Constant(factory->infinity_value(), zone); 133 Type* infinity = Type::Constant(factory->infinity_value(), zone);
191 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); 134 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
192 Type* truncating_to_zero = 135 Type* truncating_to_zero =
193 Type::Union(Type::Union(infinity, minus_infinity, zone), 136 Type::Union(Type::Union(infinity, minus_infinity, zone),
194 Type::MinusZeroOrNaN(), zone); 137 Type::MinusZeroOrNaN(), zone);
195 138
196 singleton_false_ = Type::Constant(factory->false_value(), zone); 139 singleton_false_ = Type::Constant(factory->false_value(), zone);
197 singleton_true_ = Type::Constant(factory->true_value(), zone); 140 singleton_true_ = Type::Constant(factory->true_value(), zone);
198 singleton_zero_ = Type::Range(0.0, 0.0, zone);
199 singleton_one_ = Type::Range(1.0, 1.0, zone);
200 zero_or_one_ = Type::Range(0.0, 1.0, zone);
201 zeroish_ = Type::Union(singleton_zero_, Type::MinusZeroOrNaN(), zone);
202 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); 141 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
203 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); 142 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
204 falsish_ = 143 falsish_ = Type::Union(
205 Type::Union(Type::Undetectable(), 144 Type::Undetectable(),
206 Type::Union(Type::Union(singleton_false_, zeroish_, zone), 145 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
207 Type::NullOrUndefined(), zone), 146 Type::NullOrUndefined(), zone),
208 zone); 147 zone);
209 truish_ = Type::Union( 148 truish_ = Type::Union(
210 singleton_true_, 149 singleton_true_,
211 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); 150 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
212 151
213 decorator_ = new (zone) Decorator(this); 152 decorator_ = new (zone) Decorator(this);
214 graph_->AddDecorator(decorator_); 153 graph_->AddDecorator(decorator_);
215 } 154 }
216 155
217 156
218 Typer::~Typer() { 157 Typer::~Typer() {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 : t->singleton_false_; 459 : t->singleton_false_;
521 } 460 }
522 // Type should be non empty, so we know it should be true. 461 // Type should be non empty, so we know it should be true.
523 DCHECK((outcome & kComparisonTrue) != 0); 462 DCHECK((outcome & kComparisonTrue) != 0);
524 return t->singleton_true_; 463 return t->singleton_true_;
525 } 464 }
526 465
527 466
528 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { 467 Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
529 if (type->IsRange()) return type; // Shortcut. 468 if (type->IsRange()) return type; // Shortcut.
530 if (!type->Is(t->cache_->Get(kInteger))) { 469 if (!type->Is(t->cache_.kInteger)) {
531 return type; // Give up on non-integer types. 470 return type; // Give up on non-integer types.
532 } 471 }
533 double min = type->Min(); 472 double min = type->Min();
534 double max = type->Max(); 473 double max = type->Max();
535 // Handle the degenerate case of empty bitset types (such as 474 // Handle the degenerate case of empty bitset types (such as
536 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). 475 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
537 if (std::isnan(min)) { 476 if (std::isnan(min)) {
538 DCHECK(std::isnan(max)); 477 DCHECK(std::isnan(max));
539 return type; 478 return type;
540 } 479 }
(...skipping 19 matching lines...) Expand all
560 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { 499 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
561 return t->singleton_true_; // Ruled out nan, -0 and +0. 500 return t->singleton_true_; // Ruled out nan, -0 and +0.
562 } 501 }
563 return Type::Boolean(); 502 return Type::Boolean();
564 } 503 }
565 504
566 505
567 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { 506 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
568 if (type->Is(Type::Number())) return type; 507 if (type->Is(Type::Number())) return type;
569 if (type->Is(Type::NullOrUndefined())) { 508 if (type->Is(Type::NullOrUndefined())) {
570 if (type->Is(Type::Null())) return t->singleton_zero_; 509 if (type->Is(Type::Null())) return t->cache_.kSingletonZero;
571 if (type->Is(Type::Undefined())) return Type::NaN(); 510 if (type->Is(Type::Undefined())) return Type::NaN();
572 return Type::Union(Type::NaN(), t->singleton_zero_, t->zone()); 511 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone());
573 } 512 }
574 if (type->Is(Type::NumberOrUndefined())) { 513 if (type->Is(Type::NumberOrUndefined())) {
575 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), 514 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
576 Type::NaN(), t->zone()); 515 Type::NaN(), t->zone());
577 } 516 }
578 if (type->Is(t->singleton_false_)) return t->singleton_zero_; 517 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero;
579 if (type->Is(t->singleton_true_)) return t->singleton_one_; 518 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne;
580 if (type->Is(Type::Boolean())) return t->zero_or_one_; 519 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne;
581 if (type->Is(Type::BooleanOrNumber())) { 520 if (type->Is(Type::BooleanOrNumber())) {
582 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), 521 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
583 t->zero_or_one_, t->zone()); 522 t->cache_.kZeroOrOne, t->zone());
584 } 523 }
585 return Type::Number(); 524 return Type::Number();
586 } 525 }
587 526
588 527
589 Type* Typer::Visitor::ToString(Type* type, Typer* t) { 528 Type* Typer::Visitor::ToString(Type* type, Typer* t) {
590 if (type->Is(Type::String())) return type; 529 if (type->Is(Type::String())) return type;
591 return Type::String(); 530 return Type::String();
592 } 531 }
593 532
594 533
595 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { 534 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
596 // TODO(neis): DCHECK(type->Is(Type::Number())); 535 // TODO(neis): DCHECK(type->Is(Type::Number()));
597 if (type->Is(Type::Signed32())) return type; 536 if (type->Is(Type::Signed32())) return type;
598 if (type->Is(t->zeroish_)) return t->singleton_zero_; 537 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
599 if (type->Is(t->signed32ish_)) { 538 if (type->Is(t->signed32ish_)) {
600 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), 539 return Type::Intersect(
601 Type::Signed32(), t->zone()); 540 Type::Union(type, t->cache_.kSingletonZero, t->zone()),
541 Type::Signed32(), t->zone());
602 } 542 }
603 return Type::Signed32(); 543 return Type::Signed32();
604 } 544 }
605 545
606 546
607 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { 547 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
608 // TODO(neis): DCHECK(type->Is(Type::Number())); 548 // TODO(neis): DCHECK(type->Is(Type::Number()));
609 if (type->Is(Type::Unsigned32())) return type; 549 if (type->Is(Type::Unsigned32())) return type;
610 if (type->Is(t->zeroish_)) return t->singleton_zero_; 550 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
611 if (type->Is(t->unsigned32ish_)) { 551 if (type->Is(t->unsigned32ish_)) {
612 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), 552 return Type::Intersect(
613 Type::Unsigned32(), t->zone()); 553 Type::Union(type, t->cache_.kSingletonZero, t->zone()),
554 Type::Unsigned32(), t->zone());
614 } 555 }
615 return Type::Unsigned32(); 556 return Type::Unsigned32();
616 } 557 }
617 558
618 559
619 // ----------------------------------------------------------------------------- 560 // -----------------------------------------------------------------------------
620 561
621 562
622 // Control operators. 563 // Control operators.
623 564
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 double rmin = rhs->Min(); 1099 double rmin = rhs->Min();
1159 double rmax = rhs->Max(); 1100 double rmax = rhs->Max();
1160 results[0] = lmin * rmin; 1101 results[0] = lmin * rmin;
1161 results[1] = lmin * rmax; 1102 results[1] = lmin * rmax;
1162 results[2] = lmax * rmin; 1103 results[2] = lmax * rmin;
1163 results[3] = lmax * rmax; 1104 results[3] = lmax * rmax;
1164 // If the result may be nan, we give up on calculating a precise type, because 1105 // If the result may be nan, we give up on calculating a precise type, because
1165 // the discontinuity makes it too complicated. Note that even if none of the 1106 // the discontinuity makes it too complicated. Note that even if none of the
1166 // "results" above is nan, the actual result may still be, so we have to do a 1107 // "results" above is nan, the actual result may still be, so we have to do a
1167 // different check: 1108 // different check:
1168 bool maybe_nan = (lhs->Maybe(t->singleton_zero_) && 1109 bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
1169 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || 1110 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
1170 (rhs->Maybe(t->singleton_zero_) && 1111 (rhs->Maybe(t->cache_.kSingletonZero) &&
1171 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); 1112 (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
1172 if (maybe_nan) return t->cache_->Get(kWeakint); // Giving up. 1113 if (maybe_nan) return t->cache_.kWeakint; // Giving up.
1173 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero_) && rmin < 0) || 1114 bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
1174 (rhs->Maybe(t->singleton_zero_) && lmin < 0); 1115 (rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
1175 Type* range = 1116 Type* range =
1176 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); 1117 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1177 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) 1118 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
1178 : range; 1119 : range;
1179 } 1120 }
1180 1121
1181 1122
1182 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 1123 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1183 lhs = Rangify(ToNumber(lhs, t), t); 1124 lhs = Rangify(ToNumber(lhs, t), t);
1184 rhs = Rangify(ToNumber(rhs, t), t); 1125 rhs = Rangify(ToNumber(rhs, t), t);
1185 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1126 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1186 if (lhs->IsRange() && rhs->IsRange()) { 1127 if (lhs->IsRange() && rhs->IsRange()) {
1187 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); 1128 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t);
1188 } 1129 }
1189 return Type::Number(); 1130 return Type::Number();
1190 } 1131 }
1191 1132
1192 1133
1193 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 1134 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
1194 lhs = ToNumber(lhs, t); 1135 lhs = ToNumber(lhs, t);
1195 rhs = ToNumber(rhs, t); 1136 rhs = ToNumber(rhs, t);
1196 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1137 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1197 // Division is tricky, so all we do is try ruling out nan. 1138 // Division is tricky, so all we do is try ruling out nan.
1198 // TODO(neis): try ruling out -0 as well? 1139 // TODO(neis): try ruling out -0 as well?
1199 bool maybe_nan = 1140 bool maybe_nan =
1200 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || 1141 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
1201 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 1142 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
1202 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 1143 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
1203 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 1144 return maybe_nan ? Type::Number() : Type::OrderedNumber();
1204 } 1145 }
1205 1146
1206 1147
1207 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, 1148 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
1208 Type::RangeType* rhs, Typer* t) { 1149 Type::RangeType* rhs, Typer* t) {
1209 double lmin = lhs->Min(); 1150 double lmin = lhs->Min();
1210 double lmax = lhs->Max(); 1151 double lmax = lhs->Max();
(...skipping 24 matching lines...) Expand all
1235 result = Type::Union(result, Type::MinusZero(), t->zone()); 1176 result = Type::Union(result, Type::MinusZero(), t->zone());
1236 return result; 1177 return result;
1237 } 1178 }
1238 1179
1239 1180
1240 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 1181 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1241 lhs = ToNumber(lhs, t); 1182 lhs = ToNumber(lhs, t);
1242 rhs = ToNumber(rhs, t); 1183 rhs = ToNumber(rhs, t);
1243 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1184 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1244 1185
1245 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || 1186 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
1246 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { 1187 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
1247 // Result maybe NaN. 1188 // Result maybe NaN.
1248 return Type::Number(); 1189 return Type::Number();
1249 } 1190 }
1250 1191
1251 lhs = Rangify(lhs, t); 1192 lhs = Rangify(lhs, t);
1252 rhs = Rangify(rhs, t); 1193 rhs = Rangify(rhs, t);
1253 if (lhs->IsRange() && rhs->IsRange()) { 1194 if (lhs->IsRange() && rhs->IsRange()) {
1254 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); 1195 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
1255 } 1196 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 static const double kWeakenMaxLimits[] = { 1309 static const double kWeakenMaxLimits[] = {
1369 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, 1310 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1370 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, 1311 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1371 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, 1312 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1372 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, 1313 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1373 70368744177663.0, 140737488355327.0, 281474976710655.0, 1314 70368744177663.0, 140737488355327.0, 281474976710655.0,
1374 562949953421311.0}; 1315 562949953421311.0};
1375 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); 1316 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1376 1317
1377 // If the types have nothing to do with integers, return the types. 1318 // If the types have nothing to do with integers, return the types.
1378 Type* const integer = typer_->cache_->Get(kInteger); 1319 Type* const integer = typer_->cache_.kInteger;
1379 if (!previous_type->Maybe(integer)) { 1320 if (!previous_type->Maybe(integer)) {
1380 return current_type; 1321 return current_type;
1381 } 1322 }
1382 DCHECK(current_type->Maybe(integer)); 1323 DCHECK(current_type->Maybe(integer));
1383 1324
1384 Type* current_integer = Type::Intersect(current_type, integer, zone()); 1325 Type* current_integer = Type::Intersect(current_type, integer, zone());
1385 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); 1326 Type* previous_integer = Type::Intersect(previous_type, integer, zone());
1386 1327
1387 // Once we start weakening a node, we should always weaken. 1328 // Once we start weakening a node, we should always weaken.
1388 if (!IsWeakened(node->id())) { 1329 if (!IsWeakened(node->id())) {
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 return Bounds(FieldAccessOf(node->op()).type); 1773 return Bounds(FieldAccessOf(node->op()).type);
1833 } 1774 }
1834 1775
1835 1776
1836 Bounds Typer::Visitor::TypeLoadBuffer(Node* node) { 1777 Bounds Typer::Visitor::TypeLoadBuffer(Node* node) {
1837 // TODO(bmeurer): This typing is not yet correct. Since we can still access 1778 // TODO(bmeurer): This typing is not yet correct. Since we can still access
1838 // out of bounds, the type in the general case has to include Undefined. 1779 // out of bounds, the type in the general case has to include Undefined.
1839 switch (BufferAccessOf(node->op()).external_array_type()) { 1780 switch (BufferAccessOf(node->op()).external_array_type()) {
1840 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1781 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1841 case kExternal##Type##Array: \ 1782 case kExternal##Type##Array: \
1842 return Bounds(typer_->cache_->Get(k##Type)); 1783 return Bounds(typer_->cache_.k##Type);
1843 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1784 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1844 #undef TYPED_ARRAY_CASE 1785 #undef TYPED_ARRAY_CASE
1845 } 1786 }
1846 UNREACHABLE(); 1787 UNREACHABLE();
1847 return Bounds(); 1788 return Bounds();
1848 } 1789 }
1849 1790
1850 1791
1851 Bounds Typer::Visitor::TypeLoadElement(Node* node) { 1792 Bounds Typer::Visitor::TypeLoadElement(Node* node) {
1852 return Bounds(ElementAccessOf(node->op()).type); 1793 return Bounds(ElementAccessOf(node->op()).type);
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 2280
2340 2281
2341 // Heap constants. 2282 // Heap constants.
2342 2283
2343 2284
2344 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { 2285 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
2345 if (value->IsJSFunction()) { 2286 if (value->IsJSFunction()) {
2346 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { 2287 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
2347 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { 2288 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
2348 case kMathRandom: 2289 case kMathRandom:
2349 return typer_->cache_->Get(kRandomFunc0); 2290 return typer_->cache_.kRandomFunc0;
2350 case kMathFloor: 2291 case kMathFloor:
2351 case kMathRound: 2292 case kMathRound:
2352 case kMathCeil: 2293 case kMathCeil:
2353 return typer_->cache_->Get(kWeakintFunc1); 2294 return typer_->cache_.kWeakintFunc1;
2354 // Unary math functions. 2295 // Unary math functions.
2355 case kMathAbs: // TODO(rossberg): can't express overloading 2296 case kMathAbs: // TODO(rossberg): can't express overloading
2356 case kMathLog: 2297 case kMathLog:
2357 case kMathExp: 2298 case kMathExp:
2358 case kMathSqrt: 2299 case kMathSqrt:
2359 case kMathCos: 2300 case kMathCos:
2360 case kMathSin: 2301 case kMathSin:
2361 case kMathTan: 2302 case kMathTan:
2362 case kMathAcos: 2303 case kMathAcos:
2363 case kMathAsin: 2304 case kMathAsin:
2364 case kMathAtan: 2305 case kMathAtan:
2365 case kMathFround: 2306 case kMathFround:
2366 return typer_->cache_->Get(kNumberFunc1); 2307 return typer_->cache_.kNumberFunc1;
2367 // Binary math functions. 2308 // Binary math functions.
2368 case kMathAtan2: 2309 case kMathAtan2:
2369 case kMathPow: 2310 case kMathPow:
2370 case kMathMax: 2311 case kMathMax:
2371 case kMathMin: 2312 case kMathMin:
2372 return typer_->cache_->Get(kNumberFunc2); 2313 return typer_->cache_.kNumberFunc2;
2373 case kMathImul: 2314 case kMathImul:
2374 return typer_->cache_->Get(kImulFunc); 2315 return typer_->cache_.kImulFunc;
2375 case kMathClz32: 2316 case kMathClz32:
2376 return typer_->cache_->Get(kClz32Func); 2317 return typer_->cache_.kClz32Func;
2377 default: 2318 default:
2378 break; 2319 break;
2379 } 2320 }
2380 } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) { 2321 } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) {
2381 Handle<Context> native = 2322 Handle<Context> native =
2382 handle(context().ToHandleChecked()->native_context(), isolate()); 2323 handle(context().ToHandleChecked()->native_context(), isolate());
2383 if (*value == native->array_buffer_fun()) { 2324 if (*value == native->array_buffer_fun()) {
2384 return typer_->cache_->Get(kArrayBufferFunc); 2325 return typer_->cache_.kArrayBufferFunc;
2385 } else if (*value == native->int8_array_fun()) { 2326 } else if (*value == native->int8_array_fun()) {
2386 return typer_->cache_->Get(kInt8ArrayFunc); 2327 return typer_->cache_.kInt8ArrayFunc;
2387 } else if (*value == native->int16_array_fun()) { 2328 } else if (*value == native->int16_array_fun()) {
2388 return typer_->cache_->Get(kInt16ArrayFunc); 2329 return typer_->cache_.kInt16ArrayFunc;
2389 } else if (*value == native->int32_array_fun()) { 2330 } else if (*value == native->int32_array_fun()) {
2390 return typer_->cache_->Get(kInt32ArrayFunc); 2331 return typer_->cache_.kInt32ArrayFunc;
2391 } else if (*value == native->uint8_array_fun()) { 2332 } else if (*value == native->uint8_array_fun()) {
2392 return typer_->cache_->Get(kUint8ArrayFunc); 2333 return typer_->cache_.kUint8ArrayFunc;
2393 } else if (*value == native->uint16_array_fun()) { 2334 } else if (*value == native->uint16_array_fun()) {
2394 return typer_->cache_->Get(kUint16ArrayFunc); 2335 return typer_->cache_.kUint16ArrayFunc;
2395 } else if (*value == native->uint32_array_fun()) { 2336 } else if (*value == native->uint32_array_fun()) {
2396 return typer_->cache_->Get(kUint32ArrayFunc); 2337 return typer_->cache_.kUint32ArrayFunc;
2397 } else if (*value == native->float32_array_fun()) { 2338 } else if (*value == native->float32_array_fun()) {
2398 return typer_->cache_->Get(kFloat32ArrayFunc); 2339 return typer_->cache_.kFloat32ArrayFunc;
2399 } else if (*value == native->float64_array_fun()) { 2340 } else if (*value == native->float64_array_fun()) {
2400 return typer_->cache_->Get(kFloat64ArrayFunc); 2341 return typer_->cache_.kFloat64ArrayFunc;
2401 } 2342 }
2402 } 2343 }
2403 int const arity = 2344 int const arity =
2404 JSFunction::cast(*value)->shared()->internal_formal_parameter_count(); 2345 JSFunction::cast(*value)->shared()->internal_formal_parameter_count();
2405 switch (arity) { 2346 switch (arity) {
2406 case SharedFunctionInfo::kDontAdaptArgumentsSentinel: 2347 case SharedFunctionInfo::kDontAdaptArgumentsSentinel:
2407 // Some smart optimization at work... &%$!&@+$! 2348 // Some smart optimization at work... &%$!&@+$!
2408 return Type::Any(zone()); 2349 return Type::Any(zone());
2409 case 0: 2350 case 0:
2410 return typer_->cache_->Get(kAnyFunc0); 2351 return typer_->cache_.kAnyFunc0;
2411 case 1: 2352 case 1:
2412 return typer_->cache_->Get(kAnyFunc1); 2353 return typer_->cache_.kAnyFunc1;
2413 case 2: 2354 case 2:
2414 return typer_->cache_->Get(kAnyFunc2); 2355 return typer_->cache_.kAnyFunc2;
2415 case 3: 2356 case 3:
2416 return typer_->cache_->Get(kAnyFunc3); 2357 return typer_->cache_.kAnyFunc3;
2417 default: { 2358 default: {
2418 DCHECK_LT(3, arity); 2359 DCHECK_LT(3, arity);
2419 Type** const params = zone()->NewArray<Type*>(arity); 2360 Type** const params = zone()->NewArray<Type*>(arity);
2420 std::fill(&params[0], &params[arity], Type::Any(zone())); 2361 std::fill(&params[0], &params[arity], Type::Any(zone()));
2421 return Type::Function(Type::Any(zone()), arity, params, zone()); 2362 return Type::Function(Type::Any(zone()), arity, params, zone());
2422 } 2363 }
2423 } 2364 }
2424 } else if (value->IsJSTypedArray()) { 2365 } else if (value->IsJSTypedArray()) {
2425 switch (JSTypedArray::cast(*value)->type()) { 2366 switch (JSTypedArray::cast(*value)->type()) {
2426 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2367 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
2427 case kExternal##Type##Array: \ 2368 case kExternal##Type##Array: \
2428 return typer_->cache_->Get(k##Type##Array); 2369 return typer_->cache_.k##Type##Array;
2429 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2370 TYPED_ARRAYS(TYPED_ARRAY_CASE)
2430 #undef TYPED_ARRAY_CASE 2371 #undef TYPED_ARRAY_CASE
2431 } 2372 }
2432 } 2373 }
2433 return Type::Constant(value, zone()); 2374 return Type::Constant(value, zone());
2434 } 2375 }
2435 2376
2436 } // namespace compiler 2377 } // namespace compiler
2437 } // namespace internal 2378 } // namespace internal
2438 } // namespace v8 2379 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698