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