• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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