Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_TYPES_H_
6 : #define V8_COMPILER_TYPES_H_
7 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/conversions.h"
10 : #include "src/globals.h"
11 : #include "src/handles.h"
12 : #include "src/objects.h"
13 : #include "src/ostreams.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 :
19 : // SUMMARY
20 : //
21 : // A simple type system for compiler-internal use. It is based entirely on
22 : // union types, and all subtyping hence amounts to set inclusion. Besides the
23 : // obvious primitive types and some predefined unions, the type language also
24 : // can express class types (a.k.a. specific maps) and singleton types (i.e.,
25 : // concrete constants).
26 : //
27 : // The following equations and inequations hold:
28 : //
29 : // None <= T
30 : // T <= Any
31 : //
32 : // Number = Signed32 \/ Unsigned32 \/ Double
33 : // Smi <= Signed32
34 : // Name = String \/ Symbol
35 : // UniqueName = InternalizedString \/ Symbol
36 : // InternalizedString < String
37 : //
38 : // Receiver = Object \/ Proxy
39 : // OtherUndetectable < Object
40 : // DetectableReceiver = Receiver - OtherUndetectable
41 : //
42 : // Constant(x) < T iff instance_type(map(x)) < T
43 : //
44 : //
45 : // RANGE TYPES
46 : //
47 : // A range type represents a continuous integer interval by its minimum and
48 : // maximum value. Either value may be an infinity, in which case that infinity
49 : // itself is also included in the range. A range never contains NaN or -0.
50 : //
51 : // If a value v happens to be an integer n, then Constant(v) is considered a
52 : // subtype of Range(n, n) (and therefore also a subtype of any larger range).
53 : // In order to avoid large unions, however, it is usually a good idea to use
54 : // Range rather than Constant.
55 : //
56 : //
57 : // PREDICATES
58 : //
59 : // There are two main functions for testing types:
60 : //
61 : // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
62 : // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
63 : //
64 : // Typically, the former is to be used to select representations (e.g., via
65 : // T->Is(SignedSmall())), and the latter to check whether a specific case needs
66 : // handling (e.g., via T->Maybe(Number())).
67 : //
68 : // There is no functionality to discover whether a type is a leaf in the
69 : // lattice. That is intentional. It should always be possible to refine the
70 : // lattice (e.g., splitting up number types further) without invalidating any
71 : // existing assumptions or tests.
72 : // Consequently, do not normally use Equals for type tests, always use Is!
73 : //
74 : // The NowIs operator implements state-sensitive subtying, as described above.
75 : // Any compilation decision based on such temporary properties requires runtime
76 : // guarding!
77 : //
78 : //
79 : // PROPERTIES
80 : //
81 : // Various formal properties hold for constructors, operators, and predicates
82 : // over types. For example, constructors are injective and subtyping is a
83 : // complete partial order.
84 : //
85 : // See test/cctest/test-types.cc for a comprehensive executable specification,
86 : // especially with respect to the properties of the more exotic 'temporal'
87 : // constructors and predicates (those prefixed 'Now').
88 : //
89 : //
90 : // IMPLEMENTATION
91 : //
92 : // Internally, all 'primitive' types, and their unions, are represented as
93 : // bitsets. Bit 0 is reserved for tagging. Only structured types require
94 : // allocation.
95 :
96 : // -----------------------------------------------------------------------------
97 : // Values for bitset types
98 :
99 : // clang-format off
100 :
101 : #define INTERNAL_BITSET_TYPE_LIST(V) \
102 : V(OtherUnsigned31, 1u << 1) \
103 : V(OtherUnsigned32, 1u << 2) \
104 : V(OtherSigned32, 1u << 3) \
105 : V(OtherNumber, 1u << 4) \
106 :
107 : #define PROPER_BITSET_TYPE_LIST(V) \
108 : V(None, 0u) \
109 : V(Negative31, 1u << 5) \
110 : V(Null, 1u << 6) \
111 : V(Undefined, 1u << 7) \
112 : V(Boolean, 1u << 8) \
113 : V(Unsigned30, 1u << 9) \
114 : V(MinusZero, 1u << 10) \
115 : V(NaN, 1u << 11) \
116 : V(Symbol, 1u << 12) \
117 : V(InternalizedNonSeqString, 1u << 13) \
118 : V(InternalizedSeqString, 1u << 14) \
119 : V(OtherNonSeqString, 1u << 15) \
120 : V(OtherSeqString, 1u << 16) \
121 : V(OtherCallable, 1u << 17) \
122 : V(OtherObject, 1u << 18) \
123 : V(OtherUndetectable, 1u << 19) \
124 : V(CallableProxy, 1u << 20) \
125 : V(OtherProxy, 1u << 21) \
126 : V(Function, 1u << 22) \
127 : V(BoundFunction, 1u << 23) \
128 : V(Hole, 1u << 24) \
129 : V(OtherInternal, 1u << 25) \
130 : V(ExternalPointer, 1u << 26) \
131 : V(Array, 1u << 27) \
132 : \
133 : V(Signed31, kUnsigned30 | kNegative31) \
134 : V(Signed32, kSigned31 | kOtherUnsigned31 | \
135 : kOtherSigned32) \
136 : V(Signed32OrMinusZero, kSigned32 | kMinusZero) \
137 : V(Signed32OrMinusZeroOrNaN, kSigned32 | kMinusZero | kNaN) \
138 : V(Negative32, kNegative31 | kOtherSigned32) \
139 : V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \
140 : V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | \
141 : kOtherUnsigned32) \
142 : V(Unsigned32OrMinusZero, kUnsigned32 | kMinusZero) \
143 : V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \
144 : V(Integral32, kSigned32 | kUnsigned32) \
145 : V(Integral32OrMinusZero, kIntegral32 | kMinusZero) \
146 : V(Integral32OrMinusZeroOrNaN, kIntegral32OrMinusZero | kNaN) \
147 : V(PlainNumber, kIntegral32 | kOtherNumber) \
148 : V(OrderedNumber, kPlainNumber | kMinusZero) \
149 : V(MinusZeroOrNaN, kMinusZero | kNaN) \
150 : V(Number, kOrderedNumber | kNaN) \
151 : V(InternalizedString, kInternalizedNonSeqString | \
152 : kInternalizedSeqString) \
153 : V(OtherString, kOtherNonSeqString | kOtherSeqString) \
154 : V(SeqString, kInternalizedSeqString | kOtherSeqString) \
155 : V(NonSeqString, kInternalizedNonSeqString | \
156 : kOtherNonSeqString) \
157 : V(String, kInternalizedString | kOtherString) \
158 : V(UniqueName, kSymbol | kInternalizedString) \
159 : V(Name, kSymbol | kString) \
160 : V(InternalizedStringOrNull, kInternalizedString | kNull) \
161 : V(BooleanOrNumber, kBoolean | kNumber) \
162 : V(BooleanOrNullOrNumber, kBooleanOrNumber | kNull) \
163 : V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
164 : V(Oddball, kBooleanOrNullOrUndefined | kHole) \
165 : V(NullOrNumber, kNull | kNumber) \
166 : V(NullOrUndefined, kNull | kUndefined) \
167 : V(Undetectable, kNullOrUndefined | kOtherUndetectable) \
168 : V(NumberOrHole, kNumber | kHole) \
169 : V(NumberOrOddball, kNumber | kNullOrUndefined | kBoolean | \
170 : kHole) \
171 : V(NumberOrString, kNumber | kString) \
172 : V(NumberOrUndefined, kNumber | kUndefined) \
173 : V(NumberOrUndefinedOrNullOrBoolean, \
174 : kNumber | kNullOrUndefined | kBoolean) \
175 : V(PlainPrimitive, kNumberOrString | kBoolean | \
176 : kNullOrUndefined) \
177 : V(Primitive, kSymbol | kPlainPrimitive) \
178 : V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
179 : V(Proxy, kCallableProxy | kOtherProxy) \
180 : V(ArrayOrOtherObject, kArray | kOtherObject) \
181 : V(ArrayOrProxy, kArray | kProxy) \
182 : V(DetectableCallable, kFunction | kBoundFunction | \
183 : kOtherCallable | kCallableProxy) \
184 : V(Callable, kDetectableCallable | kOtherUndetectable) \
185 : V(NonCallable, kArray | kOtherObject | kOtherProxy) \
186 : V(NonCallableOrNull, kNonCallable | kNull) \
187 : V(DetectableObject, kArray | kFunction | kBoundFunction | \
188 : kOtherCallable | kOtherObject) \
189 : V(DetectableReceiver, kDetectableObject | kProxy) \
190 : V(DetectableReceiverOrNull, kDetectableReceiver | kNull) \
191 : V(Object, kDetectableObject | kOtherUndetectable) \
192 : V(Receiver, kObject | kProxy) \
193 : V(ReceiverOrUndefined, kReceiver | kUndefined) \
194 : V(ReceiverOrNullOrUndefined, kReceiver | kNull | kUndefined) \
195 : V(SymbolOrReceiver, kSymbol | kReceiver) \
196 : V(StringOrReceiver, kString | kReceiver) \
197 : V(Unique, kBoolean | kUniqueName | kNull | \
198 : kUndefined | kReceiver) \
199 : V(Internal, kHole | kExternalPointer | kOtherInternal) \
200 : V(NonInternal, kPrimitive | kReceiver) \
201 : V(NonNumber, kUnique | kString | kInternal) \
202 : V(Any, 0xfffffffeu)
203 :
204 : // clang-format on
205 :
206 : /*
207 : * The following diagrams show how integers (in the mathematical sense) are
208 : * divided among the different atomic numerical types.
209 : *
210 : * ON OS32 N31 U30 OU31 OU32 ON
211 : * ______[_______[_______[_______[_______[_______[_______
212 : * -2^31 -2^30 0 2^30 2^31 2^32
213 : *
214 : * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
215 : *
216 : * Some of the atomic numerical bitsets are internal only (see
217 : * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in
218 : * union with certain other bitsets. For instance, OtherNumber should only
219 : * occur as part of PlainNumber.
220 : */
221 :
222 : #define BITSET_TYPE_LIST(V) \
223 : INTERNAL_BITSET_TYPE_LIST(V) \
224 : PROPER_BITSET_TYPE_LIST(V)
225 :
226 : class Type;
227 :
228 : // -----------------------------------------------------------------------------
229 : // Bitset types (internal).
230 :
231 : class V8_EXPORT_PRIVATE BitsetType {
232 : public:
233 : typedef uint32_t bitset; // Internal
234 :
235 : enum : uint32_t {
236 : #define DECLARE_TYPE(type, value) k##type = (value),
237 : BITSET_TYPE_LIST(DECLARE_TYPE)
238 : #undef DECLARE_TYPE
239 : kUnusedEOL = 0
240 : };
241 :
242 : static bitset SignedSmall();
243 : static bitset UnsignedSmall();
244 :
245 : bitset Bitset() {
246 445257411 : return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
247 : }
248 :
249 248 : static bool IsInhabited(bitset bits) { return bits != kNone; }
250 :
251 : static bool Is(bitset bits1, bitset bits2) {
252 247260719 : return (bits1 | bits2) == bits2;
253 : }
254 :
255 : static double Min(bitset);
256 : static double Max(bitset);
257 :
258 : static bitset Glb(Type* type); // greatest lower bound that's a bitset
259 : static bitset Glb(double min, double max);
260 : static bitset Lub(Type* type); // least upper bound that's a bitset
261 : static bitset Lub(i::Map* map);
262 : static bitset Lub(i::Object* value);
263 : static bitset Lub(double value);
264 : static bitset Lub(double min, double max);
265 : static bitset ExpandInternals(bitset bits);
266 :
267 : static const char* Name(bitset);
268 : static void Print(std::ostream& os, bitset); // NOLINT
269 : #ifdef DEBUG
270 : static void Print(bitset);
271 : #endif
272 :
273 : static bitset NumberBits(bitset bits);
274 :
275 : static bool IsBitset(Type* type) {
276 1030328525 : return reinterpret_cast<uintptr_t>(type) & 1;
277 : }
278 :
279 : static Type* NewForTesting(bitset bits) { return New(bits); }
280 :
281 : private:
282 : friend class Type;
283 :
284 : static Type* New(bitset bits) {
285 44184179 : return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
286 : }
287 :
288 : struct Boundary {
289 : bitset internal;
290 : bitset external;
291 : double min;
292 : };
293 : static const Boundary BoundariesArray[];
294 : static inline const Boundary* Boundaries();
295 : static inline size_t BoundariesSize();
296 : };
297 :
298 : // -----------------------------------------------------------------------------
299 : // Superclass for non-bitset types (internal).
300 : class TypeBase {
301 : protected:
302 : friend class Type;
303 :
304 : enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
305 :
306 900698879 : Kind kind() const { return kind_; }
307 47459381 : explicit TypeBase(Kind kind) : kind_(kind) {}
308 :
309 : static bool IsKind(Type* type, Kind kind) {
310 948442477 : if (BitsetType::IsBitset(type)) return false;
311 : TypeBase* base = reinterpret_cast<TypeBase*>(type);
312 900698879 : return base->kind() == kind;
313 : }
314 :
315 : // The hacky conversion to/from Type*.
316 : static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
317 : static TypeBase* FromType(Type* type) {
318 : return reinterpret_cast<TypeBase*>(type);
319 : }
320 :
321 : private:
322 : Kind kind_;
323 : };
324 :
325 : // -----------------------------------------------------------------------------
326 : // Constant types.
327 :
328 : class OtherNumberConstantType : public TypeBase {
329 : public:
330 : double Value() { return value_; }
331 :
332 : static bool IsOtherNumberConstant(double value);
333 : static bool IsOtherNumberConstant(Object* value);
334 :
335 : private:
336 : friend class Type;
337 : friend class BitsetType;
338 :
339 1796142 : static Type* New(double value, Zone* zone) {
340 : return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
341 1796142 : OtherNumberConstantType(value)); // NOLINT
342 : }
343 :
344 : static OtherNumberConstantType* cast(Type* type) {
345 : DCHECK(IsKind(type, kOtherNumberConstant));
346 : return static_cast<OtherNumberConstantType*>(FromType(type));
347 : }
348 :
349 1796142 : explicit OtherNumberConstantType(double value)
350 1796142 : : TypeBase(kOtherNumberConstant), value_(value) {
351 1796142 : CHECK(IsOtherNumberConstant(value));
352 1796142 : }
353 :
354 : BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }
355 :
356 : double value_;
357 : };
358 :
359 : class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
360 : public:
361 : i::Handle<i::HeapObject> Value() { return object_; }
362 :
363 : private:
364 : friend class Type;
365 : friend class BitsetType;
366 :
367 10803604 : static Type* New(i::Handle<i::HeapObject> value, Zone* zone) {
368 10803604 : BitsetType::bitset bitset = BitsetType::Lub(*value);
369 : return AsType(new (zone->New(sizeof(HeapConstantType)))
370 17149251 : HeapConstantType(bitset, value));
371 : }
372 :
373 : static HeapConstantType* cast(Type* type) {
374 : DCHECK(IsKind(type, kHeapConstant));
375 : return static_cast<HeapConstantType*>(FromType(type));
376 : }
377 :
378 : HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
379 :
380 : BitsetType::bitset Lub() { return bitset_; }
381 :
382 : BitsetType::bitset bitset_;
383 : Handle<i::HeapObject> object_;
384 : };
385 :
386 : // -----------------------------------------------------------------------------
387 : // Range types.
388 :
389 : class RangeType : public TypeBase {
390 : public:
391 : struct Limits {
392 : double min;
393 : double max;
394 15841756 : Limits(double min, double max) : min(min), max(max) {}
395 4505419 : explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
396 : bool IsEmpty();
397 : static Limits Empty() { return Limits(1, 0); }
398 : static Limits Intersect(Limits lhs, Limits rhs);
399 : static Limits Union(Limits lhs, Limits rhs);
400 : };
401 :
402 : double Min() { return limits_.min; }
403 : double Max() { return limits_.max; }
404 :
405 : private:
406 : friend class Type;
407 : friend class BitsetType;
408 : friend class UnionType;
409 :
410 : static Type* New(double min, double max, Zone* zone) {
411 15841756 : return New(Limits(min, max), zone);
412 : }
413 :
414 : static bool IsInteger(double x) {
415 : return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
416 : }
417 :
418 19436674 : static Type* New(Limits lim, Zone* zone) {
419 : DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
420 : DCHECK(lim.min <= lim.max);
421 8351320 : BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
422 :
423 38873262 : return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
424 : }
425 :
426 : static RangeType* cast(Type* type) {
427 : DCHECK(IsKind(type, kRange));
428 : return static_cast<RangeType*>(FromType(type));
429 : }
430 :
431 : RangeType(BitsetType::bitset bitset, Limits limits)
432 19436452 : : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
433 :
434 : BitsetType::bitset Lub() { return bitset_; }
435 :
436 : BitsetType::bitset bitset_;
437 : Limits limits_;
438 : };
439 :
440 : // -----------------------------------------------------------------------------
441 : // Superclass for types with variable number of type fields.
442 : class StructuralType : public TypeBase {
443 : public:
444 3328 : int LengthForTesting() { return Length(); }
445 :
446 : protected:
447 : friend class Type;
448 :
449 : int Length() { return length_; }
450 :
451 : Type* Get(int i) {
452 : DCHECK(0 <= i && i < this->Length());
453 214178011 : return elements_[i];
454 : }
455 :
456 : void Set(int i, Type* type) {
457 : DCHECK(0 <= i && i < this->Length());
458 41593523 : elements_[i] = type;
459 : }
460 :
461 : void Shrink(int length) {
462 : DCHECK(2 <= length && length <= this->Length());
463 13348100 : length_ = length;
464 : }
465 :
466 : StructuralType(Kind kind, int length, i::Zone* zone)
467 15423185 : : TypeBase(kind), length_(length) {
468 15423185 : elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
469 : }
470 :
471 : private:
472 : int length_;
473 : Type** elements_;
474 : };
475 :
476 : // -----------------------------------------------------------------------------
477 : // Tuple types.
478 :
479 : class TupleType : public StructuralType {
480 : public:
481 4559 : int Arity() { return this->Length(); }
482 4569 : Type* Element(int i) { return this->Get(i); }
483 :
484 4560 : void InitElement(int i, Type* type) { this->Set(i, type); }
485 :
486 : private:
487 : friend class Type;
488 :
489 : TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
490 :
491 1520 : static Type* New(int length, Zone* zone) {
492 3040 : return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
493 : }
494 :
495 : static TupleType* cast(Type* type) {
496 : DCHECK(IsKind(type, kTuple));
497 : return static_cast<TupleType*>(FromType(type));
498 : }
499 : };
500 :
501 : // -----------------------------------------------------------------------------
502 : // Union types (internal).
503 : // A union is a structured type with the following invariants:
504 : // - its length is at least 2
505 : // - at most one field is a bitset, and it must go into index 0
506 : // - no field is a union
507 : // - no field is a subtype of any other field
508 : class UnionType : public StructuralType {
509 : private:
510 : friend Type;
511 : friend BitsetType;
512 :
513 : UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
514 :
515 15421691 : static Type* New(int length, Zone* zone) {
516 30843280 : return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
517 : }
518 :
519 : static UnionType* cast(Type* type) {
520 : DCHECK(IsKind(type, kUnion));
521 : return static_cast<UnionType*>(FromType(type));
522 : }
523 :
524 : bool Wellformed();
525 : };
526 :
527 : class V8_EXPORT_PRIVATE Type {
528 : public:
529 : typedef BitsetType::bitset bitset; // Internal
530 :
531 : // Constructors.
532 : #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
533 : static Type* type() { return BitsetType::New(BitsetType::k##type); }
534 : PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
535 : #undef DEFINE_TYPE_CONSTRUCTOR
536 :
537 : static Type* SignedSmall() {
538 4530810 : return BitsetType::New(BitsetType::SignedSmall());
539 : }
540 : static Type* UnsignedSmall() {
541 68911 : return BitsetType::New(BitsetType::UnsignedSmall());
542 : }
543 :
544 : static Type* OtherNumberConstant(double value, Zone* zone) {
545 1796142 : return OtherNumberConstantType::New(value, zone);
546 : }
547 : static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) {
548 10803607 : return HeapConstantType::New(value, zone);
549 : }
550 : static Type* Range(double min, double max, Zone* zone) {
551 : return RangeType::New(min, max, zone);
552 : }
553 : static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
554 1520 : Type* tuple = TupleType::New(3, zone);
555 : tuple->AsTuple()->InitElement(0, first);
556 : tuple->AsTuple()->InitElement(1, second);
557 : tuple->AsTuple()->InitElement(2, third);
558 : return tuple;
559 : }
560 :
561 : // NewConstant is a factory that returns Constant, Range or Number.
562 : static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
563 : static Type* NewConstant(double value, Zone* zone);
564 :
565 : static Type* Union(Type* type1, Type* type2, Zone* zone);
566 : static Type* Intersect(Type* type1, Type* type2, Zone* zone);
567 :
568 : static Type* Of(double value, Zone* zone) {
569 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
570 : }
571 2490 : static Type* Of(i::Object* value, Zone* zone) {
572 4980 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
573 : }
574 : static Type* Of(i::Handle<i::Object> value, Zone* zone) {
575 2490 : return Of(*value, zone);
576 : }
577 :
578 11135 : static Type* For(i::Map* map) {
579 22270 : return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map)));
580 : }
581 11135 : static Type* For(i::Handle<i::Map> map) { return For(*map); }
582 :
583 : // Predicates.
584 : bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
585 :
586 283345444 : bool Is(Type* that) { return this == that || this->SlowIs(that); }
587 : bool Maybe(Type* that);
588 352901 : bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
589 :
590 : // Inspection.
591 : bool IsRange() { return IsKind(TypeBase::kRange); }
592 : bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
593 : bool IsOtherNumberConstant() {
594 : return IsKind(TypeBase::kOtherNumberConstant);
595 : }
596 : bool IsTuple() { return IsKind(TypeBase::kTuple); }
597 :
598 : HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
599 : OtherNumberConstantType* AsOtherNumberConstant() {
600 : return OtherNumberConstantType::cast(this);
601 : }
602 : RangeType* AsRange() { return RangeType::cast(this); }
603 : TupleType* AsTuple() { return TupleType::cast(this); }
604 :
605 : // Minimum and maximum of a numeric type.
606 : // These functions do not distinguish between -0 and +0. If the type equals
607 : // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
608 : // functions on subtypes of Number.
609 : double Min();
610 : double Max();
611 :
612 : // Extracts a range from the type: if the type is a range or a union
613 : // containing a range, that range is returned; otherwise, nullptr is returned.
614 : Type* GetRange();
615 :
616 : static bool IsInteger(i::Object* x);
617 : static bool IsInteger(double x) {
618 16915343 : return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
619 : }
620 :
621 : int NumConstants();
622 :
623 : // Printing.
624 :
625 : void PrintTo(std::ostream& os);
626 :
627 : #ifdef DEBUG
628 : void Print();
629 : #endif
630 :
631 : // Helpers for testing.
632 : bool IsBitsetForTesting() { return IsBitset(); }
633 : bool IsUnionForTesting() { return IsUnion(); }
634 : bitset AsBitsetForTesting() { return AsBitset(); }
635 : UnionType* AsUnionForTesting() { return AsUnion(); }
636 :
637 : private:
638 : // Friends.
639 : template <class>
640 : friend class Iterator;
641 : friend BitsetType;
642 : friend UnionType;
643 :
644 : // Internal inspection.
645 : bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
646 :
647 : bool IsNone() { return this == None(); }
648 : bool IsAny() { return this == Any(); }
649 : bool IsBitset() { return BitsetType::IsBitset(this); }
650 : bool IsUnion() { return IsKind(TypeBase::kUnion); }
651 :
652 : bitset AsBitset() {
653 : DCHECK(this->IsBitset());
654 : return reinterpret_cast<BitsetType*>(this)->Bitset();
655 : }
656 : UnionType* AsUnion() { return UnionType::cast(this); }
657 :
658 84002293 : bitset BitsetGlb() { return BitsetType::Glb(this); }
659 264149547 : bitset BitsetLub() { return BitsetType::Lub(this); }
660 :
661 : bool SlowIs(Type* that);
662 :
663 : static bool Overlap(RangeType* lhs, RangeType* rhs);
664 : static bool Contains(RangeType* lhs, RangeType* rhs);
665 : static bool Contains(RangeType* range, i::Object* val);
666 :
667 : static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
668 :
669 : static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
670 : Zone* zone);
671 : static RangeType::Limits ToLimits(bitset bits, Zone* zone);
672 :
673 : bool SimplyEquals(Type* that);
674 :
675 : static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
676 : static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
677 : RangeType::Limits* limits, Zone* zone);
678 : static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
679 : static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
680 : };
681 :
682 : } // namespace compiler
683 : } // namespace internal
684 : } // namespace v8
685 :
686 : #endif // V8_COMPILER_TYPES_H_
|