Home | History | Annotate | Download | only in src
      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_TYPES_H_
      6 #define V8_TYPES_H_
      7 
      8 #include "src/conversions.h"
      9 #include "src/handles.h"
     10 #include "src/objects.h"
     11 #include "src/ostreams.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 // SUMMARY
     17 //
     18 // A simple type system for compiler-internal use. It is based entirely on
     19 // union types, and all subtyping hence amounts to set inclusion. Besides the
     20 // obvious primitive types and some predefined unions, the type language also
     21 // can express class types (a.k.a. specific maps) and singleton types (i.e.,
     22 // concrete constants).
     23 //
     24 // Types consist of two dimensions: semantic (value range) and representation.
     25 // Both are related through subtyping.
     26 //
     27 //
     28 // SEMANTIC DIMENSION
     29 //
     30 // The following equations and inequations hold for the semantic axis:
     31 //
     32 //   None <= T
     33 //   T <= Any
     34 //
     35 //   Number = Signed32 \/ Unsigned32 \/ Double
     36 //   Smi <= Signed32
     37 //   Name = String \/ Symbol
     38 //   UniqueName = InternalizedString \/ Symbol
     39 //   InternalizedString < String
     40 //
     41 //   Receiver = Object \/ Proxy
     42 //   Array < Object
     43 //   Function < Object
     44 //   RegExp < Object
     45 //   Undetectable < Object
     46 //   Detectable = Receiver \/ Number \/ Name - Undetectable
     47 //
     48 //   Class(map) < T   iff instance_type(map) < T
     49 //   Constant(x) < T  iff instance_type(map(x)) < T
     50 //   Array(T) < Array
     51 //   Function(R, S, T0, T1, ...) < Function
     52 //   Context(T) < Internal
     53 //
     54 // Both structural Array and Function types are invariant in all parameters;
     55 // relaxing this would make Union and Intersect operations more involved.
     56 // There is no subtyping relation between Array, Function, or Context types
     57 // and respective Constant types, since these types cannot be reconstructed
     58 // for arbitrary heap values.
     59 // Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
     60 // change! (Its instance type cannot, however.)
     61 // TODO(rossberg): the latter is not currently true for proxies, because of fix,
     62 // but will hold once we implement direct proxies.
     63 // However, we also define a 'temporal' variant of the subtyping relation that
     64 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)).
     65 //
     66 //
     67 // REPRESENTATIONAL DIMENSION
     68 //
     69 // For the representation axis, the following holds:
     70 //
     71 //   None <= R
     72 //   R <= Any
     73 //
     74 //   UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/
     75 //                 UntaggedInt16 \/ UntaggedInt32
     76 //   UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64
     77 //   UntaggedNumber = UntaggedInt \/ UntaggedFloat
     78 //   Untagged = UntaggedNumber \/ UntaggedPtr
     79 //   Tagged = TaggedInt \/ TaggedPtr
     80 //
     81 // Subtyping relates the two dimensions, for example:
     82 //
     83 //   Number <= Tagged \/ UntaggedNumber
     84 //   Object <= TaggedPtr \/ UntaggedPtr
     85 //
     86 // That holds because the semantic type constructors defined by the API create
     87 // types that allow for all possible representations, and dually, the ones for
     88 // representation types initially include all semantic ranges. Representations
     89 // can then e.g. be narrowed for a given semantic type using intersection:
     90 //
     91 //   SignedSmall /\ TaggedInt       (a 'smi')
     92 //   Number /\ TaggedPtr            (a heap number)
     93 //
     94 //
     95 // RANGE TYPES
     96 //
     97 // A range type represents a continuous integer interval by its minimum and
     98 // maximum value.  Either value may be an infinity, in which case that infinity
     99 // itself is also included in the range.   A range never contains NaN or -0.
    100 //
    101 // If a value v happens to be an integer n, then Constant(v) is considered a
    102 // subtype of Range(n, n) (and therefore also a subtype of any larger range).
    103 // In order to avoid large unions, however, it is usually a good idea to use
    104 // Range rather than Constant.
    105 //
    106 //
    107 // PREDICATES
    108 //
    109 // There are two main functions for testing types:
    110 //
    111 //   T1->Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
    112 //   T1->Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
    113 //
    114 // Typically, the former is to be used to select representations (e.g., via
    115 // T->Is(SignedSmall())), and the latter to check whether a specific case needs
    116 // handling (e.g., via T->Maybe(Number())).
    117 //
    118 // There is no functionality to discover whether a type is a leaf in the
    119 // lattice. That is intentional. It should always be possible to refine the
    120 // lattice (e.g., splitting up number types further) without invalidating any
    121 // existing assumptions or tests.
    122 // Consequently, do not normally use Equals for type tests, always use Is!
    123 //
    124 // The NowIs operator implements state-sensitive subtying, as described above.
    125 // Any compilation decision based on such temporary properties requires runtime
    126 // guarding!
    127 //
    128 //
    129 // PROPERTIES
    130 //
    131 // Various formal properties hold for constructors, operators, and predicates
    132 // over types. For example, constructors are injective and subtyping is a
    133 // complete partial order.
    134 //
    135 // See test/cctest/test-types.cc for a comprehensive executable specification,
    136 // especially with respect to the properties of the more exotic 'temporal'
    137 // constructors and predicates (those prefixed 'Now').
    138 //
    139 //
    140 // IMPLEMENTATION
    141 //
    142 // Internally, all 'primitive' types, and their unions, are represented as
    143 // bitsets. Bit 0 is reserved for tagging. Class is a heap pointer to the
    144 // respective map. Only structured types require allocation.
    145 // Note that the bitset representation is closed under both Union and Intersect.
    146 //
    147 // There are two type representations, using different allocation:
    148 //
    149 // - class Type (zone-allocated, for compiler and concurrent compilation)
    150 // - class HeapType (heap-allocated, for persistent types)
    151 //
    152 // Both provide the same API, and the Convert method can be used to interconvert
    153 // them. For zone types, no query method touches the heap, only constructors do.
    154 
    155 
    156 // -----------------------------------------------------------------------------
    157 // Values for bitset types
    158 
    159 // clang-format off
    160 
    161 #define MASK_BITSET_TYPE_LIST(V) \
    162   V(Representation, 0xff800000u) \
    163   V(Semantic,       0x007ffffeu)
    164 
    165 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
    166 #define SEMANTIC(k)       ((k) & BitsetType::kSemantic)
    167 
    168 #define REPRESENTATION_BITSET_TYPE_LIST(V)    \
    169   V(None,               0)                    \
    170   V(UntaggedBit,        1u << 23 | kSemantic) \
    171   V(UntaggedIntegral8,  1u << 24 | kSemantic) \
    172   V(UntaggedIntegral16, 1u << 25 | kSemantic) \
    173   V(UntaggedIntegral32, 1u << 26 | kSemantic) \
    174   V(UntaggedFloat32,    1u << 27 | kSemantic) \
    175   V(UntaggedFloat64,    1u << 28 | kSemantic) \
    176   V(UntaggedPointer,    1u << 29 | kSemantic) \
    177   V(TaggedSigned,       1u << 30 | kSemantic) \
    178   V(TaggedPointer,      1u << 31 | kSemantic) \
    179   \
    180   V(UntaggedIntegral,   kUntaggedBit | kUntaggedIntegral8 |        \
    181                         kUntaggedIntegral16 | kUntaggedIntegral32) \
    182   V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)       \
    183   V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)        \
    184   V(Untagged,           kUntaggedNumber | kUntaggedPointer)        \
    185   V(Tagged,             kTaggedSigned | kTaggedPointer)
    186 
    187 #define INTERNAL_BITSET_TYPE_LIST(V)                                      \
    188   V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
    189   V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
    190   V(OtherSigned32,   1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
    191   V(OtherNumber,     1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
    192 
    193 #define SEMANTIC_BITSET_TYPE_LIST(V) \
    194   V(Negative31,          1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
    195   V(Null,                1u << 6  | REPRESENTATION(kTaggedPointer)) \
    196   V(Undefined,           1u << 7  | REPRESENTATION(kTaggedPointer)) \
    197   V(Boolean,             1u << 8  | REPRESENTATION(kTaggedPointer)) \
    198   V(Unsigned30,          1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
    199   V(MinusZero,           1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
    200   V(NaN,                 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
    201   V(Symbol,              1u << 12 | REPRESENTATION(kTaggedPointer)) \
    202   V(InternalizedString,  1u << 13 | REPRESENTATION(kTaggedPointer)) \
    203   V(OtherString,         1u << 14 | REPRESENTATION(kTaggedPointer)) \
    204   V(Simd,                1u << 15 | REPRESENTATION(kTaggedPointer)) \
    205   V(Undetectable,        1u << 16 | REPRESENTATION(kTaggedPointer)) \
    206   V(OtherObject,         1u << 17 | REPRESENTATION(kTaggedPointer)) \
    207   V(Proxy,               1u << 18 | REPRESENTATION(kTaggedPointer)) \
    208   V(Function,            1u << 19 | REPRESENTATION(kTaggedPointer)) \
    209   V(Internal,            1u << 20 | REPRESENTATION(kTagged | kUntagged)) \
    210   \
    211   V(Signed31,                 kUnsigned30 | kNegative31) \
    212   V(Signed32,                 kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
    213   V(Negative32,               kNegative31 | kOtherSigned32) \
    214   V(Unsigned31,               kUnsigned30 | kOtherUnsigned31) \
    215   V(Unsigned32,               kUnsigned30 | kOtherUnsigned31 | \
    216                               kOtherUnsigned32) \
    217   V(Integral32,               kSigned32 | kUnsigned32) \
    218   V(PlainNumber,              kIntegral32 | kOtherNumber) \
    219   V(OrderedNumber,            kPlainNumber | kMinusZero) \
    220   V(MinusZeroOrNaN,           kMinusZero | kNaN) \
    221   V(Number,                   kOrderedNumber | kNaN) \
    222   V(String,                   kInternalizedString | kOtherString) \
    223   V(UniqueName,               kSymbol | kInternalizedString) \
    224   V(Name,                     kSymbol | kString) \
    225   V(BooleanOrNumber,          kBoolean | kNumber) \
    226   V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
    227   V(NullOrUndefined,          kNull | kUndefined) \
    228   V(NumberOrString,           kNumber | kString) \
    229   V(NumberOrUndefined,        kNumber | kUndefined) \
    230   V(PlainPrimitive,           kNumberOrString | kBoolean | kNullOrUndefined) \
    231   V(Primitive,                kSymbol | kSimd | kPlainPrimitive) \
    232   V(DetectableReceiver,       kFunction | kOtherObject | kProxy) \
    233   V(Detectable,               kDetectableReceiver | kNumber | kName) \
    234   V(Object,                   kFunction | kOtherObject | kUndetectable) \
    235   V(Receiver,                 kObject | kProxy) \
    236   V(StringOrReceiver,         kString | kReceiver) \
    237   V(Unique,                   kBoolean | kUniqueName | kNull | kUndefined | \
    238                               kReceiver) \
    239   V(NonNumber,                kUnique | kString | kInternal) \
    240   V(Any,                      0xfffffffeu)
    241 
    242 // clang-format on
    243 
    244 /*
    245  * The following diagrams show how integers (in the mathematical sense) are
    246  * divided among the different atomic numerical types.
    247  *
    248  *   ON    OS32     N31     U30     OU31    OU32     ON
    249  * ______[_______[_______[_______[_______[_______[_______
    250  *     -2^31   -2^30     0      2^30    2^31    2^32
    251  *
    252  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
    253  *
    254  * Some of the atomic numerical bitsets are internal only (see
    255  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
    256  * union with certain other bitsets.  For instance, OtherNumber should only
    257  * occur as part of PlainNumber.
    258  */
    259 
    260 #define PROPER_BITSET_TYPE_LIST(V) \
    261   REPRESENTATION_BITSET_TYPE_LIST(V) \
    262   SEMANTIC_BITSET_TYPE_LIST(V)
    263 
    264 #define BITSET_TYPE_LIST(V)          \
    265   MASK_BITSET_TYPE_LIST(V)           \
    266   REPRESENTATION_BITSET_TYPE_LIST(V) \
    267   INTERNAL_BITSET_TYPE_LIST(V)       \
    268   SEMANTIC_BITSET_TYPE_LIST(V)
    269 
    270 
    271 // -----------------------------------------------------------------------------
    272 // The abstract Type class, parameterized over the low-level representation.
    273 
    274 // struct Config {
    275 //   typedef TypeImpl<Config> Type;
    276 //   typedef Base;
    277 //   typedef Struct;
    278 //   typedef Range;
    279 //   typedef Region;
    280 //   template<class> struct Handle { typedef type; }  // No template typedefs...
    281 //
    282 //   template<class T> static Handle<T>::type null_handle();
    283 //   template<class T> static Handle<T>::type handle(T* t);  // !is_bitset(t)
    284 //   template<class T> static Handle<T>::type cast(Handle<Type>::type);
    285 //
    286 //   static bool is_bitset(Type*);
    287 //   static bool is_class(Type*);
    288 //   static bool is_struct(Type*, int tag);
    289 //   static bool is_range(Type*);
    290 //
    291 //   static bitset as_bitset(Type*);
    292 //   static i::Handle<i::Map> as_class(Type*);
    293 //   static Handle<Struct>::type as_struct(Type*);
    294 //   static Handle<Range>::type as_range(Type*);
    295 //
    296 //   static Type* from_bitset(bitset);
    297 //   static Handle<Type>::type from_bitset(bitset, Region*);
    298 //   static Handle<Type>::type from_class(i::Handle<Map>, Region*);
    299 //   static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
    300 //   static Handle<Type>::type from_range(Handle<Range>::type);
    301 //
    302 //   static Handle<Struct>::type struct_create(int tag, int length, Region*);
    303 //   static void struct_shrink(Handle<Struct>::type, int length);
    304 //   static int struct_tag(Handle<Struct>::type);
    305 //   static int struct_length(Handle<Struct>::type);
    306 //   static Handle<Type>::type struct_get(Handle<Struct>::type, int);
    307 //   static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
    308 //   template<class V>
    309 //   static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
    310 //   template<class V>
    311 //   static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
    312 //
    313 //   static Handle<Range>::type range_create(Region*);
    314 //   static int range_get_bitset(Handle<Range>::type);
    315 //   static void range_set_bitset(Handle<Range>::type, int);
    316 //   static double range_get_double(Handle<Range>::type, int);
    317 //   static void range_set_double(Handle<Range>::type, int, double, Region*);
    318 // }
    319 template<class Config>
    320 class TypeImpl : public Config::Base {
    321  public:
    322   // Auxiliary types.
    323 
    324   typedef uint32_t bitset;  // Internal
    325   class BitsetType;         // Internal
    326   class StructuralType;     // Internal
    327   class UnionType;          // Internal
    328 
    329   class ClassType;
    330   class ConstantType;
    331   class RangeType;
    332   class ContextType;
    333   class ArrayType;
    334   class FunctionType;
    335 
    336   typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
    337   typedef typename Config::template Handle<ClassType>::type ClassHandle;
    338   typedef typename Config::template Handle<ConstantType>::type ConstantHandle;
    339   typedef typename Config::template Handle<RangeType>::type RangeHandle;
    340   typedef typename Config::template Handle<ContextType>::type ContextHandle;
    341   typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
    342   typedef typename Config::template Handle<FunctionType>::type FunctionHandle;
    343   typedef typename Config::template Handle<UnionType>::type UnionHandle;
    344   typedef typename Config::Region Region;
    345 
    346   // Constructors.
    347 
    348   #define DEFINE_TYPE_CONSTRUCTOR(type, value)                                \
    349     static TypeImpl* type() {                                                 \
    350       return BitsetType::New(BitsetType::k##type);                            \
    351     }                                                                         \
    352     static TypeHandle type(Region* region) {                                  \
    353       return BitsetType::New(BitsetType::k##type, region);                    \
    354     }
    355   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
    356   #undef DEFINE_TYPE_CONSTRUCTOR
    357 
    358   static TypeImpl* SignedSmall() {
    359     return BitsetType::New(BitsetType::SignedSmall());
    360   }
    361   static TypeHandle SignedSmall(Region* region) {
    362     return BitsetType::New(BitsetType::SignedSmall(), region);
    363   }
    364   static TypeImpl* UnsignedSmall() {
    365     return BitsetType::New(BitsetType::UnsignedSmall());
    366   }
    367   static TypeHandle UnsignedSmall(Region* region) {
    368     return BitsetType::New(BitsetType::UnsignedSmall(), region);
    369   }
    370 
    371   static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
    372     return ClassType::New(map, region);
    373   }
    374   static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
    375     return ConstantType::New(value, region);
    376   }
    377   static TypeHandle Range(double min, double max, Region* region) {
    378     return RangeType::New(
    379         min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged |
    380                                                  BitsetType::kUntaggedNumber),
    381                                   region),
    382         region);
    383   }
    384   static TypeHandle Context(TypeHandle outer, Region* region) {
    385     return ContextType::New(outer, region);
    386   }
    387   static TypeHandle Array(TypeHandle element, Region* region) {
    388     return ArrayType::New(element, region);
    389   }
    390   static FunctionHandle Function(
    391       TypeHandle result, TypeHandle receiver, int arity, Region* region) {
    392     return FunctionType::New(result, receiver, arity, region);
    393   }
    394   static TypeHandle Function(TypeHandle result, Region* region) {
    395     return Function(result, Any(region), 0, region);
    396   }
    397   static TypeHandle Function(
    398       TypeHandle result, TypeHandle param0, Region* region) {
    399     FunctionHandle function = Function(result, Any(region), 1, region);
    400     function->InitParameter(0, param0);
    401     return function;
    402   }
    403   static TypeHandle Function(
    404       TypeHandle result, TypeHandle param0, TypeHandle param1, Region* region) {
    405     FunctionHandle function = Function(result, Any(region), 2, region);
    406     function->InitParameter(0, param0);
    407     function->InitParameter(1, param1);
    408     return function;
    409   }
    410   static TypeHandle Function(
    411       TypeHandle result, TypeHandle param0, TypeHandle param1,
    412       TypeHandle param2, Region* region) {
    413     FunctionHandle function = Function(result, Any(region), 3, region);
    414     function->InitParameter(0, param0);
    415     function->InitParameter(1, param1);
    416     function->InitParameter(2, param2);
    417     return function;
    418   }
    419   static TypeHandle Function(TypeHandle result, int arity, TypeHandle* params,
    420                              Region* region) {
    421     FunctionHandle function = Function(result, Any(region), arity, region);
    422     for (int i = 0; i < arity; ++i) {
    423       function->InitParameter(i, params[i]);
    424     }
    425     return function;
    426   }
    427 
    428 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
    429   static TypeHandle Name(Isolate* isolate, Region* region);
    430   SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
    431 #undef CONSTRUCT_SIMD_TYPE
    432 
    433   static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
    434   static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
    435 
    436   static TypeHandle Of(double value, Region* region) {
    437     return Config::from_bitset(BitsetType::ExpandInternals(
    438         BitsetType::Lub(value)), region);
    439   }
    440   static TypeHandle Of(i::Object* value, Region* region) {
    441     return Config::from_bitset(BitsetType::ExpandInternals(
    442         BitsetType::Lub(value)), region);
    443   }
    444   static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
    445     return Of(*value, region);
    446   }
    447 
    448   // Extraction of components.
    449   static TypeHandle Representation(TypeHandle t, Region* region);
    450   static TypeHandle Semantic(TypeHandle t, Region* region);
    451 
    452   // Predicates.
    453   bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
    454 
    455   bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
    456   template<class TypeHandle>
    457   bool Is(TypeHandle that) { return this->Is(*that); }
    458 
    459   bool Maybe(TypeImpl* that);
    460   template<class TypeHandle>
    461   bool Maybe(TypeHandle that) { return this->Maybe(*that); }
    462 
    463   bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
    464   template<class TypeHandle>
    465   bool Equals(TypeHandle that) { return this->Equals(*that); }
    466 
    467   // Equivalent to Constant(val)->Is(this), but avoiding allocation.
    468   bool Contains(i::Object* val);
    469   bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
    470 
    471   // State-dependent versions of the above that consider subtyping between
    472   // a constant and its map class.
    473   inline static TypeHandle NowOf(i::Object* value, Region* region);
    474   static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) {
    475     return NowOf(*value, region);
    476   }
    477   bool NowIs(TypeImpl* that);
    478   template<class TypeHandle>
    479   bool NowIs(TypeHandle that)  { return this->NowIs(*that); }
    480   inline bool NowContains(i::Object* val);
    481   bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
    482 
    483   bool NowStable();
    484 
    485   // Inspection.
    486 
    487   bool IsRange() { return Config::is_range(this); }
    488   bool IsClass() {
    489     return Config::is_class(this)
    490         || Config::is_struct(this, StructuralType::kClassTag);
    491   }
    492   bool IsConstant() {
    493     return Config::is_struct(this, StructuralType::kConstantTag);
    494   }
    495   bool IsContext() {
    496     return Config::is_struct(this, StructuralType::kContextTag);
    497   }
    498   bool IsArray() {
    499     return Config::is_struct(this, StructuralType::kArrayTag);
    500   }
    501   bool IsFunction() {
    502     return Config::is_struct(this, StructuralType::kFunctionTag);
    503   }
    504 
    505   ClassType* AsClass() { return ClassType::cast(this); }
    506   ConstantType* AsConstant() { return ConstantType::cast(this); }
    507   RangeType* AsRange() { return RangeType::cast(this); }
    508   ContextType* AsContext() { return ContextType::cast(this); }
    509   ArrayType* AsArray() { return ArrayType::cast(this); }
    510   FunctionType* AsFunction() { return FunctionType::cast(this); }
    511 
    512   // Minimum and maximum of a numeric type.
    513   // These functions do not distinguish between -0 and +0.  If the type equals
    514   // kNaN, they return NaN; otherwise kNaN is ignored.  Only call these
    515   // functions on subtypes of Number.
    516   double Min();
    517   double Max();
    518 
    519   // Extracts a range from the type: if the type is a range or a union
    520   // containing a range, that range is returned; otherwise, NULL is returned.
    521   RangeType* GetRange();
    522 
    523   static bool IsInteger(double x) {
    524     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
    525   }
    526   static bool IsInteger(i::Object* x) {
    527     return x->IsNumber() && IsInteger(x->Number());
    528   }
    529 
    530   int NumClasses();
    531   int NumConstants();
    532 
    533   template<class T> class Iterator;
    534   Iterator<i::Map> Classes() {
    535     if (this->IsBitset()) return Iterator<i::Map>();
    536     return Iterator<i::Map>(Config::handle(this));
    537   }
    538   Iterator<i::Object> Constants() {
    539     if (this->IsBitset()) return Iterator<i::Object>();
    540     return Iterator<i::Object>(Config::handle(this));
    541   }
    542 
    543   // Casting and conversion.
    544 
    545   static inline TypeImpl* cast(typename Config::Base* object);
    546 
    547   template<class OtherTypeImpl>
    548   static TypeHandle Convert(
    549       typename OtherTypeImpl::TypeHandle type, Region* region);
    550 
    551   // Printing.
    552 
    553   enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
    554 
    555   void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS);  // NOLINT
    556 
    557 #ifdef DEBUG
    558   void Print();
    559 #endif
    560 
    561   bool IsUnionForTesting() { return IsUnion(); }
    562 
    563  protected:
    564   // Friends.
    565 
    566   template<class> friend class Iterator;
    567   template<class> friend class TypeImpl;
    568 
    569   // Handle conversion.
    570 
    571   template<class T>
    572   static typename Config::template Handle<T>::type handle(T* type) {
    573     return Config::handle(type);
    574   }
    575   TypeImpl* unhandle() { return this; }
    576 
    577   // Internal inspection.
    578 
    579   bool IsNone() { return this == None(); }
    580   bool IsAny() { return this == Any(); }
    581   bool IsBitset() { return Config::is_bitset(this); }
    582   bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); }
    583 
    584   bitset AsBitset() {
    585     DCHECK(this->IsBitset());
    586     return static_cast<BitsetType*>(this)->Bitset();
    587   }
    588   UnionType* AsUnion() { return UnionType::cast(this); }
    589 
    590   bitset Representation();
    591 
    592   // Auxiliary functions.
    593   bool SemanticMaybe(TypeImpl* that);
    594 
    595   bitset BitsetGlb() { return BitsetType::Glb(this); }
    596   bitset BitsetLub() { return BitsetType::Lub(this); }
    597 
    598   bool SlowIs(TypeImpl* that);
    599   bool SemanticIs(TypeImpl* that);
    600 
    601   struct Limits {
    602     double min;
    603     double max;
    604     Limits(double min, double max) : min(min), max(max) {}
    605     explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
    606     bool IsEmpty();
    607     static Limits Empty() { return Limits(1, 0); }
    608     static Limits Intersect(Limits lhs, Limits rhs);
    609     static Limits Union(Limits lhs, Limits rhs);
    610   };
    611 
    612   static bool Overlap(RangeType* lhs, RangeType* rhs);
    613   static bool Contains(RangeType* lhs, RangeType* rhs);
    614   static bool Contains(RangeType* range, ConstantType* constant);
    615   static bool Contains(RangeType* range, i::Object* val);
    616 
    617   static int UpdateRange(
    618       RangeHandle type, UnionHandle result, int size, Region* region);
    619 
    620   static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits,
    621                                         Region* region);
    622   static Limits ToLimits(bitset bits, Region* region);
    623 
    624   bool SimplyEquals(TypeImpl* that);
    625   template<class TypeHandle>
    626   bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); }
    627 
    628   static int AddToUnion(
    629       TypeHandle type, UnionHandle result, int size, Region* region);
    630   static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result,
    631                           int size, Limits* limits, Region* region);
    632   static TypeHandle NormalizeUnion(UnionHandle unioned, int size,
    633                                    Region* region);
    634   static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits,
    635                                             Region* region);
    636 };
    637 
    638 
    639 // -----------------------------------------------------------------------------
    640 // Bitset types (internal).
    641 
    642 template<class Config>
    643 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
    644  protected:
    645   friend class TypeImpl<Config>;
    646 
    647   enum : uint32_t {
    648     #define DECLARE_TYPE(type, value) k##type = (value),
    649     BITSET_TYPE_LIST(DECLARE_TYPE)
    650     #undef DECLARE_TYPE
    651     kUnusedEOL = 0
    652   };
    653 
    654   static bitset SignedSmall();
    655   static bitset UnsignedSmall();
    656 
    657   bitset Bitset() { return Config::as_bitset(this); }
    658 
    659   static TypeImpl* New(bitset bits) {
    660     return Config::from_bitset(bits);
    661   }
    662   static TypeHandle New(bitset bits, Region* region) {
    663     return Config::from_bitset(bits, region);
    664   }
    665 
    666   static bool IsInhabited(bitset bits) {
    667     return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
    668   }
    669 
    670   static bool SemanticIsInhabited(bitset bits) {
    671     return SEMANTIC(bits) != kNone;
    672   }
    673 
    674   static bool Is(bitset bits1, bitset bits2) {
    675     return (bits1 | bits2) == bits2;
    676   }
    677 
    678   static double Min(bitset);
    679   static double Max(bitset);
    680 
    681   static bitset Glb(TypeImpl* type);  // greatest lower bound that's a bitset
    682   static bitset Glb(double min, double max);
    683   static bitset Lub(TypeImpl* type);  // least upper bound that's a bitset
    684   static bitset Lub(i::Map* map);
    685   static bitset Lub(i::Object* value);
    686   static bitset Lub(double value);
    687   static bitset Lub(double min, double max);
    688   static bitset ExpandInternals(bitset bits);
    689 
    690   static const char* Name(bitset);
    691   static void Print(std::ostream& os, bitset);  // NOLINT
    692 #ifdef DEBUG
    693   static void Print(bitset);
    694 #endif
    695 
    696   static bitset NumberBits(bitset bits);
    697 
    698  private:
    699   struct Boundary {
    700     bitset internal;
    701     bitset external;
    702     double min;
    703   };
    704   static const Boundary BoundariesArray[];
    705   static inline const Boundary* Boundaries();
    706   static inline size_t BoundariesSize();
    707 };
    708 
    709 
    710 // -----------------------------------------------------------------------------
    711 // Superclass for non-bitset types (internal).
    712 // Contains a tag and a variable number of type or value fields.
    713 
    714 template<class Config>
    715 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
    716  protected:
    717   template<class> friend class TypeImpl;
    718   friend struct ZoneTypeConfig;  // For tags.
    719   friend struct HeapTypeConfig;
    720 
    721   enum Tag {
    722     kClassTag,
    723     kConstantTag,
    724     kContextTag,
    725     kArrayTag,
    726     kFunctionTag,
    727     kUnionTag
    728   };
    729 
    730   int Length() {
    731     return Config::struct_length(Config::as_struct(this));
    732   }
    733   TypeHandle Get(int i) {
    734     DCHECK(0 <= i && i < this->Length());
    735     return Config::struct_get(Config::as_struct(this), i);
    736   }
    737   void Set(int i, TypeHandle type) {
    738     DCHECK(0 <= i && i < this->Length());
    739     Config::struct_set(Config::as_struct(this), i, type);
    740   }
    741   void Shrink(int length) {
    742     DCHECK(2 <= length && length <= this->Length());
    743     Config::struct_shrink(Config::as_struct(this), length);
    744   }
    745   template<class V> i::Handle<V> GetValue(int i) {
    746     DCHECK(0 <= i && i < this->Length());
    747     return Config::template struct_get_value<V>(Config::as_struct(this), i);
    748   }
    749   template<class V> void SetValue(int i, i::Handle<V> x) {
    750     DCHECK(0 <= i && i < this->Length());
    751     Config::struct_set_value(Config::as_struct(this), i, x);
    752   }
    753 
    754   static TypeHandle New(Tag tag, int length, Region* region) {
    755     DCHECK(1 <= length);
    756     return Config::from_struct(Config::struct_create(tag, length, region));
    757   }
    758 };
    759 
    760 
    761 // -----------------------------------------------------------------------------
    762 // Union types (internal).
    763 // A union is a structured type with the following invariants:
    764 // - its length is at least 2
    765 // - at most one field is a bitset, and it must go into index 0
    766 // - no field is a union
    767 // - no field is a subtype of any other field
    768 template<class Config>
    769 class TypeImpl<Config>::UnionType : public StructuralType {
    770  public:
    771   static UnionHandle New(int length, Region* region) {
    772     return Config::template cast<UnionType>(
    773         StructuralType::New(StructuralType::kUnionTag, length, region));
    774   }
    775 
    776   static UnionType* cast(TypeImpl* type) {
    777     DCHECK(type->IsUnion());
    778     return static_cast<UnionType*>(type);
    779   }
    780 
    781   bool Wellformed();
    782 };
    783 
    784 
    785 // -----------------------------------------------------------------------------
    786 // Class types.
    787 
    788 template<class Config>
    789 class TypeImpl<Config>::ClassType : public StructuralType {
    790  public:
    791   i::Handle<i::Map> Map() {
    792     return Config::is_class(this) ? Config::as_class(this) :
    793         this->template GetValue<i::Map>(1);
    794   }
    795 
    796   static ClassHandle New(i::Handle<i::Map> map, Region* region) {
    797     ClassHandle type =
    798         Config::template cast<ClassType>(Config::from_class(map, region));
    799     if (!type->IsClass()) {
    800       type = Config::template cast<ClassType>(
    801           StructuralType::New(StructuralType::kClassTag, 2, region));
    802       type->Set(0, BitsetType::New(BitsetType::Lub(*map), region));
    803       type->SetValue(1, map);
    804     }
    805     return type;
    806   }
    807 
    808   static ClassType* cast(TypeImpl* type) {
    809     DCHECK(type->IsClass());
    810     return static_cast<ClassType*>(type);
    811   }
    812 
    813  private:
    814   template<class> friend class TypeImpl;
    815   bitset Lub() {
    816     return Config::is_class(this) ?
    817         BitsetType::Lub(*Config::as_class(this)) :
    818         this->Get(0)->AsBitset();
    819   }
    820 };
    821 
    822 
    823 // -----------------------------------------------------------------------------
    824 // Constant types.
    825 
    826 template<class Config>
    827 class TypeImpl<Config>::ConstantType : public StructuralType {
    828  public:
    829   i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
    830 
    831   static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
    832     ConstantHandle type = Config::template cast<ConstantType>(
    833         StructuralType::New(StructuralType::kConstantTag, 2, region));
    834     type->Set(0, BitsetType::New(BitsetType::Lub(*value), region));
    835     type->SetValue(1, value);
    836     return type;
    837   }
    838 
    839   static ConstantType* cast(TypeImpl* type) {
    840     DCHECK(type->IsConstant());
    841     return static_cast<ConstantType*>(type);
    842   }
    843 
    844  private:
    845   template<class> friend class TypeImpl;
    846   bitset Lub() { return this->Get(0)->AsBitset(); }
    847 };
    848 // TODO(neis): Also cache value if numerical.
    849 // TODO(neis): Allow restricting the representation.
    850 
    851 
    852 // -----------------------------------------------------------------------------
    853 // Range types.
    854 
    855 template <class Config>
    856 class TypeImpl<Config>::RangeType : public TypeImpl<Config> {
    857  public:
    858   double Min() { return Config::range_get_double(Config::as_range(this), 0); }
    859   double Max() { return Config::range_get_double(Config::as_range(this), 1); }
    860 
    861   static RangeHandle New(double min, double max, TypeHandle representation,
    862                          Region* region) {
    863     DCHECK(IsInteger(min) && IsInteger(max));
    864     DCHECK(min <= max);
    865     bitset representation_bits = representation->AsBitset();
    866     DCHECK(REPRESENTATION(representation_bits) == representation_bits);
    867 
    868     typename Config::template Handle<typename Config::Range>::type range =
    869         Config::range_create(region);
    870 
    871     bitset bits = SEMANTIC(BitsetType::Lub(min, max)) | representation_bits;
    872     Config::range_set_bitset(range, bits);
    873     Config::range_set_double(range, 0, min, region);
    874     Config::range_set_double(range, 1, max, region);
    875     return Config::template cast<RangeType>(Config::from_range(range));
    876   }
    877 
    878   static RangeHandle New(Limits lim, bitset representation, Region* region) {
    879     return New(lim.min, lim.max, BitsetType::New(representation, region),
    880                region);
    881   }
    882 
    883   static RangeType* cast(TypeImpl* type) {
    884     DCHECK(type->IsRange());
    885     return static_cast<RangeType*>(type);
    886   }
    887 
    888  private:
    889   template<class> friend class TypeImpl;
    890   bitset Lub() {
    891     return Config::range_get_bitset(Config::as_range(this));
    892   }
    893 };
    894 
    895 
    896 // -----------------------------------------------------------------------------
    897 // Context types.
    898 
    899 template<class Config>
    900 class TypeImpl<Config>::ContextType : public StructuralType {
    901  public:
    902   TypeHandle Outer() { return this->Get(0); }
    903 
    904   static ContextHandle New(TypeHandle outer, Region* region) {
    905     ContextHandle type = Config::template cast<ContextType>(
    906         StructuralType::New(StructuralType::kContextTag, 1, region));
    907     type->Set(0, outer);
    908     return type;
    909   }
    910 
    911   static ContextType* cast(TypeImpl* type) {
    912     DCHECK(type->IsContext());
    913     return static_cast<ContextType*>(type);
    914   }
    915 };
    916 
    917 
    918 // -----------------------------------------------------------------------------
    919 // Array types.
    920 
    921 template<class Config>
    922 class TypeImpl<Config>::ArrayType : public StructuralType {
    923  public:
    924   TypeHandle Element() { return this->Get(0); }
    925 
    926   static ArrayHandle New(TypeHandle element, Region* region) {
    927     ArrayHandle type = Config::template cast<ArrayType>(
    928         StructuralType::New(StructuralType::kArrayTag, 1, region));
    929     type->Set(0, element);
    930     return type;
    931   }
    932 
    933   static ArrayType* cast(TypeImpl* type) {
    934     DCHECK(type->IsArray());
    935     return static_cast<ArrayType*>(type);
    936   }
    937 };
    938 
    939 
    940 // -----------------------------------------------------------------------------
    941 // Function types.
    942 
    943 template<class Config>
    944 class TypeImpl<Config>::FunctionType : public StructuralType {
    945  public:
    946   int Arity() { return this->Length() - 2; }
    947   TypeHandle Result() { return this->Get(0); }
    948   TypeHandle Receiver() { return this->Get(1); }
    949   TypeHandle Parameter(int i) { return this->Get(2 + i); }
    950 
    951   void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
    952 
    953   static FunctionHandle New(
    954       TypeHandle result, TypeHandle receiver, int arity, Region* region) {
    955     FunctionHandle type = Config::template cast<FunctionType>(
    956         StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
    957     type->Set(0, result);
    958     type->Set(1, receiver);
    959     return type;
    960   }
    961 
    962   static FunctionType* cast(TypeImpl* type) {
    963     DCHECK(type->IsFunction());
    964     return static_cast<FunctionType*>(type);
    965   }
    966 };
    967 
    968 
    969 // -----------------------------------------------------------------------------
    970 // Type iterators.
    971 
    972 template<class Config> template<class T>
    973 class TypeImpl<Config>::Iterator {
    974  public:
    975   bool Done() const { return index_ < 0; }
    976   i::Handle<T> Current();
    977   void Advance();
    978 
    979  private:
    980   template<class> friend class TypeImpl;
    981 
    982   Iterator() : index_(-1) {}
    983   explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
    984     Advance();
    985   }
    986 
    987   inline bool matches(TypeHandle type);
    988   inline TypeHandle get_type();
    989 
    990   TypeHandle type_;
    991   int index_;
    992 };
    993 
    994 
    995 // -----------------------------------------------------------------------------
    996 // Zone-allocated types; they are either (odd) integers to represent bitsets, or
    997 // (even) pointers to structures for everything else.
    998 
    999 struct ZoneTypeConfig {
   1000   typedef TypeImpl<ZoneTypeConfig> Type;
   1001   class Base {};
   1002   typedef void* Struct;
   1003   // Hack: the Struct and Range types can be aliased in memory, the first
   1004   // pointer word of each both must be the tag (kRangeStructTag for Range,
   1005   // anything else for Struct) so that we can differentiate them.
   1006   struct Range {
   1007     void* tag;
   1008     int bitset;
   1009     double limits[2];
   1010   };
   1011   typedef i::Zone Region;
   1012   template<class T> struct Handle { typedef T* type; };
   1013 
   1014   static const int kRangeStructTag = 0x1000;
   1015 
   1016   template<class T> static inline T* null_handle() { return nullptr; }
   1017   template<class T> static inline T* handle(T* type);
   1018   template<class T> static inline T* cast(Type* type);
   1019 
   1020   static inline bool is_bitset(Type* type);
   1021   static inline bool is_class(Type* type);
   1022   static inline bool is_struct(Type* type, int tag);
   1023   static inline bool is_range(Type* type);
   1024 
   1025   static inline Type::bitset as_bitset(Type* type);
   1026   static inline i::Handle<i::Map> as_class(Type* type);
   1027   static inline Struct* as_struct(Type* type);
   1028   static inline Range* as_range(Type* type);
   1029 
   1030   static inline Type* from_bitset(Type::bitset);
   1031   static inline Type* from_bitset(Type::bitset, Zone* zone);
   1032   static inline Type* from_class(i::Handle<i::Map> map, Zone* zone);
   1033   static inline Type* from_struct(Struct* structured);
   1034   static inline Type* from_range(Range* range);
   1035 
   1036   static inline Struct* struct_create(int tag, int length, Zone* zone);
   1037   static inline void struct_shrink(Struct* structure, int length);
   1038   static inline int struct_tag(Struct* structure);
   1039   static inline int struct_length(Struct* structure);
   1040   static inline Type* struct_get(Struct* structure, int i);
   1041   static inline void struct_set(Struct* structure, int i, Type* type);
   1042   template<class V>
   1043   static inline i::Handle<V> struct_get_value(Struct* structure, int i);
   1044   template<class V> static inline void struct_set_value(
   1045       Struct* structure, int i, i::Handle<V> x);
   1046 
   1047   static inline Range* range_create(Zone* zone);
   1048   static inline int range_get_bitset(Range* range);
   1049   static inline void range_set_bitset(Range* range, int);
   1050   static inline double range_get_double(Range*, int index);
   1051   static inline void range_set_double(Range*, int index, double value, Zone*);
   1052 };
   1053 
   1054 typedef TypeImpl<ZoneTypeConfig> Type;
   1055 
   1056 
   1057 // -----------------------------------------------------------------------------
   1058 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for
   1059 // constants, or fixed arrays for unions.
   1060 
   1061 struct HeapTypeConfig {
   1062   typedef TypeImpl<HeapTypeConfig> Type;
   1063   typedef i::Object Base;
   1064   typedef i::FixedArray Struct;
   1065   typedef i::FixedArray Range;
   1066   typedef i::Isolate Region;
   1067   template<class T> struct Handle { typedef i::Handle<T> type; };
   1068 
   1069   static const int kRangeStructTag = 0xffff;
   1070 
   1071   template<class T> static inline i::Handle<T> null_handle() {
   1072     return i::Handle<T>();
   1073   }
   1074   template<class T> static inline i::Handle<T> handle(T* type);
   1075   template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
   1076 
   1077   static inline bool is_bitset(Type* type);
   1078   static inline bool is_class(Type* type);
   1079   static inline bool is_struct(Type* type, int tag);
   1080   static inline bool is_range(Type* type);
   1081 
   1082   static inline Type::bitset as_bitset(Type* type);
   1083   static inline i::Handle<i::Map> as_class(Type* type);
   1084   static inline i::Handle<Struct> as_struct(Type* type);
   1085   static inline i::Handle<Range> as_range(Type* type);
   1086 
   1087   static inline Type* from_bitset(Type::bitset);
   1088   static inline i::Handle<Type> from_bitset(Type::bitset, Isolate* isolate);
   1089   static inline i::Handle<Type> from_class(
   1090       i::Handle<i::Map> map, Isolate* isolate);
   1091   static inline i::Handle<Type> from_struct(i::Handle<Struct> structure);
   1092   static inline i::Handle<Type> from_range(i::Handle<Range> range);
   1093 
   1094   static inline i::Handle<Struct> struct_create(
   1095       int tag, int length, Isolate* isolate);
   1096   static inline void struct_shrink(i::Handle<Struct> structure, int length);
   1097   static inline int struct_tag(i::Handle<Struct> structure);
   1098   static inline int struct_length(i::Handle<Struct> structure);
   1099   static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i);
   1100   static inline void struct_set(
   1101       i::Handle<Struct> structure, int i, i::Handle<Type> type);
   1102   template<class V>
   1103   static inline i::Handle<V> struct_get_value(
   1104       i::Handle<Struct> structure, int i);
   1105   template<class V>
   1106   static inline void struct_set_value(
   1107       i::Handle<Struct> structure, int i, i::Handle<V> x);
   1108 
   1109   static inline i::Handle<Range> range_create(Isolate* isolate);
   1110   static inline int range_get_bitset(i::Handle<Range> range);
   1111   static inline void range_set_bitset(i::Handle<Range> range, int value);
   1112   static inline double range_get_double(i::Handle<Range> range, int index);
   1113   static inline void range_set_double(i::Handle<Range> range, int index,
   1114                                       double value, Isolate* isolate);
   1115 };
   1116 
   1117 typedef TypeImpl<HeapTypeConfig> HeapType;
   1118 
   1119 
   1120 // -----------------------------------------------------------------------------
   1121 // Type bounds. A simple struct to represent a pair of lower/upper types.
   1122 
   1123 template<class Config>
   1124 struct BoundsImpl {
   1125   typedef TypeImpl<Config> Type;
   1126   typedef typename Type::TypeHandle TypeHandle;
   1127   typedef typename Type::Region Region;
   1128 
   1129   TypeHandle lower;
   1130   TypeHandle upper;
   1131 
   1132   BoundsImpl() :  // Make sure accessing uninitialized bounds crashes big-time.
   1133     lower(Config::template null_handle<Type>()),
   1134     upper(Config::template null_handle<Type>()) {}
   1135   explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {}
   1136   BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) {
   1137     DCHECK(lower->Is(upper));
   1138   }
   1139 
   1140   // Unrestricted bounds.
   1141   static BoundsImpl Unbounded() {
   1142     return BoundsImpl(Type::None(), Type::Any());
   1143   }
   1144 
   1145   // Meet: both b1 and b2 are known to hold.
   1146   static BoundsImpl Both(BoundsImpl b1, BoundsImpl b2, Region* region) {
   1147     TypeHandle lower = Type::Union(b1.lower, b2.lower, region);
   1148     TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region);
   1149     // Lower bounds are considered approximate, correct as necessary.
   1150     if (!lower->Is(upper)) lower = upper;
   1151     return BoundsImpl(lower, upper);
   1152   }
   1153 
   1154   // Join: either b1 or b2 is known to hold.
   1155   static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region* region) {
   1156     TypeHandle lower = Type::Intersect(b1.lower, b2.lower, region);
   1157     TypeHandle upper = Type::Union(b1.upper, b2.upper, region);
   1158     return BoundsImpl(lower, upper);
   1159   }
   1160 
   1161   static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) {
   1162     TypeHandle lower = Type::Union(b.lower, t, region);
   1163     // Lower bounds are considered approximate, correct as necessary.
   1164     if (!lower->Is(b.upper)) lower = b.upper;
   1165     return BoundsImpl(lower, b.upper);
   1166   }
   1167   static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) {
   1168     TypeHandle lower = b.lower;
   1169     TypeHandle upper = Type::Intersect(b.upper, t, region);
   1170     // Lower bounds are considered approximate, correct as necessary.
   1171     if (!lower->Is(upper)) lower = upper;
   1172     return BoundsImpl(lower, upper);
   1173   }
   1174 
   1175   bool Narrows(BoundsImpl that) {
   1176     return that.lower->Is(this->lower) && this->upper->Is(that.upper);
   1177   }
   1178 };
   1179 
   1180 typedef BoundsImpl<ZoneTypeConfig> Bounds;
   1181 
   1182 }  // namespace internal
   1183 }  // namespace v8
   1184 
   1185 #endif  // V8_TYPES_H_
   1186