types.h 22.1 KB
Newer Older
1 2 3
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_COMPILER_TYPES_H_
#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 16

namespace v8 {
namespace internal {
17
namespace compiler {
18

19 20
// SUMMARY
//
21 22 23 24 25 26
// A simple type system for compiler-internal use. It is based entirely on
// union types, and all subtyping hence amounts to set inclusion. Besides the
// obvious primitive types and some predefined unions, the type language also
// can express class types (a.k.a. specific maps) and singleton types (i.e.,
// concrete constants).
//
27
// The following equations and inequations hold:
28 29 30 31
//
//   None <= T
//   T <= Any
//
32 33
//   Number = Signed32 \/ Unsigned32 \/ Double
//   Smi <= Signed32
34 35 36 37 38
//   Name = String \/ Symbol
//   UniqueName = InternalizedString \/ Symbol
//   InternalizedString < String
//
//   Receiver = Object \/ Proxy
39 40
//   OtherUndetectable < Object
//   DetectableReceiver = Receiver - OtherUndetectable
41 42
//
//   Constant(x) < T  iff instance_type(map(x)) < T
43
//
44 45 46 47
//
// RANGE TYPES
//
// A range type represents a continuous integer interval by its minimum and
48 49
// maximum value.  Either value may be an infinity, in which case that infinity
// itself is also included in the range.   A range never contains NaN or -0.
50
//
51 52 53 54
// If a value v happens to be an integer n, then Constant(v) is considered a
// subtype of Range(n, n) (and therefore also a subtype of any larger range).
// In order to avoid large unions, however, it is usually a good idea to use
// Range rather than Constant.
55 56
//
//
57 58
// PREDICATES
//
59 60 61 62 63
// There are two main functions for testing types:
//
//   T1->Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
//   T1->Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
//
64
// Typically, the former is to be used to select representations (e.g., via
65 66
// T->Is(SignedSmall())), and the latter to check whether a specific case needs
// handling (e.g., via T->Maybe(Number())).
67 68 69 70 71
//
// There is no functionality to discover whether a type is a leaf in the
// lattice. That is intentional. It should always be possible to refine the
// lattice (e.g., splitting up number types further) without invalidating any
// existing assumptions or tests.
72
// Consequently, do not normally use Equals for type tests, always use Is!
73
//
74 75 76 77
// The NowIs operator implements state-sensitive subtying, as described above.
// Any compilation decision based on such temporary properties requires runtime
// guarding!
//
78
//
79 80 81
// PROPERTIES
//
// Various formal properties hold for constructors, operators, and predicates
82 83
// over types. For example, constructors are injective and subtyping is a
// 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 88
// constructors and predicates (those prefixed 'Now').
//
89
//
90 91
// IMPLEMENTATION
//
92
// Internally, all 'primitive' types, and their unions, are represented as
bmeurer's avatar
bmeurer committed
93 94
// bitsets. Bit 0 is reserved for tagging. Only structured types require
// allocation.
95

96 97 98
// -----------------------------------------------------------------------------
// Values for bitset types

99 100
// clang-format off

101
#define INTERNAL_BITSET_TYPE_LIST(V)                                      \
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  V(OtherUnsigned31, 1u << 1)  \
  V(OtherUnsigned32, 1u << 2)  \
  V(OtherSigned32,   1u << 3)  \
  V(OtherNumber,     1u << 4)  \

#define PROPER_BITSET_TYPE_LIST(V) \
  V(None,                0u)        \
  V(Negative31,          1u << 5)   \
  V(Null,                1u << 6)   \
  V(Undefined,           1u << 7)   \
  V(Boolean,             1u << 8)   \
  V(Unsigned30,          1u << 9)   \
  V(MinusZero,           1u << 10)  \
  V(NaN,                 1u << 11)  \
  V(Symbol,              1u << 12)  \
  V(InternalizedString,  1u << 13)  \
  V(OtherString,         1u << 14)  \
bbudge's avatar
bbudge committed
119 120 121 122 123 124 125 126 127 128
  V(OtherCallable,       1u << 15)  \
  V(OtherObject,         1u << 16)  \
  V(OtherUndetectable,   1u << 17)  \
  V(CallableProxy,       1u << 18)  \
  V(OtherProxy,          1u << 19)  \
  V(Function,            1u << 20)  \
  V(BoundFunction,       1u << 21)  \
  V(Hole,                1u << 22)  \
  V(OtherInternal,       1u << 23)  \
  V(ExternalPointer,     1u << 24)  \
129
  \
130 131 132 133 134 135 136 137 138 139 140 141
  V(Signed31,                     kUnsigned30 | kNegative31) \
  V(Signed32,                     kSigned31 | kOtherUnsigned31 | \
                                  kOtherSigned32) \
  V(Signed32OrMinusZero,          kSigned32 | kMinusZero) \
  V(Signed32OrMinusZeroOrNaN,     kSigned32 | kMinusZero | kNaN) \
  V(Negative32,                   kNegative31 | kOtherSigned32) \
  V(Unsigned31,                   kUnsigned30 | kOtherUnsigned31) \
  V(Unsigned32,                   kUnsigned30 | kOtherUnsigned31 | \
                                  kOtherUnsigned32) \
  V(Unsigned32OrMinusZero,        kUnsigned32 | kMinusZero) \
  V(Unsigned32OrMinusZeroOrNaN,   kUnsigned32 | kMinusZero | kNaN) \
  V(Integral32,                   kSigned32 | kUnsigned32) \
142 143
  V(Integral32OrMinusZero,        kIntegral32 | kMinusZero) \
  V(Integral32OrMinusZeroOrNaN,   kIntegral32OrMinusZero | kNaN) \
144 145 146 147 148 149 150
  V(PlainNumber,                  kIntegral32 | kOtherNumber) \
  V(OrderedNumber,                kPlainNumber | kMinusZero) \
  V(MinusZeroOrNaN,               kMinusZero | kNaN) \
  V(Number,                       kOrderedNumber | kNaN) \
  V(String,                       kInternalizedString | kOtherString) \
  V(UniqueName,                   kSymbol | kInternalizedString) \
  V(Name,                         kSymbol | kString) \
151
  V(InternalizedStringOrNull,     kInternalizedString | kNull) \
152 153 154
  V(BooleanOrNumber,              kBoolean | kNumber) \
  V(BooleanOrNullOrNumber,        kBooleanOrNumber | kNull) \
  V(BooleanOrNullOrUndefined,     kBoolean | kNull | kUndefined) \
155
  V(Oddball,                      kBooleanOrNullOrUndefined | kHole) \
156 157 158 159 160 161 162 163 164
  V(NullOrNumber,                 kNull | kNumber) \
  V(NullOrUndefined,              kNull | kUndefined) \
  V(Undetectable,                 kNullOrUndefined | kOtherUndetectable) \
  V(NumberOrOddball,              kNumber | kNullOrUndefined | kBoolean | \
                                  kHole) \
  V(NumberOrString,               kNumber | kString) \
  V(NumberOrUndefined,            kNumber | kUndefined) \
  V(PlainPrimitive,               kNumberOrString | kBoolean | \
                                  kNullOrUndefined) \
bbudge's avatar
bbudge committed
165
  V(Primitive,                    kSymbol | kPlainPrimitive) \
166 167
  V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
  V(Proxy,                        kCallableProxy | kOtherProxy) \
168 169 170
  V(DetectableCallable,           kFunction | kBoundFunction | \
                                  kOtherCallable | kCallableProxy) \
  V(Callable,                     kDetectableCallable | kOtherUndetectable) \
171 172 173 174 175 176 177 178 179 180
  V(NonCallable,                  kOtherObject | kOtherProxy) \
  V(NonCallableOrNull,            kNonCallable | kNull) \
  V(DetectableObject,             kFunction | kBoundFunction | \
                                  kOtherCallable | kOtherObject) \
  V(DetectableReceiver,           kDetectableObject | kProxy) \
  V(DetectableReceiverOrNull,     kDetectableReceiver | kNull) \
  V(Object,                       kDetectableObject | kOtherUndetectable) \
  V(Receiver,                     kObject | kProxy) \
  V(ReceiverOrUndefined,          kReceiver | kUndefined) \
  V(ReceiverOrNullOrUndefined,    kReceiver | kNull | kUndefined) \
181
  V(SymbolOrReceiver,             kSymbol | kReceiver) \
182 183 184 185 186 187 188
  V(StringOrReceiver,             kString | kReceiver) \
  V(Unique,                       kBoolean | kUniqueName | kNull | \
                                  kUndefined | kReceiver) \
  V(Internal,                     kHole | kExternalPointer | kOtherInternal) \
  V(NonInternal,                  kPrimitive | kReceiver) \
  V(NonNumber,                    kUnique | kString | kInternal) \
  V(Any,                          0xfffffffeu)
189

190
// clang-format on
191

192 193 194 195
/*
 * The following diagrams show how integers (in the mathematical sense) are
 * divided among the different atomic numerical types.
 *
196
 *   ON    OS32     N31     U30     OU31    OU32     ON
197 198 199 200
 * ______[_______[_______[_______[_______[_______[_______
 *     -2^31   -2^30     0      2^30    2^31    2^32
 *
 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
201 202 203 204 205
 *
 * Some of the atomic numerical bitsets are internal only (see
 * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
 * union with certain other bitsets.  For instance, OtherNumber should only
 * occur as part of PlainNumber.
206 207
 */

208 209 210
#define BITSET_TYPE_LIST(V)    \
  INTERNAL_BITSET_TYPE_LIST(V) \
  PROPER_BITSET_TYPE_LIST(V)
211

212
class Type;
213

214
// -----------------------------------------------------------------------------
215
// Bitset types (internal).
216

217
class V8_EXPORT_PRIVATE BitsetType {
218
 public:
219
  typedef uint32_t bitset;  // Internal
220

221 222 223 224 225 226
  enum : uint32_t {
#define DECLARE_TYPE(type, value) k##type = (value),
    BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
        kUnusedEOL = 0
  };
227

228 229
  static bitset SignedSmall();
  static bitset UnsignedSmall();
230

231 232
  bitset Bitset() {
    return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
233
  }
234

235
  static bool IsInhabited(bitset bits) { return bits != kNone; }
236

237 238 239
  static bool Is(bitset bits1, bitset bits2) {
    return (bits1 | bits2) == bits2;
  }
240

241 242
  static double Min(bitset);
  static double Max(bitset);
243

244 245 246 247 248 249 250 251
  static bitset Glb(Type* type);  // greatest lower bound that's a bitset
  static bitset Glb(double min, double max);
  static bitset Lub(Type* type);  // least upper bound that's a bitset
  static bitset Lub(i::Map* map);
  static bitset Lub(i::Object* value);
  static bitset Lub(double value);
  static bitset Lub(double min, double max);
  static bitset ExpandInternals(bitset bits);
252

253 254 255 256 257
  static const char* Name(bitset);
  static void Print(std::ostream& os, bitset);  // NOLINT
#ifdef DEBUG
  static void Print(bitset);
#endif
258

259
  static bitset NumberBits(bitset bits);
260

261 262
  static bool IsBitset(Type* type) {
    return reinterpret_cast<uintptr_t>(type) & 1;
263
  }
264

265
  static Type* NewForTesting(bitset bits) { return New(bits); }
266

267 268
 private:
  friend class Type;
269

270 271
  static Type* New(bitset bits) {
    return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
272
  }
273

274 275 276 277 278 279 280 281 282
  struct Boundary {
    bitset internal;
    bitset external;
    double min;
  };
  static const Boundary BoundariesArray[];
  static inline const Boundary* Boundaries();
  static inline size_t BoundariesSize();
};
283

284 285 286 287 288 289
// -----------------------------------------------------------------------------
// Superclass for non-bitset types (internal).
class TypeBase {
 protected:
  friend class Type;

290
  enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
291

292 293
  Kind kind() const { return kind_; }
  explicit TypeBase(Kind kind) : kind_(kind) {}
294

295 296 297 298
  static bool IsKind(Type* type, Kind kind) {
    if (BitsetType::IsBitset(type)) return false;
    TypeBase* base = reinterpret_cast<TypeBase*>(type);
    return base->kind() == kind;
299 300
  }

301 302 303 304
  // The hacky conversion to/from Type*.
  static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
  static TypeBase* FromType(Type* type) {
    return reinterpret_cast<TypeBase*>(type);
305
  }
306

307 308 309
 private:
  Kind kind_;
};
310

311 312
// -----------------------------------------------------------------------------
// Constant types.
313

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
class OtherNumberConstantType : public TypeBase {
 public:
  double Value() { return value_; }

  static bool IsOtherNumberConstant(double value);
  static bool IsOtherNumberConstant(Object* value);

 private:
  friend class Type;
  friend class BitsetType;

  static Type* New(double value, Zone* zone) {
    return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
                      OtherNumberConstantType(value));  // NOLINT
  }

  static OtherNumberConstantType* cast(Type* type) {
    DCHECK(IsKind(type, kOtherNumberConstant));
    return static_cast<OtherNumberConstantType*>(FromType(type));
  }

  explicit OtherNumberConstantType(double value)
      : TypeBase(kOtherNumberConstant), value_(value) {
    CHECK(IsOtherNumberConstant(value));
  }

  BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }

  double value_;
};

345
class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
346
 public:
347
  i::Handle<i::HeapObject> Value() { return object_; }
348

349 350 351
 private:
  friend class Type;
  friend class BitsetType;
352

353
  static Type* New(i::Handle<i::HeapObject> value, Zone* zone) {
354
    BitsetType::bitset bitset = BitsetType::Lub(*value);
355 356
    return AsType(new (zone->New(sizeof(HeapConstantType)))
                      HeapConstantType(bitset, value));
357
  }
358

359 360 361
  static HeapConstantType* cast(Type* type) {
    DCHECK(IsKind(type, kHeapConstant));
    return static_cast<HeapConstantType*>(FromType(type));
362 363
  }

364
  HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
365

366
  BitsetType::bitset Lub() { return bitset_; }
367

368
  BitsetType::bitset bitset_;
369
  Handle<i::HeapObject> object_;
370
};
371

372 373
// -----------------------------------------------------------------------------
// Range types.
374

375 376
class RangeType : public TypeBase {
 public:
377
  struct Limits {
378 379
    double min;
    double max;
380 381
    Limits(double min, double max) : min(min), max(max) {}
    explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
382 383 384 385
    bool IsEmpty();
    static Limits Empty() { return Limits(1, 0); }
    static Limits Intersect(Limits lhs, Limits rhs);
    static Limits Union(Limits lhs, Limits rhs);
386 387
  };

388 389
  double Min() { return limits_.min; }
  double Max() { return limits_.max; }
390

391 392 393 394
 private:
  friend class Type;
  friend class BitsetType;
  friend class UnionType;
395

396 397
  static Type* New(double min, double max, Zone* zone) {
    return New(Limits(min, max), zone);
398
  }
399

400 401 402
  static bool IsInteger(double x) {
    return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
  }
403

404
  static Type* New(Limits lim, Zone* zone) {
405 406
    DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
    DCHECK(lim.min <= lim.max);
407
    BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
408

409 410
    return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
  }
411

412 413 414 415
  static RangeType* cast(Type* type) {
    DCHECK(IsKind(type, kRange));
    return static_cast<RangeType*>(FromType(type));
  }
416

417 418
  RangeType(BitsetType::bitset bitset, Limits limits)
      : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
419

420
  BitsetType::bitset Lub() { return bitset_; }
421

422 423 424
  BitsetType::bitset bitset_;
  Limits limits_;
};
425

426
// -----------------------------------------------------------------------------
427 428 429 430
// Superclass for types with variable number of type fields.
class StructuralType : public TypeBase {
 public:
  int LengthForTesting() { return Length(); }
431

432
 protected:
433
  friend class Type;
434

435 436 437
  int Length() { return length_; }

  Type* Get(int i) {
438
    DCHECK(0 <= i && i < this->Length());
439
    return elements_[i];
440
  }
441 442

  void Set(int i, Type* type) {
443
    DCHECK(0 <= i && i < this->Length());
444
    elements_[i] = type;
445
  }
446

447
  void Shrink(int length) {
448
    DCHECK(2 <= length && length <= this->Length());
449
    length_ = length;
450
  }
451 452 453 454

  StructuralType(Kind kind, int length, i::Zone* zone)
      : TypeBase(kind), length_(length) {
    elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
455
  }
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485

 private:
  int length_;
  Type** elements_;
};

// -----------------------------------------------------------------------------
// Tuple types.

class TupleType : public StructuralType {
 public:
  int Arity() { return this->Length(); }
  Type* Element(int i) { return this->Get(i); }

  void InitElement(int i, Type* type) { this->Set(i, type); }

 private:
  friend class Type;

  TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}

  static Type* New(int length, Zone* zone) {
    return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
  }

  static TupleType* cast(Type* type) {
    DCHECK(IsKind(type, kTuple));
    return static_cast<TupleType*>(FromType(type));
  }
};
486

487 488 489 490 491 492 493
// -----------------------------------------------------------------------------
// Union types (internal).
// A union is a structured type with the following invariants:
// - its length is at least 2
// - at most one field is a bitset, and it must go into index 0
// - no field is a union
// - no field is a subtype of any other field
494 495 496 497 498 499 500 501 502
class UnionType : public StructuralType {
 private:
  friend Type;
  friend BitsetType;

  UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}

  static Type* New(int length, Zone* zone) {
    return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
503 504
  }

505 506 507
  static UnionType* cast(Type* type) {
    DCHECK(IsKind(type, kUnion));
    return static_cast<UnionType*>(FromType(type));
508 509 510 511 512
  }

  bool Wellformed();
};

513
class V8_EXPORT_PRIVATE Type {
514 515
 public:
  typedef BitsetType::bitset bitset;  // Internal
516

517 518 519 520 521
// Constructors.
#define DEFINE_TYPE_CONSTRUCTOR(type, value) \
  static Type* type() { return BitsetType::New(BitsetType::k##type); }
  PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
#undef DEFINE_TYPE_CONSTRUCTOR
522

523 524
  static Type* SignedSmall() {
    return BitsetType::New(BitsetType::SignedSmall());
525
  }
526 527
  static Type* UnsignedSmall() {
    return BitsetType::New(BitsetType::UnsignedSmall());
528 529
  }

530 531 532
  static Type* OtherNumberConstant(double value, Zone* zone) {
    return OtherNumberConstantType::New(value, zone);
  }
533
  static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) {
534
    return HeapConstantType::New(value, zone);
535 536
  }
  static Type* Range(double min, double max, Zone* zone) {
537
    return RangeType::New(min, max, zone);
538 539 540 541 542 543 544
  }
  static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
    Type* tuple = TupleType::New(3, zone);
    tuple->AsTuple()->InitElement(0, first);
    tuple->AsTuple()->InitElement(1, second);
    tuple->AsTuple()->InitElement(2, third);
    return tuple;
545
  }
546

547 548 549 550
  // NewConstant is a factory that returns Constant, Range or Number.
  static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
  static Type* NewConstant(double value, Zone* zone);

551 552
  static Type* Union(Type* type1, Type* type2, Zone* zone);
  static Type* Intersect(Type* type1, Type* type2, Zone* zone);
553

554 555
  static Type* Of(double value, Zone* zone) {
    return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
556
  }
557 558 559 560 561
  static Type* Of(i::Object* value, Zone* zone) {
    return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
  }
  static Type* Of(i::Handle<i::Object> value, Zone* zone) {
    return Of(*value, zone);
562
  }
563

564 565 566 567 568
  static Type* For(i::Map* map) {
    return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map)));
  }
  static Type* For(i::Handle<i::Map> map) { return For(*map); }

569 570
  // Predicates.
  bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
571

572 573 574
  bool Is(Type* that) { return this == that || this->SlowIs(that); }
  bool Maybe(Type* that);
  bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
575

576 577
  // Inspection.
  bool IsRange() { return IsKind(TypeBase::kRange); }
578 579 580 581
  bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
  bool IsOtherNumberConstant() {
    return IsKind(TypeBase::kOtherNumberConstant);
  }
582
  bool IsTuple() { return IsKind(TypeBase::kTuple); }
583

584 585 586 587
  HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
  OtherNumberConstantType* AsOtherNumberConstant() {
    return OtherNumberConstantType::cast(this);
  }
588 589
  RangeType* AsRange() { return RangeType::cast(this); }
  TupleType* AsTuple() { return TupleType::cast(this); }
590

591 592 593 594 595 596
  // Minimum and maximum of a numeric type.
  // These functions do not distinguish between -0 and +0.  If the type equals
  // kNaN, they return NaN; otherwise kNaN is ignored.  Only call these
  // functions on subtypes of Number.
  double Min();
  double Max();
597

598 599 600
  // Extracts a range from the type: if the type is a range or a union
  // containing a range, that range is returned; otherwise, NULL is returned.
  Type* GetRange();
601

602 603 604
  static bool IsInteger(i::Object* x);
  static bool IsInteger(double x) {
    return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
605 606
  }

607
  int NumConstants();
608

609
  // Printing.
610

611
  void PrintTo(std::ostream& os);
612

613 614 615
#ifdef DEBUG
  void Print();
#endif
616

617 618 619 620 621
  // Helpers for testing.
  bool IsBitsetForTesting() { return IsBitset(); }
  bool IsUnionForTesting() { return IsUnion(); }
  bitset AsBitsetForTesting() { return AsBitset(); }
  UnionType* AsUnionForTesting() { return AsUnion(); }
622

623 624 625 626 627 628
 private:
  // Friends.
  template <class>
  friend class Iterator;
  friend BitsetType;
  friend UnionType;
629

630 631
  // Internal inspection.
  bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
632

633 634 635 636
  bool IsNone() { return this == None(); }
  bool IsAny() { return this == Any(); }
  bool IsBitset() { return BitsetType::IsBitset(this); }
  bool IsUnion() { return IsKind(TypeBase::kUnion); }
637

638 639 640
  bitset AsBitset() {
    DCHECK(this->IsBitset());
    return reinterpret_cast<BitsetType*>(this)->Bitset();
641
  }
642
  UnionType* AsUnion() { return UnionType::cast(this); }
643

644 645
  bitset BitsetGlb() { return BitsetType::Glb(this); }
  bitset BitsetLub() { return BitsetType::Lub(this); }
646

647
  bool SlowIs(Type* that);
648

649 650 651
  static bool Overlap(RangeType* lhs, RangeType* rhs);
  static bool Contains(RangeType* lhs, RangeType* rhs);
  static bool Contains(RangeType* range, i::Object* val);
652

653
  static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
654

655 656 657
  static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
                                                   Zone* zone);
  static RangeType::Limits ToLimits(bitset bits, Zone* zone);
658

659
  bool SimplyEquals(Type* that);
660

661 662 663 664 665
  static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
  static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
                          RangeType::Limits* limits, Zone* zone);
  static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
  static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
666 667
};

668
}  // namespace compiler
669 670
}  // namespace internal
}  // namespace v8
671

672
#endif  // V8_COMPILER_TYPES_H_