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(InternalizedString, 1u << 13) \
118 V(OtherString, 1u << 14) \
119 V(Simd, 1u << 15) \
120 V(OtherObject, 1u << 17) \
121 V(OtherUndetectable, 1u << 16) \
122 V(Proxy, 1u << 18) \
123 V(Function, 1u << 19) \
124 V(Hole, 1u << 20) \
125 V(OtherInternal, 1u << 21) \
126 V(ExternalPointer, 1u << 22) \
127 \
128 V(Signed31, kUnsigned30 | kNegative31) \
129 V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
130 V(Signed32OrMinusZero, kSigned32 | kMinusZero) \
131 V(Signed32OrMinusZeroOrNaN, kSigned32 | kMinusZero | kNaN) \
132 V(Negative32, kNegative31 | kOtherSigned32) \
133 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \
134 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | \
135 kOtherUnsigned32) \
136 V(Unsigned32OrMinusZero, kUnsigned32 | kMinusZero) \
137 V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \
138 V(Integral32, kSigned32 | kUnsigned32) \
139 V(PlainNumber, kIntegral32 | kOtherNumber) \
140 V(OrderedNumber, kPlainNumber | kMinusZero) \
141 V(MinusZeroOrNaN, kMinusZero | kNaN) \
142 V(Number, kOrderedNumber | kNaN) \
143 V(String, kInternalizedString | kOtherString) \
144 V(UniqueName, kSymbol | kInternalizedString) \
145 V(Name, kSymbol | kString) \
146 V(BooleanOrNumber, kBoolean | kNumber) \
147 V(BooleanOrNullOrNumber, kBooleanOrNumber | kNull) \
148 V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
149 V(NullOrNumber, kNull | kNumber) \
150 V(NullOrUndefined, kNull | kUndefined) \
151 V(Undetectable, kNullOrUndefined | kOtherUndetectable) \
152 V(NumberOrOddball, kNumber | kNullOrUndefined | kBoolean | kHole) \
153 V(NumberOrSimdOrString, kNumber | kSimd | kString) \
154 V(NumberOrString, kNumber | kString) \
155 V(NumberOrUndefined, kNumber | kUndefined) \
156 V(PlainPrimitive, kNumberOrString | kBoolean | kNullOrUndefined) \
157 V(Primitive, kSymbol | kSimd | kPlainPrimitive) \
158 V(DetectableReceiver, kFunction | kOtherObject | kProxy) \
159 V(Object, kFunction | kOtherObject | kOtherUndetectable) \
160 V(Receiver, kObject | kProxy) \
161 V(ReceiverOrUndefined, kReceiver | kUndefined) \
162 V(StringOrReceiver, kString | kReceiver) \
163 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \
164 kReceiver) \
165 V(Internal, kHole | kExternalPointer | kOtherInternal) \
166 V(NonInternal, kPrimitive | kReceiver) \
167 V(NonNumber, kUnique | kString | kInternal) \
168 V(Any, 0xfffffffeu)
169
170 // clang-format on
171
172 /*
173 * The following diagrams show how integers (in the mathematical sense) are
174 * divided among the different atomic numerical types.
175 *
176 * ON OS32 N31 U30 OU31 OU32 ON
177 * ______[_______[_______[_______[_______[_______[_______
178 * -2^31 -2^30 0 2^30 2^31 2^32
179 *
180 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
181 *
182 * Some of the atomic numerical bitsets are internal only (see
183 * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in
184 * union with certain other bitsets. For instance, OtherNumber should only
185 * occur as part of PlainNumber.
186 */
187
188 #define BITSET_TYPE_LIST(V) \
189 INTERNAL_BITSET_TYPE_LIST(V) \
190 PROPER_BITSET_TYPE_LIST(V)
191
192 class Type;
193
194 // -----------------------------------------------------------------------------
195 // Bitset types (internal).
196
197 class V8_EXPORT_PRIVATE BitsetType {
198 public:
199 typedef uint32_t bitset; // Internal
200
201 enum : uint32_t {
202 #define DECLARE_TYPE(type, value) k##type = (value),
203 BITSET_TYPE_LIST(DECLARE_TYPE)
204 #undef DECLARE_TYPE
205 kUnusedEOL = 0
206 };
207
208 static bitset SignedSmall();
209 static bitset UnsignedSmall();
210
Bitset()211 bitset Bitset() {
212 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
213 }
214
IsInhabited(bitset bits)215 static bool IsInhabited(bitset bits) { return bits != kNone; }
216
Is(bitset bits1,bitset bits2)217 static bool Is(bitset bits1, bitset bits2) {
218 return (bits1 | bits2) == bits2;
219 }
220
221 static double Min(bitset);
222 static double Max(bitset);
223
224 static bitset Glb(Type* type); // greatest lower bound that's a bitset
225 static bitset Glb(double min, double max);
226 static bitset Lub(Type* type); // least upper bound that's a bitset
227 static bitset Lub(i::Map* map);
228 static bitset Lub(i::Object* value);
229 static bitset Lub(double value);
230 static bitset Lub(double min, double max);
231 static bitset ExpandInternals(bitset bits);
232
233 static const char* Name(bitset);
234 static void Print(std::ostream& os, bitset); // NOLINT
235 #ifdef DEBUG
236 static void Print(bitset);
237 #endif
238
239 static bitset NumberBits(bitset bits);
240
IsBitset(Type * type)241 static bool IsBitset(Type* type) {
242 return reinterpret_cast<uintptr_t>(type) & 1;
243 }
244
NewForTesting(bitset bits)245 static Type* NewForTesting(bitset bits) { return New(bits); }
246
247 private:
248 friend class Type;
249
New(bitset bits)250 static Type* New(bitset bits) {
251 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
252 }
253
254 struct Boundary {
255 bitset internal;
256 bitset external;
257 double min;
258 };
259 static const Boundary BoundariesArray[];
260 static inline const Boundary* Boundaries();
261 static inline size_t BoundariesSize();
262 };
263
264 // -----------------------------------------------------------------------------
265 // Superclass for non-bitset types (internal).
266 class TypeBase {
267 protected:
268 friend class Type;
269
270 enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
271
kind()272 Kind kind() const { return kind_; }
TypeBase(Kind kind)273 explicit TypeBase(Kind kind) : kind_(kind) {}
274
IsKind(Type * type,Kind kind)275 static bool IsKind(Type* type, Kind kind) {
276 if (BitsetType::IsBitset(type)) return false;
277 TypeBase* base = reinterpret_cast<TypeBase*>(type);
278 return base->kind() == kind;
279 }
280
281 // The hacky conversion to/from Type*.
AsType(TypeBase * type)282 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
FromType(Type * type)283 static TypeBase* FromType(Type* type) {
284 return reinterpret_cast<TypeBase*>(type);
285 }
286
287 private:
288 Kind kind_;
289 };
290
291 // -----------------------------------------------------------------------------
292 // Constant types.
293
294 class OtherNumberConstantType : public TypeBase {
295 public:
Value()296 double Value() { return value_; }
297
298 static bool IsOtherNumberConstant(double value);
299 static bool IsOtherNumberConstant(Object* value);
300
301 private:
302 friend class Type;
303 friend class BitsetType;
304
New(double value,Zone * zone)305 static Type* New(double value, Zone* zone) {
306 return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
307 OtherNumberConstantType(value)); // NOLINT
308 }
309
cast(Type * type)310 static OtherNumberConstantType* cast(Type* type) {
311 DCHECK(IsKind(type, kOtherNumberConstant));
312 return static_cast<OtherNumberConstantType*>(FromType(type));
313 }
314
OtherNumberConstantType(double value)315 explicit OtherNumberConstantType(double value)
316 : TypeBase(kOtherNumberConstant), value_(value) {
317 CHECK(IsOtherNumberConstant(value));
318 }
319
Lub()320 BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }
321
322 double value_;
323 };
324
NON_EXPORTED_BASE(TypeBase)325 class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
326 public:
327 i::Handle<i::HeapObject> Value() { return object_; }
328
329 private:
330 friend class Type;
331 friend class BitsetType;
332
333 static Type* New(i::Handle<i::HeapObject> value, Zone* zone) {
334 BitsetType::bitset bitset = BitsetType::Lub(*value);
335 return AsType(new (zone->New(sizeof(HeapConstantType)))
336 HeapConstantType(bitset, value));
337 }
338
339 static HeapConstantType* cast(Type* type) {
340 DCHECK(IsKind(type, kHeapConstant));
341 return static_cast<HeapConstantType*>(FromType(type));
342 }
343
344 HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
345
346 BitsetType::bitset Lub() { return bitset_; }
347
348 BitsetType::bitset bitset_;
349 Handle<i::HeapObject> object_;
350 };
351
352 // -----------------------------------------------------------------------------
353 // Range types.
354
355 class RangeType : public TypeBase {
356 public:
357 struct Limits {
358 double min;
359 double max;
LimitsLimits360 Limits(double min, double max) : min(min), max(max) {}
LimitsLimits361 explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
362 bool IsEmpty();
EmptyLimits363 static Limits Empty() { return Limits(1, 0); }
364 static Limits Intersect(Limits lhs, Limits rhs);
365 static Limits Union(Limits lhs, Limits rhs);
366 };
367
Min()368 double Min() { return limits_.min; }
Max()369 double Max() { return limits_.max; }
370
371 private:
372 friend class Type;
373 friend class BitsetType;
374 friend class UnionType;
375
New(double min,double max,Zone * zone)376 static Type* New(double min, double max, Zone* zone) {
377 return New(Limits(min, max), zone);
378 }
379
IsInteger(double x)380 static bool IsInteger(double x) {
381 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
382 }
383
New(Limits lim,Zone * zone)384 static Type* New(Limits lim, Zone* zone) {
385 DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
386 DCHECK(lim.min <= lim.max);
387 BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
388
389 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
390 }
391
cast(Type * type)392 static RangeType* cast(Type* type) {
393 DCHECK(IsKind(type, kRange));
394 return static_cast<RangeType*>(FromType(type));
395 }
396
RangeType(BitsetType::bitset bitset,Limits limits)397 RangeType(BitsetType::bitset bitset, Limits limits)
398 : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
399
Lub()400 BitsetType::bitset Lub() { return bitset_; }
401
402 BitsetType::bitset bitset_;
403 Limits limits_;
404 };
405
406 // -----------------------------------------------------------------------------
407 // Superclass for types with variable number of type fields.
408 class StructuralType : public TypeBase {
409 public:
LengthForTesting()410 int LengthForTesting() { return Length(); }
411
412 protected:
413 friend class Type;
414
Length()415 int Length() { return length_; }
416
Get(int i)417 Type* Get(int i) {
418 DCHECK(0 <= i && i < this->Length());
419 return elements_[i];
420 }
421
Set(int i,Type * type)422 void Set(int i, Type* type) {
423 DCHECK(0 <= i && i < this->Length());
424 elements_[i] = type;
425 }
426
Shrink(int length)427 void Shrink(int length) {
428 DCHECK(2 <= length && length <= this->Length());
429 length_ = length;
430 }
431
StructuralType(Kind kind,int length,i::Zone * zone)432 StructuralType(Kind kind, int length, i::Zone* zone)
433 : TypeBase(kind), length_(length) {
434 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
435 }
436
437 private:
438 int length_;
439 Type** elements_;
440 };
441
442 // -----------------------------------------------------------------------------
443 // Tuple types.
444
445 class TupleType : public StructuralType {
446 public:
Arity()447 int Arity() { return this->Length(); }
Element(int i)448 Type* Element(int i) { return this->Get(i); }
449
InitElement(int i,Type * type)450 void InitElement(int i, Type* type) { this->Set(i, type); }
451
452 private:
453 friend class Type;
454
TupleType(int length,Zone * zone)455 TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
456
New(int length,Zone * zone)457 static Type* New(int length, Zone* zone) {
458 return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
459 }
460
cast(Type * type)461 static TupleType* cast(Type* type) {
462 DCHECK(IsKind(type, kTuple));
463 return static_cast<TupleType*>(FromType(type));
464 }
465 };
466
467 // -----------------------------------------------------------------------------
468 // Union types (internal).
469 // A union is a structured type with the following invariants:
470 // - its length is at least 2
471 // - at most one field is a bitset, and it must go into index 0
472 // - no field is a union
473 // - no field is a subtype of any other field
474 class UnionType : public StructuralType {
475 private:
476 friend Type;
477 friend BitsetType;
478
UnionType(int length,Zone * zone)479 UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
480
New(int length,Zone * zone)481 static Type* New(int length, Zone* zone) {
482 return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
483 }
484
cast(Type * type)485 static UnionType* cast(Type* type) {
486 DCHECK(IsKind(type, kUnion));
487 return static_cast<UnionType*>(FromType(type));
488 }
489
490 bool Wellformed();
491 };
492
493 class V8_EXPORT_PRIVATE Type {
494 public:
495 typedef BitsetType::bitset bitset; // Internal
496
497 // Constructors.
498 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
499 static Type* type() { return BitsetType::New(BitsetType::k##type); }
PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)500 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
501 #undef DEFINE_TYPE_CONSTRUCTOR
502
503 static Type* SignedSmall() {
504 return BitsetType::New(BitsetType::SignedSmall());
505 }
UnsignedSmall()506 static Type* UnsignedSmall() {
507 return BitsetType::New(BitsetType::UnsignedSmall());
508 }
509
OtherNumberConstant(double value,Zone * zone)510 static Type* OtherNumberConstant(double value, Zone* zone) {
511 return OtherNumberConstantType::New(value, zone);
512 }
HeapConstant(i::Handle<i::HeapObject> value,Zone * zone)513 static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) {
514 return HeapConstantType::New(value, zone);
515 }
Range(double min,double max,Zone * zone)516 static Type* Range(double min, double max, Zone* zone) {
517 return RangeType::New(min, max, zone);
518 }
Tuple(Type * first,Type * second,Type * third,Zone * zone)519 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
520 Type* tuple = TupleType::New(3, zone);
521 tuple->AsTuple()->InitElement(0, first);
522 tuple->AsTuple()->InitElement(1, second);
523 tuple->AsTuple()->InitElement(2, third);
524 return tuple;
525 }
526
527 // NewConstant is a factory that returns Constant, Range or Number.
528 static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
529 static Type* NewConstant(double value, Zone* zone);
530
531 static Type* Union(Type* type1, Type* type2, Zone* zone);
532 static Type* Intersect(Type* type1, Type* type2, Zone* zone);
533
Of(double value,Zone * zone)534 static Type* Of(double value, Zone* zone) {
535 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
536 }
Of(i::Object * value,Zone * zone)537 static Type* Of(i::Object* value, Zone* zone) {
538 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
539 }
Of(i::Handle<i::Object> value,Zone * zone)540 static Type* Of(i::Handle<i::Object> value, Zone* zone) {
541 return Of(*value, zone);
542 }
543
For(i::Map * map)544 static Type* For(i::Map* map) {
545 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map)));
546 }
For(i::Handle<i::Map> map)547 static Type* For(i::Handle<i::Map> map) { return For(*map); }
548
549 // Predicates.
IsInhabited()550 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
551
Is(Type * that)552 bool Is(Type* that) { return this == that || this->SlowIs(that); }
553 bool Maybe(Type* that);
Equals(Type * that)554 bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
555
556 // Inspection.
IsRange()557 bool IsRange() { return IsKind(TypeBase::kRange); }
IsHeapConstant()558 bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
IsOtherNumberConstant()559 bool IsOtherNumberConstant() {
560 return IsKind(TypeBase::kOtherNumberConstant);
561 }
IsTuple()562 bool IsTuple() { return IsKind(TypeBase::kTuple); }
563
AsHeapConstant()564 HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
AsOtherNumberConstant()565 OtherNumberConstantType* AsOtherNumberConstant() {
566 return OtherNumberConstantType::cast(this);
567 }
AsRange()568 RangeType* AsRange() { return RangeType::cast(this); }
AsTuple()569 TupleType* AsTuple() { return TupleType::cast(this); }
570
571 // Minimum and maximum of a numeric type.
572 // These functions do not distinguish between -0 and +0. If the type equals
573 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
574 // functions on subtypes of Number.
575 double Min();
576 double Max();
577
578 // Extracts a range from the type: if the type is a range or a union
579 // containing a range, that range is returned; otherwise, NULL is returned.
580 Type* GetRange();
581
582 static bool IsInteger(i::Object* x);
IsInteger(double x)583 static bool IsInteger(double x) {
584 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
585 }
586
587 int NumConstants();
588
589 // Printing.
590
591 void PrintTo(std::ostream& os);
592
593 #ifdef DEBUG
594 void Print();
595 #endif
596
597 // Helpers for testing.
IsBitsetForTesting()598 bool IsBitsetForTesting() { return IsBitset(); }
IsUnionForTesting()599 bool IsUnionForTesting() { return IsUnion(); }
AsBitsetForTesting()600 bitset AsBitsetForTesting() { return AsBitset(); }
AsUnionForTesting()601 UnionType* AsUnionForTesting() { return AsUnion(); }
602
603 private:
604 // Friends.
605 template <class>
606 friend class Iterator;
607 friend BitsetType;
608 friend UnionType;
609
610 // Internal inspection.
IsKind(TypeBase::Kind kind)611 bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
612
IsNone()613 bool IsNone() { return this == None(); }
IsAny()614 bool IsAny() { return this == Any(); }
IsBitset()615 bool IsBitset() { return BitsetType::IsBitset(this); }
IsUnion()616 bool IsUnion() { return IsKind(TypeBase::kUnion); }
617
AsBitset()618 bitset AsBitset() {
619 DCHECK(this->IsBitset());
620 return reinterpret_cast<BitsetType*>(this)->Bitset();
621 }
AsUnion()622 UnionType* AsUnion() { return UnionType::cast(this); }
623
BitsetGlb()624 bitset BitsetGlb() { return BitsetType::Glb(this); }
BitsetLub()625 bitset BitsetLub() { return BitsetType::Lub(this); }
626
627 bool SlowIs(Type* that);
628
629 static bool Overlap(RangeType* lhs, RangeType* rhs);
630 static bool Contains(RangeType* lhs, RangeType* rhs);
631 static bool Contains(RangeType* range, i::Object* val);
632
633 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
634
635 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
636 Zone* zone);
637 static RangeType::Limits ToLimits(bitset bits, Zone* zone);
638
639 bool SimplyEquals(Type* that);
640
641 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
642 static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
643 RangeType::Limits* limits, Zone* zone);
644 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
645 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
646 };
647
648 } // namespace compiler
649 } // namespace internal
650 } // namespace v8
651
652 #endif // V8_COMPILER_TYPES_H_
653