Home | History | Annotate | Download | only in cctest
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <vector>
     29 
     30 #include "src/hydrogen-types.h"
     31 #include "src/types.h"
     32 #include "src/utils/random-number-generator.h"
     33 #include "test/cctest/cctest.h"
     34 
     35 using namespace v8::internal;
     36 
     37 // Testing auxiliaries (breaking the Type abstraction).
     38 struct ZoneRep {
     39   typedef void* Struct;
     40 
     41   static bool IsStruct(Type* t, int tag) {
     42     return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
     43   }
     44   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
     45   static bool IsClass(Type* t) { return IsStruct(t, 0); }
     46   static bool IsConstant(Type* t) { return IsStruct(t, 1); }
     47   static bool IsContext(Type* t) { return IsStruct(t, 2); }
     48   static bool IsArray(Type* t) { return IsStruct(t, 3); }
     49   static bool IsFunction(Type* t) { return IsStruct(t, 4); }
     50   static bool IsUnion(Type* t) { return IsStruct(t, 5); }
     51 
     52   static Struct* AsStruct(Type* t) {
     53     return reinterpret_cast<Struct*>(t);
     54   }
     55   static int AsBitset(Type* t) {
     56     return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
     57   }
     58   static Map* AsClass(Type* t) {
     59     return *static_cast<Map**>(AsStruct(t)[3]);
     60   }
     61   static Object* AsConstant(Type* t) {
     62     return *static_cast<Object**>(AsStruct(t)[3]);
     63   }
     64   static Type* AsContext(Type* t) {
     65     return *static_cast<Type**>(AsStruct(t)[2]);
     66   }
     67   static Struct* AsUnion(Type* t) {
     68     return AsStruct(t);
     69   }
     70   static int Length(Struct* structured) {
     71     return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
     72   }
     73 
     74   static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
     75 
     76   struct BitsetType : Type::BitsetType {
     77     using Type::BitsetType::New;
     78     using Type::BitsetType::Glb;
     79     using Type::BitsetType::Lub;
     80     using Type::BitsetType::InherentLub;
     81   };
     82 };
     83 
     84 
     85 struct HeapRep {
     86   typedef FixedArray Struct;
     87 
     88   static bool IsStruct(Handle<HeapType> t, int tag) {
     89     return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
     90   }
     91   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
     92   static bool IsClass(Handle<HeapType> t) {
     93     return t->IsMap() || IsStruct(t, 0);
     94   }
     95   static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); }
     96   static bool IsContext(Handle<HeapType> t) { return IsStruct(t, 2); }
     97   static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 3); }
     98   static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 4); }
     99   static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 5); }
    100 
    101   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
    102   static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
    103   static Map* AsClass(Handle<HeapType> t) {
    104     return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2));
    105   }
    106   static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); }
    107   static HeapType* AsContext(Handle<HeapType> t) {
    108     return HeapType::cast(AsStruct(t)->get(1));
    109   }
    110   static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
    111   static int Length(Struct* structured) { return structured->length() - 1; }
    112 
    113   static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
    114 
    115   struct BitsetType : HeapType::BitsetType {
    116     using HeapType::BitsetType::New;
    117     using HeapType::BitsetType::Glb;
    118     using HeapType::BitsetType::Lub;
    119     using HeapType::BitsetType::InherentLub;
    120     static int Glb(Handle<HeapType> type) { return Glb(*type); }
    121     static int Lub(Handle<HeapType> type) { return Lub(*type); }
    122     static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); }
    123   };
    124 };
    125 
    126 
    127 template<class Type, class TypeHandle, class Region>
    128 class Types {
    129  public:
    130   Types(Region* region, Isolate* isolate) : region_(region) {
    131     #define DECLARE_TYPE(name, value) \
    132       name = Type::name(region); \
    133       types.push_back(name);
    134     BITSET_TYPE_LIST(DECLARE_TYPE)
    135     #undef DECLARE_TYPE
    136 
    137     object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize);
    138     array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize);
    139     uninitialized_map = isolate->factory()->uninitialized_map();
    140     ObjectClass = Type::Class(object_map, region);
    141     ArrayClass = Type::Class(array_map, region);
    142     UninitializedClass = Type::Class(uninitialized_map, region);
    143 
    144     maps.push_back(object_map);
    145     maps.push_back(array_map);
    146     maps.push_back(uninitialized_map);
    147     for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
    148       types.push_back(Type::Class(*it, region));
    149     }
    150 
    151     smi = handle(Smi::FromInt(666), isolate);
    152     signed32 = isolate->factory()->NewHeapNumber(0x40000000);
    153     object1 = isolate->factory()->NewJSObjectFromMap(object_map);
    154     object2 = isolate->factory()->NewJSObjectFromMap(object_map);
    155     array = isolate->factory()->NewJSArray(20);
    156     uninitialized = isolate->factory()->uninitialized_value();
    157     SmiConstant = Type::Constant(smi, region);
    158     Signed32Constant = Type::Constant(signed32, region);
    159     ObjectConstant1 = Type::Constant(object1, region);
    160     ObjectConstant2 = Type::Constant(object2, region);
    161     ArrayConstant = Type::Constant(array, region);
    162     UninitializedConstant = Type::Constant(uninitialized, region);
    163 
    164     values.push_back(smi);
    165     values.push_back(signed32);
    166     values.push_back(object1);
    167     values.push_back(object2);
    168     values.push_back(array);
    169     values.push_back(uninitialized);
    170     for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
    171       types.push_back(Type::Constant(*it, region));
    172     }
    173 
    174     NumberArray = Type::Array(Number, region);
    175     StringArray = Type::Array(String, region);
    176     AnyArray = Type::Array(Any, region);
    177 
    178     SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
    179     NumberFunction1 = Type::Function(Number, Number, region);
    180     NumberFunction2 = Type::Function(Number, Number, Number, region);
    181     MethodFunction = Type::Function(String, Object, 0, region);
    182 
    183     for (int i = 0; i < 50; ++i) {
    184       types.push_back(Fuzz());
    185     }
    186   }
    187 
    188   Handle<i::Map> object_map;
    189   Handle<i::Map> array_map;
    190   Handle<i::Map> uninitialized_map;
    191 
    192   Handle<i::Smi> smi;
    193   Handle<i::HeapNumber> signed32;
    194   Handle<i::JSObject> object1;
    195   Handle<i::JSObject> object2;
    196   Handle<i::JSArray> array;
    197   Handle<i::Oddball> uninitialized;
    198 
    199   #define DECLARE_TYPE(name, value) TypeHandle name;
    200   BITSET_TYPE_LIST(DECLARE_TYPE)
    201   #undef DECLARE_TYPE
    202 
    203   TypeHandle ObjectClass;
    204   TypeHandle ArrayClass;
    205   TypeHandle UninitializedClass;
    206 
    207   TypeHandle SmiConstant;
    208   TypeHandle Signed32Constant;
    209   TypeHandle ObjectConstant1;
    210   TypeHandle ObjectConstant2;
    211   TypeHandle ArrayConstant;
    212   TypeHandle UninitializedConstant;
    213 
    214   TypeHandle NumberArray;
    215   TypeHandle StringArray;
    216   TypeHandle AnyArray;
    217 
    218   TypeHandle SignedFunction1;
    219   TypeHandle NumberFunction1;
    220   TypeHandle NumberFunction2;
    221   TypeHandle MethodFunction;
    222 
    223   typedef std::vector<TypeHandle> TypeVector;
    224   typedef std::vector<Handle<i::Map> > MapVector;
    225   typedef std::vector<Handle<i::Object> > ValueVector;
    226   TypeVector types;
    227   MapVector maps;
    228   ValueVector values;
    229 
    230   TypeHandle Of(Handle<i::Object> value) {
    231     return Type::Of(value, region_);
    232   }
    233 
    234   TypeHandle NowOf(Handle<i::Object> value) {
    235     return Type::NowOf(value, region_);
    236   }
    237 
    238   TypeHandle Constant(Handle<i::Object> value) {
    239     return Type::Constant(value, region_);
    240   }
    241 
    242   TypeHandle Class(Handle<i::Map> map) {
    243     return Type::Class(map, region_);
    244   }
    245 
    246   TypeHandle Array1(TypeHandle element) {
    247     return Type::Array(element, region_);
    248   }
    249 
    250   TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
    251     return Type::Function(result, receiver, 0, region_);
    252   }
    253 
    254   TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
    255     TypeHandle type = Type::Function(result, receiver, 1, region_);
    256     type->AsFunction()->InitParameter(0, arg);
    257     return type;
    258   }
    259 
    260   TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
    261     return Type::Function(result, arg1, arg2, region_);
    262   }
    263 
    264   TypeHandle Union(TypeHandle t1, TypeHandle t2) {
    265     return Type::Union(t1, t2, region_);
    266   }
    267   TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
    268     return Type::Intersect(t1, t2, region_);
    269   }
    270 
    271   template<class Type2, class TypeHandle2>
    272   TypeHandle Convert(TypeHandle2 t) {
    273     return Type::template Convert<Type2>(t, region_);
    274   }
    275 
    276   TypeHandle Random() {
    277     return types[rng_.NextInt(static_cast<int>(types.size()))];
    278   }
    279 
    280   TypeHandle Fuzz(int depth = 5) {
    281     switch (rng_.NextInt(depth == 0 ? 3 : 20)) {
    282       case 0: {  // bitset
    283         int n = 0
    284         #define COUNT_BITSET_TYPES(type, value) + 1
    285         BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
    286         #undef COUNT_BITSET_TYPES
    287         ;
    288         int i = rng_.NextInt(n);
    289         #define PICK_BITSET_TYPE(type, value) \
    290           if (i-- == 0) return Type::type(region_);
    291         BITSET_TYPE_LIST(PICK_BITSET_TYPE)
    292         #undef PICK_BITSET_TYPE
    293         UNREACHABLE();
    294       }
    295       case 1: {  // class
    296         int i = rng_.NextInt(static_cast<int>(maps.size()));
    297         return Type::Class(maps[i], region_);
    298       }
    299       case 2: {  // constant
    300         int i = rng_.NextInt(static_cast<int>(values.size()));
    301         return Type::Constant(values[i], region_);
    302       }
    303       case 3: {  // context
    304         int depth = rng_.NextInt(3);
    305         TypeHandle type = Type::Internal(region_);
    306         for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
    307         return type;
    308       }
    309       case 4: {  // array
    310         TypeHandle element = Fuzz(depth / 2);
    311         return Type::Array(element, region_);
    312       }
    313       case 5:
    314       case 6:
    315       case 7: {  // function
    316         TypeHandle result = Fuzz(depth / 2);
    317         TypeHandle receiver = Fuzz(depth / 2);
    318         int arity = rng_.NextInt(3);
    319         TypeHandle type = Type::Function(result, receiver, arity, region_);
    320         for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
    321           TypeHandle parameter = Fuzz(depth - 1);
    322           type->AsFunction()->InitParameter(i, parameter);
    323         }
    324       }
    325       default: {  // union
    326         int n = rng_.NextInt(10);
    327         TypeHandle type = None;
    328         for (int i = 0; i < n; ++i) {
    329           TypeHandle operand = Fuzz(depth - 1);
    330           type = Type::Union(type, operand, region_);
    331         }
    332         return type;
    333       }
    334     }
    335     UNREACHABLE();
    336   }
    337 
    338   Region* region() { return region_; }
    339 
    340  private:
    341   Region* region_;
    342   RandomNumberGenerator rng_;
    343 };
    344 
    345 
    346 template<class Type, class TypeHandle, class Region, class Rep>
    347 struct Tests : Rep {
    348   typedef Types<Type, TypeHandle, Region> TypesInstance;
    349   typedef typename TypesInstance::TypeVector::iterator TypeIterator;
    350   typedef typename TypesInstance::MapVector::iterator MapIterator;
    351   typedef typename TypesInstance::ValueVector::iterator ValueIterator;
    352 
    353   Isolate* isolate;
    354   HandleScope scope;
    355   Zone zone;
    356   TypesInstance T;
    357 
    358   Tests() :
    359       isolate(CcTest::i_isolate()),
    360       scope(isolate),
    361       zone(isolate),
    362       T(Rep::ToRegion(&zone, isolate), isolate) {
    363   }
    364 
    365   bool Equal(TypeHandle type1, TypeHandle type2) {
    366     return
    367         type1->Is(type2) && type2->Is(type1) &&
    368         Rep::IsBitset(type1) == Rep::IsBitset(type2) &&
    369         Rep::IsClass(type1) == Rep::IsClass(type2) &&
    370         Rep::IsConstant(type1) == Rep::IsConstant(type2) &&
    371         Rep::IsContext(type1) == Rep::IsContext(type2) &&
    372         Rep::IsArray(type1) == Rep::IsArray(type2) &&
    373         Rep::IsFunction(type1) == Rep::IsFunction(type2) &&
    374         Rep::IsUnion(type1) == Rep::IsUnion(type2) &&
    375         type1->NumClasses() == type2->NumClasses() &&
    376         type1->NumConstants() == type2->NumConstants() &&
    377         (!Rep::IsBitset(type1) ||
    378           Rep::AsBitset(type1) == Rep::AsBitset(type2)) &&
    379         (!Rep::IsClass(type1) ||
    380           Rep::AsClass(type1) == Rep::AsClass(type2)) &&
    381         (!Rep::IsConstant(type1) ||
    382           Rep::AsConstant(type1) == Rep::AsConstant(type2)) &&
    383           // TODO(rossberg): Check details of arrays, functions, bounds.
    384           (!Rep::IsUnion(type1) ||
    385           Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2)));
    386   }
    387 
    388   void CheckEqual(TypeHandle type1, TypeHandle type2) {
    389     CHECK(Equal(type1, type2));
    390   }
    391 
    392   void CheckSub(TypeHandle type1, TypeHandle type2) {
    393     CHECK(type1->Is(type2));
    394     CHECK(!type2->Is(type1));
    395     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
    396       CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
    397     }
    398   }
    399 
    400   void CheckUnordered(TypeHandle type1, TypeHandle type2) {
    401     CHECK(!type1->Is(type2));
    402     CHECK(!type2->Is(type1));
    403     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
    404       CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
    405     }
    406   }
    407 
    408   void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
    409     CHECK(type1->Maybe(type2));
    410     CHECK(type2->Maybe(type1));
    411     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
    412       CHECK_NE(0,
    413           Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
    414     }
    415   }
    416 
    417   void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
    418     CHECK(!type1->Is(type2));
    419     CHECK(!type2->Is(type1));
    420     CHECK(!type1->Maybe(type2));
    421     CHECK(!type2->Maybe(type1));
    422     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
    423       CHECK_EQ(0,
    424           Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
    425     }
    426   }
    427 
    428   void Bitset() {
    429     // None and Any are bitsets.
    430     CHECK(this->IsBitset(T.None));
    431     CHECK(this->IsBitset(T.Any));
    432 
    433     CHECK_EQ(0, this->AsBitset(T.None));
    434     CHECK_EQ(-1, this->AsBitset(T.Any));
    435 
    436     // Union(T1, T2) is bitset for bitsets T1,T2
    437     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    438       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    439         TypeHandle type1 = *it1;
    440         TypeHandle type2 = *it2;
    441         TypeHandle union12 = T.Union(type1, type2);
    442         CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
    443               this->IsBitset(union12));
    444       }
    445     }
    446 
    447     // Intersect(T1, T2) is bitset for bitsets T1,T2
    448     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    449       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    450         TypeHandle type1 = *it1;
    451         TypeHandle type2 = *it2;
    452         TypeHandle intersect12 = T.Intersect(type1, type2);
    453         CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
    454               this->IsBitset(intersect12));
    455       }
    456     }
    457 
    458     // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2)
    459     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    460       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    461         TypeHandle type1 = *it1;
    462         TypeHandle type2 = *it2;
    463         TypeHandle union12 = T.Union(type1, type2);
    464         CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
    465               this->IsBitset(union12));
    466       }
    467     }
    468 
    469     // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
    470     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    471       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    472         TypeHandle type1 = *it1;
    473         TypeHandle type2 = *it2;
    474         TypeHandle union12 = T.Union(type1, type2);
    475         if (this->IsBitset(type1) && this->IsBitset(type2)) {
    476           CHECK_EQ(
    477               this->AsBitset(type1) | this->AsBitset(type2),
    478               this->AsBitset(union12));
    479         }
    480       }
    481     }
    482 
    483     // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2
    484     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    485       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    486         TypeHandle type1 = *it1;
    487         TypeHandle type2 = *it2;
    488         TypeHandle intersect12 = T.Intersect(type1, type2);
    489         if (this->IsBitset(type1) && this->IsBitset(type2)) {
    490           CHECK_EQ(
    491               this->AsBitset(type1) & this->AsBitset(type2),
    492               this->AsBitset(intersect12));
    493         }
    494       }
    495     }
    496   }
    497 
    498   void Class() {
    499     // Constructor
    500     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
    501       Handle<i::Map> map = *mt;
    502       TypeHandle type = T.Class(map);
    503       CHECK(this->IsClass(type));
    504     }
    505 
    506     // Map attribute
    507     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
    508       Handle<i::Map> map = *mt;
    509       TypeHandle type = T.Class(map);
    510       CHECK(*map == *type->AsClass()->Map());
    511     }
    512 
    513     // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
    514     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
    515       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
    516         Handle<i::Map> map1 = *mt1;
    517         Handle<i::Map> map2 = *mt2;
    518         TypeHandle type1 = T.Class(map1);
    519         TypeHandle type2 = T.Class(map2);
    520         CHECK(Equal(type1, type2) == (*map1 == *map2));
    521       }
    522     }
    523   }
    524 
    525   void Constant() {
    526     // Constructor
    527     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    528       Handle<i::Object> value = *vt;
    529       TypeHandle type = T.Constant(value);
    530       CHECK(this->IsConstant(type));
    531     }
    532 
    533     // Value attribute
    534     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    535       Handle<i::Object> value = *vt;
    536       TypeHandle type = T.Constant(value);
    537       CHECK(*value == *type->AsConstant()->Value());
    538     }
    539 
    540     // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
    541     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
    542       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
    543         Handle<i::Object> value1 = *vt1;
    544         Handle<i::Object> value2 = *vt2;
    545         TypeHandle type1 = T.Constant(value1);
    546         TypeHandle type2 = T.Constant(value2);
    547         CHECK(Equal(type1, type2) == (*value1 == *value2));
    548       }
    549     }
    550 
    551     // Typing of numbers
    552     Factory* fac = isolate->factory();
    553     CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
    554     CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
    555     CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
    556     CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
    557     CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
    558     CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
    559     if (SmiValuesAre31Bits()) {
    560       CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
    561       CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
    562       CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
    563       CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
    564       CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
    565     } else {
    566       CHECK(SmiValuesAre32Bits());
    567       CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
    568       CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
    569       CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
    570       CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
    571       CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
    572       CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
    573       CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
    574       CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
    575       CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
    576       CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
    577     }
    578     CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
    579     CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
    580     CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
    581     CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
    582     CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
    583     CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
    584     CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
    585     CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
    586     CHECK(T.Constant(fac->NewNumber(OS::nan_value()))->Is(T.NaN));
    587     CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
    588     CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
    589   }
    590 
    591   void Array() {
    592     // Constructor
    593     for (int i = 0; i < 20; ++i) {
    594       TypeHandle type = T.Random();
    595       TypeHandle array = T.Array1(type);
    596       CHECK(this->IsArray(array));
    597     }
    598 
    599     // Attributes
    600     for (int i = 0; i < 20; ++i) {
    601       TypeHandle type = T.Random();
    602       TypeHandle array = T.Array1(type);
    603       CheckEqual(type, array->AsArray()->Element());
    604     }
    605 
    606     // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
    607     for (int i = 0; i < 20; ++i) {
    608       for (int j = 0; j < 20; ++j) {
    609         TypeHandle type1 = T.Random();
    610         TypeHandle type2 = T.Random();
    611         TypeHandle array1 = T.Array1(type1);
    612         TypeHandle array2 = T.Array1(type2);
    613         CHECK(Equal(array1, array2) == Equal(type1, type2));
    614       }
    615     }
    616   }
    617 
    618   void Function() {
    619     // Constructors
    620     for (int i = 0; i < 20; ++i) {
    621       for (int j = 0; j < 20; ++j) {
    622         for (int k = 0; k < 20; ++k) {
    623           TypeHandle type1 = T.Random();
    624           TypeHandle type2 = T.Random();
    625           TypeHandle type3 = T.Random();
    626           TypeHandle function0 = T.Function0(type1, type2);
    627           TypeHandle function1 = T.Function1(type1, type2, type3);
    628           TypeHandle function2 = T.Function2(type1, type2, type3);
    629           CHECK(function0->IsFunction());
    630           CHECK(function1->IsFunction());
    631           CHECK(function2->IsFunction());
    632         }
    633       }
    634     }
    635 
    636     // Attributes
    637     for (int i = 0; i < 20; ++i) {
    638       for (int j = 0; j < 20; ++j) {
    639         for (int k = 0; k < 20; ++k) {
    640           TypeHandle type1 = T.Random();
    641           TypeHandle type2 = T.Random();
    642           TypeHandle type3 = T.Random();
    643           TypeHandle function0 = T.Function0(type1, type2);
    644           TypeHandle function1 = T.Function1(type1, type2, type3);
    645           TypeHandle function2 = T.Function2(type1, type2, type3);
    646           CHECK_EQ(0, function0->AsFunction()->Arity());
    647           CHECK_EQ(1, function1->AsFunction()->Arity());
    648           CHECK_EQ(2, function2->AsFunction()->Arity());
    649           CheckEqual(type1, function0->AsFunction()->Result());
    650           CheckEqual(type1, function1->AsFunction()->Result());
    651           CheckEqual(type1, function2->AsFunction()->Result());
    652           CheckEqual(type2, function0->AsFunction()->Receiver());
    653           CheckEqual(type2, function1->AsFunction()->Receiver());
    654           CheckEqual(T.Any, function2->AsFunction()->Receiver());
    655           CheckEqual(type3, function1->AsFunction()->Parameter(0));
    656           CheckEqual(type2, function2->AsFunction()->Parameter(0));
    657           CheckEqual(type3, function2->AsFunction()->Parameter(1));
    658         }
    659       }
    660     }
    661 
    662     // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
    663     for (int i = 0; i < 20; ++i) {
    664       for (int j = 0; j < 20; ++j) {
    665         for (int k = 0; k < 20; ++k) {
    666           TypeHandle type1 = T.Random();
    667           TypeHandle type2 = T.Random();
    668           TypeHandle type3 = T.Random();
    669           TypeHandle function01 = T.Function0(type1, type2);
    670           TypeHandle function02 = T.Function0(type1, type3);
    671           TypeHandle function03 = T.Function0(type3, type2);
    672           TypeHandle function11 = T.Function1(type1, type2, type2);
    673           TypeHandle function12 = T.Function1(type1, type2, type3);
    674           TypeHandle function21 = T.Function2(type1, type2, type2);
    675           TypeHandle function22 = T.Function2(type1, type2, type3);
    676           TypeHandle function23 = T.Function2(type1, type3, type2);
    677           CHECK(Equal(function01, function02) == Equal(type2, type3));
    678           CHECK(Equal(function01, function03) == Equal(type1, type3));
    679           CHECK(Equal(function11, function12) == Equal(type2, type3));
    680           CHECK(Equal(function21, function22) == Equal(type2, type3));
    681           CHECK(Equal(function21, function23) == Equal(type2, type3));
    682         }
    683       }
    684     }
    685   }
    686 
    687   void Of() {
    688     // Constant(V)->Is(Of(V))
    689     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    690       Handle<i::Object> value = *vt;
    691       TypeHandle const_type = T.Constant(value);
    692       TypeHandle of_type = T.Of(value);
    693       CHECK(const_type->Is(of_type));
    694     }
    695 
    696     // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V))
    697     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    698       for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    699         Handle<i::Object> value = *vt;
    700         TypeHandle type = *it;
    701         TypeHandle const_type = T.Constant(value);
    702         TypeHandle of_type = T.Of(value);
    703         CHECK(const_type->Is(type) ==
    704               (of_type->Is(type) || type->Maybe(const_type)));
    705       }
    706     }
    707   }
    708 
    709   void NowOf() {
    710     // Constant(V)->NowIs(NowOf(V))
    711     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    712       Handle<i::Object> value = *vt;
    713       TypeHandle const_type = T.Constant(value);
    714       TypeHandle nowof_type = T.NowOf(value);
    715       CHECK(const_type->NowIs(nowof_type));
    716     }
    717 
    718     // NowOf(V)->Is(Of(V))
    719     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    720       Handle<i::Object> value = *vt;
    721       TypeHandle nowof_type = T.NowOf(value);
    722       TypeHandle of_type = T.Of(value);
    723       CHECK(nowof_type->Is(of_type));
    724     }
    725 
    726     // Constant(V)->NowIs(T) iff NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
    727     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    728       for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    729         Handle<i::Object> value = *vt;
    730         TypeHandle type = *it;
    731         TypeHandle const_type = T.Constant(value);
    732         TypeHandle nowof_type = T.NowOf(value);
    733         CHECK(const_type->NowIs(type) ==
    734               (nowof_type->NowIs(type) || type->Maybe(const_type)));
    735       }
    736     }
    737 
    738     // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V))
    739     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    740       for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    741         Handle<i::Object> value = *vt;
    742         TypeHandle type = *it;
    743         TypeHandle const_type = T.Constant(value);
    744         TypeHandle nowof_type = T.NowOf(value);
    745         CHECK(!const_type->Is(type) ||
    746               (nowof_type->Is(type) || type->Maybe(const_type)));
    747       }
    748     }
    749   }
    750 
    751   void Bounds() {
    752     // Ordering: (T->BitsetGlb())->Is(T->BitsetLub())
    753     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    754       TypeHandle type = *it;
    755       TypeHandle glb =
    756           Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
    757       TypeHandle lub =
    758           Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
    759       CHECK(glb->Is(lub));
    760     }
    761 
    762     // Lower bound: (T->BitsetGlb())->Is(T)
    763     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    764       TypeHandle type = *it;
    765       TypeHandle glb =
    766           Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
    767       CHECK(glb->Is(type));
    768     }
    769 
    770     // Upper bound: T->Is(T->BitsetLub())
    771     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    772       TypeHandle type = *it;
    773       TypeHandle lub =
    774           Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
    775       CHECK(type->Is(lub));
    776     }
    777 
    778     // Inherent bound: (T->BitsetLub())->Is(T->InherentBitsetLub())
    779     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    780       TypeHandle type = *it;
    781       TypeHandle lub =
    782           Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
    783       TypeHandle inherent =
    784           Rep::BitsetType::New(Rep::BitsetType::InherentLub(type), T.region());
    785       CHECK(lub->Is(inherent));
    786     }
    787   }
    788 
    789   void Is() {
    790     // Least Element (Bottom): None->Is(T)
    791     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    792       TypeHandle type = *it;
    793       CHECK(T.None->Is(type));
    794     }
    795 
    796     // Greatest Element (Top): T->Is(Any)
    797     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    798       TypeHandle type = *it;
    799       CHECK(type->Is(T.Any));
    800     }
    801 
    802     // Bottom Uniqueness: T->Is(None) implies T = None
    803     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    804       TypeHandle type = *it;
    805       if (type->Is(T.None)) CheckEqual(type, T.None);
    806     }
    807 
    808     // Top Uniqueness: Any->Is(T) implies T = Any
    809     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    810       TypeHandle type = *it;
    811       if (T.Any->Is(type)) CheckEqual(type, T.Any);
    812     }
    813 
    814     // Reflexivity: T->Is(T)
    815     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    816       TypeHandle type = *it;
    817       CHECK(type->Is(type));
    818     }
    819 
    820     // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
    821     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    822       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    823         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
    824           TypeHandle type1 = *it1;
    825           TypeHandle type2 = *it2;
    826           TypeHandle type3 = *it3;
    827           CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
    828         }
    829       }
    830     }
    831 
    832     // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
    833     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    834       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    835         TypeHandle type1 = *it1;
    836         TypeHandle type2 = *it2;
    837         CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
    838       }
    839     }
    840 
    841     // Constant(V1)->Is(Constant(V2)) iff V1 = V2
    842     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
    843       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
    844         Handle<i::Object> value1 = *vt1;
    845         Handle<i::Object> value2 = *vt2;
    846         TypeHandle const_type1 = T.Constant(value1);
    847         TypeHandle const_type2 = T.Constant(value2);
    848         CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
    849       }
    850     }
    851 
    852     // Class(M1)->Is(Class(M2)) iff M1 = M2
    853     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
    854       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
    855         Handle<i::Map> map1 = *mt1;
    856         Handle<i::Map> map2 = *mt2;
    857         TypeHandle class_type1 = T.Class(map1);
    858         TypeHandle class_type2 = T.Class(map2);
    859         CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
    860       }
    861     }
    862 
    863     // Constant(V)->Is(Class(M)) never
    864     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
    865       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    866         Handle<i::Map> map = *mt;
    867         Handle<i::Object> value = *vt;
    868         TypeHandle constant_type = T.Constant(value);
    869         TypeHandle class_type = T.Class(map);
    870         CHECK(!constant_type->Is(class_type));
    871       }
    872     }
    873 
    874     // Class(M)->Is(Constant(V)) never
    875     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
    876       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
    877         Handle<i::Map> map = *mt;
    878         Handle<i::Object> value = *vt;
    879         TypeHandle constant_type = T.Constant(value);
    880         TypeHandle class_type = T.Class(map);
    881         CHECK(!class_type->Is(constant_type));
    882       }
    883     }
    884 
    885     // Basic types
    886     CheckUnordered(T.Boolean, T.Null);
    887     CheckUnordered(T.Undefined, T.Null);
    888     CheckUnordered(T.Boolean, T.Undefined);
    889 
    890     CheckSub(T.SignedSmall, T.Number);
    891     CheckSub(T.Signed32, T.Number);
    892     CheckSub(T.SignedSmall, T.Signed32);
    893     CheckUnordered(T.SignedSmall, T.MinusZero);
    894     CheckUnordered(T.Signed32, T.Unsigned32);
    895 
    896     CheckSub(T.UniqueName, T.Name);
    897     CheckSub(T.String, T.Name);
    898     CheckSub(T.InternalizedString, T.String);
    899     CheckSub(T.InternalizedString, T.UniqueName);
    900     CheckSub(T.InternalizedString, T.Name);
    901     CheckSub(T.Symbol, T.UniqueName);
    902     CheckSub(T.Symbol, T.Name);
    903     CheckUnordered(T.String, T.UniqueName);
    904     CheckUnordered(T.String, T.Symbol);
    905     CheckUnordered(T.InternalizedString, T.Symbol);
    906 
    907     CheckSub(T.Object, T.Receiver);
    908     CheckSub(T.Array, T.Object);
    909     CheckSub(T.Function, T.Object);
    910     CheckSub(T.Proxy, T.Receiver);
    911     CheckUnordered(T.Object, T.Proxy);
    912     CheckUnordered(T.Array, T.Function);
    913 
    914     // Structural types
    915     CheckSub(T.ObjectClass, T.Object);
    916     CheckSub(T.ArrayClass, T.Object);
    917     CheckSub(T.ArrayClass, T.Array);
    918     CheckSub(T.UninitializedClass, T.Internal);
    919     CheckUnordered(T.ObjectClass, T.ArrayClass);
    920     CheckUnordered(T.UninitializedClass, T.Null);
    921     CheckUnordered(T.UninitializedClass, T.Undefined);
    922 
    923     CheckSub(T.SmiConstant, T.SignedSmall);
    924     CheckSub(T.SmiConstant, T.Signed32);
    925     CheckSub(T.SmiConstant, T.Number);
    926     CheckSub(T.ObjectConstant1, T.Object);
    927     CheckSub(T.ObjectConstant2, T.Object);
    928     CheckSub(T.ArrayConstant, T.Object);
    929     CheckSub(T.ArrayConstant, T.Array);
    930     CheckSub(T.UninitializedConstant, T.Internal);
    931     CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
    932     CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
    933     CheckUnordered(T.UninitializedConstant, T.Null);
    934     CheckUnordered(T.UninitializedConstant, T.Undefined);
    935 
    936     CheckUnordered(T.ObjectConstant1, T.ObjectClass);
    937     CheckUnordered(T.ObjectConstant2, T.ObjectClass);
    938     CheckUnordered(T.ObjectConstant1, T.ArrayClass);
    939     CheckUnordered(T.ObjectConstant2, T.ArrayClass);
    940     CheckUnordered(T.ArrayConstant, T.ObjectClass);
    941 
    942     CheckSub(T.NumberArray, T.Array);
    943     CheckSub(T.NumberArray, T.Object);
    944     CheckUnordered(T.StringArray, T.AnyArray);
    945 
    946     CheckSub(T.MethodFunction, T.Function);
    947     CheckSub(T.NumberFunction1, T.Object);
    948     CheckUnordered(T.SignedFunction1, T.NumberFunction1);
    949     CheckUnordered(T.NumberFunction1, T.NumberFunction2);
    950   }
    951 
    952   void NowIs() {
    953     // Least Element (Bottom): None->NowIs(T)
    954     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    955       TypeHandle type = *it;
    956       CHECK(T.None->NowIs(type));
    957     }
    958 
    959     // Greatest Element (Top): T->NowIs(Any)
    960     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    961       TypeHandle type = *it;
    962       CHECK(type->NowIs(T.Any));
    963     }
    964 
    965     // Bottom Uniqueness: T->NowIs(None) implies T = None
    966     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    967       TypeHandle type = *it;
    968       if (type->NowIs(T.None)) CheckEqual(type, T.None);
    969     }
    970 
    971     // Top Uniqueness: Any->NowIs(T) implies T = Any
    972     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    973       TypeHandle type = *it;
    974       if (T.Any->NowIs(type)) CheckEqual(type, T.Any);
    975     }
    976 
    977     // Reflexivity: T->NowIs(T)
    978     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
    979       TypeHandle type = *it;
    980       CHECK(type->NowIs(type));
    981     }
    982 
    983     // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3)
    984     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    985       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    986         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
    987           TypeHandle type1 = *it1;
    988           TypeHandle type2 = *it2;
    989           TypeHandle type3 = *it3;
    990           CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) ||
    991                 type1->NowIs(type3));
    992         }
    993       }
    994     }
    995 
    996     // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2
    997     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
    998       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
    999         TypeHandle type1 = *it1;
   1000         TypeHandle type2 = *it2;
   1001         CHECK((type1->NowIs(type2) && type2->NowIs(type1)) ==
   1002               Equal(type1, type2));
   1003       }
   1004     }
   1005 
   1006     // T1->Is(T2) implies T1->NowIs(T2)
   1007     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1008       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1009         TypeHandle type1 = *it1;
   1010         TypeHandle type2 = *it2;
   1011         CHECK(!type1->Is(type2) || type1->NowIs(type2));
   1012       }
   1013     }
   1014 
   1015     // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
   1016     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
   1017       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
   1018         Handle<i::Object> value1 = *vt1;
   1019         Handle<i::Object> value2 = *vt2;
   1020         TypeHandle const_type1 = T.Constant(value1);
   1021         TypeHandle const_type2 = T.Constant(value2);
   1022         CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2));
   1023       }
   1024     }
   1025 
   1026     // Class(M1)->NowIs(Class(M2)) iff M1 = M2
   1027     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
   1028       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
   1029         Handle<i::Map> map1 = *mt1;
   1030         Handle<i::Map> map2 = *mt2;
   1031         TypeHandle class_type1 = T.Class(map1);
   1032         TypeHandle class_type2 = T.Class(map2);
   1033         CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2));
   1034       }
   1035     }
   1036 
   1037     // Constant(V)->NowIs(Class(M)) iff V has map M
   1038     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
   1039       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1040         Handle<i::Map> map = *mt;
   1041         Handle<i::Object> value = *vt;
   1042         TypeHandle const_type = T.Constant(value);
   1043         TypeHandle class_type = T.Class(map);
   1044         CHECK((value->IsHeapObject() &&
   1045                i::HeapObject::cast(*value)->map() == *map)
   1046               == const_type->NowIs(class_type));
   1047       }
   1048     }
   1049 
   1050     // Class(M)->NowIs(Constant(V)) never
   1051     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
   1052       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1053         Handle<i::Map> map = *mt;
   1054         Handle<i::Object> value = *vt;
   1055         TypeHandle const_type = T.Constant(value);
   1056         TypeHandle class_type = T.Class(map);
   1057         CHECK(!class_type->NowIs(const_type));
   1058       }
   1059     }
   1060   }
   1061 
   1062   void Contains() {
   1063     // T->Contains(V) iff Constant(V)->Is(T)
   1064     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1065       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1066         TypeHandle type = *it;
   1067         Handle<i::Object> value = *vt;
   1068         TypeHandle const_type = T.Constant(value);
   1069         CHECK(type->Contains(value) == const_type->Is(type));
   1070       }
   1071     }
   1072 
   1073     // Of(V)->Is(T) implies T->Contains(V)
   1074     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1075       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1076         TypeHandle type = *it;
   1077         Handle<i::Object> value = *vt;
   1078         TypeHandle of_type = T.Of(value);
   1079         CHECK(!of_type->Is(type) || type->Contains(value));
   1080       }
   1081     }
   1082   }
   1083 
   1084   void NowContains() {
   1085     // T->NowContains(V) iff Constant(V)->NowIs(T)
   1086     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1087       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1088         TypeHandle type = *it;
   1089         Handle<i::Object> value = *vt;
   1090         TypeHandle const_type = T.Constant(value);
   1091         CHECK(type->NowContains(value) == const_type->NowIs(type));
   1092       }
   1093     }
   1094 
   1095     // T->Contains(V) implies T->NowContains(V)
   1096     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1097       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1098         TypeHandle type = *it;
   1099         Handle<i::Object> value = *vt;
   1100         CHECK(!type->Contains(value) || type->NowContains(value));
   1101       }
   1102     }
   1103 
   1104     // NowOf(V)->Is(T) implies T->NowContains(V)
   1105     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1106       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1107         TypeHandle type = *it;
   1108         Handle<i::Object> value = *vt;
   1109         TypeHandle nowof_type = T.Of(value);
   1110         CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
   1111       }
   1112     }
   1113 
   1114     // NowOf(V)->NowIs(T) implies T->NowContains(V)
   1115     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1116       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1117         TypeHandle type = *it;
   1118         Handle<i::Object> value = *vt;
   1119         TypeHandle nowof_type = T.Of(value);
   1120         CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
   1121       }
   1122     }
   1123   }
   1124 
   1125   void Maybe() {
   1126     // T->Maybe(Any) iff T inhabited
   1127     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1128       TypeHandle type = *it;
   1129       CHECK(type->Maybe(T.Any) == type->IsInhabited());
   1130     }
   1131 
   1132     // T->Maybe(None) never
   1133     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1134       TypeHandle type = *it;
   1135       CHECK(!type->Maybe(T.None));
   1136     }
   1137 
   1138     // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited
   1139     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1140       TypeHandle type = *it;
   1141       CHECK(type->Maybe(type) == type->IsInhabited());
   1142     }
   1143 
   1144     // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
   1145     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1146       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1147         TypeHandle type1 = *it1;
   1148         TypeHandle type2 = *it2;
   1149         CHECK(type1->Maybe(type2) == type2->Maybe(type1));
   1150       }
   1151     }
   1152 
   1153     // T1->Maybe(T2) implies T1, T2 inhabited
   1154     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1155       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1156         TypeHandle type1 = *it1;
   1157         TypeHandle type2 = *it2;
   1158         CHECK(!type1->Maybe(type2) ||
   1159               (type1->IsInhabited() && type2->IsInhabited()));
   1160       }
   1161     }
   1162 
   1163     // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
   1164     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1165       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1166         TypeHandle type1 = *it1;
   1167         TypeHandle type2 = *it2;
   1168         TypeHandle intersect12 = T.Intersect(type1, type2);
   1169         CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
   1170       }
   1171     }
   1172 
   1173     // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2)
   1174     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1175       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1176         TypeHandle type1 = *it1;
   1177         TypeHandle type2 = *it2;
   1178         CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
   1179               type1->Maybe(type2));
   1180       }
   1181     }
   1182 
   1183     // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
   1184     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
   1185       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
   1186         Handle<i::Object> value1 = *vt1;
   1187         Handle<i::Object> value2 = *vt2;
   1188         TypeHandle const_type1 = T.Constant(value1);
   1189         TypeHandle const_type2 = T.Constant(value2);
   1190         CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
   1191       }
   1192     }
   1193 
   1194     // Class(M1)->Maybe(Class(M2)) iff M1 = M2
   1195     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
   1196       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
   1197         Handle<i::Map> map1 = *mt1;
   1198         Handle<i::Map> map2 = *mt2;
   1199         TypeHandle class_type1 = T.Class(map1);
   1200         TypeHandle class_type2 = T.Class(map2);
   1201         CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
   1202       }
   1203     }
   1204 
   1205     // Constant(V)->Maybe(Class(M)) never
   1206     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
   1207       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1208         Handle<i::Map> map = *mt;
   1209         Handle<i::Object> value = *vt;
   1210         TypeHandle const_type = T.Constant(value);
   1211         TypeHandle class_type = T.Class(map);
   1212         CHECK(!const_type->Maybe(class_type));
   1213       }
   1214     }
   1215 
   1216     // Class(M)->Maybe(Constant(V)) never
   1217     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
   1218       for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
   1219         Handle<i::Map> map = *mt;
   1220         Handle<i::Object> value = *vt;
   1221         TypeHandle const_type = T.Constant(value);
   1222         TypeHandle class_type = T.Class(map);
   1223         CHECK(!class_type->Maybe(const_type));
   1224       }
   1225     }
   1226 
   1227     // Basic types
   1228     CheckDisjoint(T.Boolean, T.Null, T.Semantic);
   1229     CheckDisjoint(T.Undefined, T.Null, T.Semantic);
   1230     CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
   1231 
   1232     CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
   1233     CheckOverlap(T.NaN, T.Number, T.Semantic);
   1234     CheckDisjoint(T.Signed32, T.NaN, T.Semantic);
   1235 
   1236     CheckOverlap(T.UniqueName, T.Name, T.Semantic);
   1237     CheckOverlap(T.String, T.Name, T.Semantic);
   1238     CheckOverlap(T.InternalizedString, T.String, T.Semantic);
   1239     CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic);
   1240     CheckOverlap(T.InternalizedString, T.Name, T.Semantic);
   1241     CheckOverlap(T.Symbol, T.UniqueName, T.Semantic);
   1242     CheckOverlap(T.Symbol, T.Name, T.Semantic);
   1243     CheckOverlap(T.String, T.UniqueName, T.Semantic);
   1244     CheckDisjoint(T.String, T.Symbol, T.Semantic);
   1245     CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
   1246 
   1247     CheckOverlap(T.Object, T.Receiver, T.Semantic);
   1248     CheckOverlap(T.Array, T.Object, T.Semantic);
   1249     CheckOverlap(T.Function, T.Object, T.Semantic);
   1250     CheckOverlap(T.Proxy, T.Receiver, T.Semantic);
   1251     CheckDisjoint(T.Object, T.Proxy, T.Semantic);
   1252     CheckDisjoint(T.Array, T.Function, T.Semantic);
   1253 
   1254     // Structural types
   1255     CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
   1256     CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
   1257     CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
   1258     CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic);
   1259     CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic);
   1260 
   1261     CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
   1262     CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
   1263     CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
   1264     CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
   1265     CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
   1266     CheckOverlap(T.ArrayConstant, T.Object, T.Semantic);
   1267     CheckOverlap(T.ArrayConstant, T.Array, T.Semantic);
   1268     CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic);
   1269     CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic);
   1270     CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic);
   1271 
   1272     CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic);
   1273     CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic);
   1274     CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
   1275     CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
   1276     CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic);
   1277 
   1278     CheckOverlap(T.NumberArray, T.Array, T.Semantic);
   1279     CheckDisjoint(T.NumberArray, T.AnyArray, T.Semantic);
   1280     CheckDisjoint(T.NumberArray, T.StringArray, T.Semantic);
   1281 
   1282     CheckOverlap(T.MethodFunction, T.Function, T.Semantic);
   1283     CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic);
   1284     CheckDisjoint(T.SignedFunction1, T.NumberFunction2, T.Semantic);
   1285     CheckDisjoint(T.NumberFunction1, T.NumberFunction2, T.Semantic);
   1286     CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic);
   1287   }
   1288 
   1289   void Union1() {
   1290     // Identity: Union(T, None) = T
   1291     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1292       TypeHandle type = *it;
   1293       TypeHandle union_type = T.Union(type, T.None);
   1294       CheckEqual(union_type, type);
   1295     }
   1296 
   1297     // Domination: Union(T, Any) = Any
   1298     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1299       TypeHandle type = *it;
   1300       TypeHandle union_type = T.Union(type, T.Any);
   1301       CheckEqual(union_type, T.Any);
   1302     }
   1303 
   1304     // Idempotence: Union(T, T) = T
   1305     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1306       TypeHandle type = *it;
   1307       TypeHandle union_type = T.Union(type, type);
   1308       CheckEqual(union_type, type);
   1309     }
   1310 
   1311     // Commutativity: Union(T1, T2) = Union(T2, T1)
   1312     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1313       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1314         TypeHandle type1 = *it1;
   1315         TypeHandle type2 = *it2;
   1316         TypeHandle union12 = T.Union(type1, type2);
   1317         TypeHandle union21 = T.Union(type2, type1);
   1318         CheckEqual(union12, union21);
   1319       }
   1320     }
   1321 
   1322     // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
   1323     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1324       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1325         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1326           TypeHandle type1 = *it1;
   1327           TypeHandle type2 = *it2;
   1328           TypeHandle type3 = *it3;
   1329           TypeHandle union12 = T.Union(type1, type2);
   1330           TypeHandle union23 = T.Union(type2, type3);
   1331           TypeHandle union1_23 = T.Union(type1, union23);
   1332           TypeHandle union12_3 = T.Union(union12, type3);
   1333           CheckEqual(union1_23, union12_3);
   1334         }
   1335       }
   1336     }
   1337 
   1338     // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
   1339     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1340       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1341         TypeHandle type1 = *it1;
   1342         TypeHandle type2 = *it2;
   1343         TypeHandle union12 = T.Union(type1, type2);
   1344         CHECK(type1->Is(union12));
   1345         CHECK(type2->Is(union12));
   1346       }
   1347     }
   1348 
   1349     // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
   1350     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1351       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1352         TypeHandle type1 = *it1;
   1353         TypeHandle type2 = *it2;
   1354         TypeHandle union12 = T.Union(type1, type2);
   1355         if (type1->Is(type2)) CheckEqual(union12, type2);
   1356       }
   1357     }
   1358   }
   1359 
   1360   void Union2() {
   1361     // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
   1362     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1363       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1364         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1365           TypeHandle type1 = *it1;
   1366           TypeHandle type2 = *it2;
   1367           TypeHandle type3 = *it3;
   1368           TypeHandle union13 = T.Union(type1, type3);
   1369           TypeHandle union23 = T.Union(type2, type3);
   1370           CHECK(!type1->Is(type2) || union13->Is(union23));
   1371         }
   1372       }
   1373     }
   1374 
   1375     // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
   1376     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1377       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1378         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1379           TypeHandle type1 = *it1;
   1380           TypeHandle type2 = *it2;
   1381           TypeHandle type3 = *it3;
   1382           TypeHandle union12 = T.Union(type1, type2);
   1383           CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
   1384         }
   1385       }
   1386     }
   1387 
   1388     // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
   1389     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1390       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1391         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1392           TypeHandle type1 = *it1;
   1393           TypeHandle type2 = *it2;
   1394           TypeHandle type3 = *it3;
   1395           TypeHandle union23 = T.Union(type2, type3);
   1396           CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
   1397         }
   1398       }
   1399     }
   1400 
   1401     // Class-class
   1402     CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
   1403     CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
   1404     CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic);
   1405     CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic);
   1406 
   1407     // Constant-constant
   1408     CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
   1409     CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
   1410     CheckUnordered(
   1411         T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
   1412     CheckOverlap(
   1413         T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic);
   1414     CheckDisjoint(
   1415         T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic);
   1416     CheckDisjoint(
   1417         T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic);
   1418 
   1419     // Bitset-array
   1420     CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
   1421     CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
   1422 
   1423     CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
   1424     CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
   1425     CheckOverlap(T.Union(T.NumberArray, T.String), T.Object, T.Semantic);
   1426     CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number, T.Semantic);
   1427 
   1428     // Bitset-function
   1429     CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
   1430     CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
   1431 
   1432     CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
   1433     CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
   1434     CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic);
   1435     CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic);
   1436 
   1437     // Bitset-class
   1438     CheckSub(
   1439         T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
   1440     CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
   1441     CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
   1442     CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic);
   1443     CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic);
   1444 
   1445     // Bitset-constant
   1446     CheckSub(
   1447         T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
   1448     CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
   1449     CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
   1450     CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic);
   1451     CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic);
   1452 
   1453     // Class-constant
   1454     CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
   1455     CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
   1456     CheckSub(
   1457         T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
   1458     CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
   1459     CheckDisjoint(
   1460         T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2,
   1461         T.Semantic);
   1462     CheckDisjoint(
   1463         T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic);
   1464 
   1465     // Bitset-union
   1466     CheckSub(
   1467         T.NaN,
   1468         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
   1469     CheckSub(
   1470         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
   1471         T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
   1472 
   1473     // Class-union
   1474     CheckSub(
   1475         T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
   1476         T.Object);
   1477     CheckEqual(
   1478         T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
   1479         T.Union(T.ArrayClass, T.ObjectConstant2));
   1480 
   1481     // Constant-union
   1482     CheckEqual(
   1483         T.Union(
   1484             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
   1485         T.Union(T.ObjectConstant2, T.ObjectConstant1));
   1486     CheckEqual(
   1487         T.Union(
   1488             T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
   1489         T.Union(
   1490             T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
   1491 
   1492     // Array-union
   1493     CheckEqual(
   1494         T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
   1495         T.Union(T.AnyArray, T.NumberArray));
   1496     CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array);
   1497 
   1498     // Function-union
   1499     CheckEqual(
   1500         T.Union(T.NumberFunction1, T.NumberFunction2),
   1501         T.Union(T.NumberFunction2, T.NumberFunction1));
   1502     CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
   1503 
   1504     // Union-union
   1505     CheckEqual(
   1506         T.Union(
   1507             T.Union(T.ObjectConstant2, T.ObjectConstant1),
   1508             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
   1509         T.Union(T.ObjectConstant2, T.ObjectConstant1));
   1510     CheckEqual(
   1511         T.Union(
   1512             T.Union(T.Number, T.ArrayClass),
   1513             T.Union(T.SignedSmall, T.Array)),
   1514         T.Union(T.Number, T.Array));
   1515   }
   1516 
   1517   void Intersect1() {
   1518     // Identity: Intersect(T, Any) = T
   1519     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1520       TypeHandle type = *it;
   1521       TypeHandle intersect_type = T.Intersect(type, T.Any);
   1522       CheckEqual(intersect_type, type);
   1523     }
   1524 
   1525     // Domination: Intersect(T, None) = None
   1526     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1527       TypeHandle type = *it;
   1528       TypeHandle intersect_type = T.Intersect(type, T.None);
   1529       CheckEqual(intersect_type, T.None);
   1530     }
   1531 
   1532     // Idempotence: Intersect(T, T) = T
   1533     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1534       TypeHandle type = *it;
   1535       TypeHandle intersect_type = T.Intersect(type, type);
   1536       CheckEqual(intersect_type, type);
   1537     }
   1538 
   1539     // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
   1540     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1541       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1542         TypeHandle type1 = *it1;
   1543         TypeHandle type2 = *it2;
   1544         TypeHandle intersect12 = T.Intersect(type1, type2);
   1545         TypeHandle intersect21 = T.Intersect(type2, type1);
   1546         CheckEqual(intersect12, intersect21);
   1547       }
   1548     }
   1549 
   1550     // Associativity:
   1551     // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
   1552     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1553       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1554         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1555           TypeHandle type1 = *it1;
   1556           TypeHandle type2 = *it2;
   1557           TypeHandle type3 = *it3;
   1558           TypeHandle intersect12 = T.Intersect(type1, type2);
   1559           TypeHandle intersect23 = T.Intersect(type2, type3);
   1560           TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
   1561           TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
   1562           CheckEqual(intersect1_23, intersect12_3);
   1563         }
   1564       }
   1565     }
   1566 
   1567     // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
   1568     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1569       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1570         TypeHandle type1 = *it1;
   1571         TypeHandle type2 = *it2;
   1572         TypeHandle intersect12 = T.Intersect(type1, type2);
   1573         CHECK(intersect12->Is(type1));
   1574         CHECK(intersect12->Is(type2));
   1575       }
   1576     }
   1577 
   1578     // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
   1579     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1580       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1581         TypeHandle type1 = *it1;
   1582         TypeHandle type2 = *it2;
   1583         TypeHandle intersect12 = T.Intersect(type1, type2);
   1584         if (type1->Is(type2)) CheckEqual(intersect12, type1);
   1585       }
   1586     }
   1587   }
   1588 
   1589   void Intersect2() {
   1590     // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
   1591     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1592       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1593         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1594           TypeHandle type1 = *it1;
   1595           TypeHandle type2 = *it2;
   1596           TypeHandle type3 = *it3;
   1597           TypeHandle intersect13 = T.Intersect(type1, type3);
   1598           TypeHandle intersect23 = T.Intersect(type2, type3);
   1599           CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
   1600         }
   1601       }
   1602     }
   1603 
   1604     // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
   1605     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1606       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1607         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1608           TypeHandle type1 = *it1;
   1609           TypeHandle type2 = *it2;
   1610           TypeHandle type3 = *it3;
   1611           TypeHandle intersect12 = T.Intersect(type1, type2);
   1612           CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
   1613                 intersect12->Is(type3));
   1614         }
   1615       }
   1616     }
   1617 
   1618     // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
   1619     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1620       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1621         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1622           TypeHandle type1 = *it1;
   1623           TypeHandle type2 = *it2;
   1624           TypeHandle type3 = *it3;
   1625           TypeHandle intersect23 = T.Intersect(type2, type3);
   1626           CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
   1627                 type1->Is(intersect23));
   1628         }
   1629       }
   1630     }
   1631 
   1632     // Bitset-class
   1633     CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
   1634     CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
   1635     CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
   1636 
   1637     // Bitset-array
   1638     CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
   1639     CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation);
   1640 
   1641     // Bitset-function
   1642     CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
   1643     CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation);
   1644 
   1645     // Bitset-union
   1646     CheckEqual(
   1647         T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
   1648         T.Union(T.ObjectConstant1, T.ObjectClass));
   1649     CHECK(
   1650         !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
   1651             ->IsInhabited());
   1652 
   1653     // Class-constant
   1654     CHECK(!T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited());
   1655     CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
   1656 
   1657     // Array-union
   1658     CheckEqual(
   1659         T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
   1660         T.NumberArray);
   1661     CheckEqual(
   1662         T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
   1663         T.AnyArray);
   1664     CHECK(
   1665         !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
   1666             ->IsInhabited());
   1667 
   1668     // Function-union
   1669     CheckEqual(
   1670         T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
   1671         T.MethodFunction);
   1672     CheckEqual(
   1673         T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
   1674         T.NumberFunction1);
   1675     CHECK(
   1676         !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
   1677             ->IsInhabited());
   1678 
   1679     // Class-union
   1680     CheckEqual(
   1681         T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
   1682         T.ArrayClass);
   1683     CheckEqual(
   1684         T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
   1685         T.ArrayClass);
   1686     CHECK(
   1687         !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
   1688             ->IsInhabited());
   1689 
   1690     // Constant-union
   1691     CheckEqual(
   1692         T.Intersect(
   1693             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
   1694         T.ObjectConstant1);
   1695     CheckEqual(
   1696         T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
   1697         T.SmiConstant);
   1698     CHECK(
   1699         !T.Intersect(
   1700             T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
   1701                 ->IsInhabited());
   1702 
   1703     // Union-union
   1704     CheckEqual(
   1705         T.Intersect(
   1706             T.Union(T.Number, T.ArrayClass),
   1707             T.Union(T.SignedSmall, T.Array)),
   1708         T.Union(T.SignedSmall, T.ArrayClass));
   1709     CheckEqual(
   1710         T.Intersect(
   1711             T.Union(T.Number, T.ObjectClass),
   1712             T.Union(T.Signed32, T.Array)),
   1713         T.Signed32);
   1714     CheckEqual(
   1715         T.Intersect(
   1716             T.Union(T.ObjectConstant2, T.ObjectConstant1),
   1717             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
   1718         T.Union(T.ObjectConstant2, T.ObjectConstant1));
   1719     CheckEqual(
   1720         T.Intersect(
   1721             T.Union(
   1722                 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
   1723             T.Union(
   1724                 T.ObjectConstant1,
   1725                 T.Union(T.ArrayConstant, T.ObjectConstant2))),
   1726         T.Union(T.ObjectConstant2, T.ObjectConstant1));
   1727   }
   1728 
   1729   void Distributivity1() {
   1730     // Distributivity:
   1731     // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
   1732     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1733       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1734         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1735           TypeHandle type1 = *it1;
   1736           TypeHandle type2 = *it2;
   1737           TypeHandle type3 = *it3;
   1738           TypeHandle union12 = T.Union(type1, type2);
   1739           TypeHandle union13 = T.Union(type1, type3);
   1740           TypeHandle intersect23 = T.Intersect(type2, type3);
   1741           TypeHandle union1_23 = T.Union(type1, intersect23);
   1742           TypeHandle intersect12_13 = T.Intersect(union12, union13);
   1743           CHECK(Equal(union1_23, intersect12_13));
   1744         }
   1745       }
   1746     }
   1747   }
   1748 
   1749   void Distributivity2() {
   1750     // Distributivity:
   1751     // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
   1752     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1753       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1754         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
   1755           TypeHandle type1 = *it1;
   1756           TypeHandle type2 = *it2;
   1757           TypeHandle type3 = *it3;
   1758           TypeHandle intersect12 = T.Intersect(type1, type2);
   1759           TypeHandle intersect13 = T.Intersect(type1, type3);
   1760           TypeHandle union23 = T.Union(type2, type3);
   1761           TypeHandle intersect1_23 = T.Intersect(type1, union23);
   1762           TypeHandle union12_13 = T.Union(intersect12, intersect13);
   1763           CHECK(Equal(intersect1_23, union12_13));
   1764         }
   1765       }
   1766     }
   1767   }
   1768 
   1769   template<class Type2, class TypeHandle2, class Region2, class Rep2>
   1770   void Convert() {
   1771     Types<Type2, TypeHandle2, Region2> T2(
   1772         Rep2::ToRegion(&zone, isolate), isolate);
   1773     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
   1774       TypeHandle type1 = *it;
   1775       TypeHandle2 type2 = T2.template Convert<Type>(type1);
   1776       TypeHandle type3 = T.template Convert<Type2>(type2);
   1777       CheckEqual(type1, type3);
   1778     }
   1779   }
   1780 
   1781   void HTypeFromType() {
   1782     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
   1783       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
   1784         TypeHandle type1 = *it1;
   1785         TypeHandle type2 = *it2;
   1786         HType htype1 = HType::FromType<Type>(type1);
   1787         HType htype2 = HType::FromType<Type>(type2);
   1788         CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
   1789       }
   1790     }
   1791   }
   1792 };
   1793 
   1794 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
   1795 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
   1796 
   1797 
   1798 TEST(BitsetType) {
   1799   CcTest::InitializeVM();
   1800   ZoneTests().Bitset();
   1801   HeapTests().Bitset();
   1802 }
   1803 
   1804 
   1805 TEST(ClassType) {
   1806   CcTest::InitializeVM();
   1807   ZoneTests().Class();
   1808   HeapTests().Class();
   1809 }
   1810 
   1811 
   1812 TEST(ConstantType) {
   1813   CcTest::InitializeVM();
   1814   ZoneTests().Constant();
   1815   HeapTests().Constant();
   1816 }
   1817 
   1818 
   1819 TEST(ArrayType) {
   1820   CcTest::InitializeVM();
   1821   ZoneTests().Array();
   1822   HeapTests().Array();
   1823 }
   1824 
   1825 
   1826 TEST(FunctionType) {
   1827   CcTest::InitializeVM();
   1828   ZoneTests().Function();
   1829   HeapTests().Function();
   1830 }
   1831 
   1832 
   1833 TEST(Of) {
   1834   CcTest::InitializeVM();
   1835   ZoneTests().Of();
   1836   HeapTests().Of();
   1837 }
   1838 
   1839 
   1840 TEST(NowOf) {
   1841   CcTest::InitializeVM();
   1842   ZoneTests().NowOf();
   1843   HeapTests().NowOf();
   1844 }
   1845 
   1846 
   1847 TEST(Bounds) {
   1848   CcTest::InitializeVM();
   1849   ZoneTests().Bounds();
   1850   HeapTests().Bounds();
   1851 }
   1852 
   1853 
   1854 TEST(Is) {
   1855   CcTest::InitializeVM();
   1856   ZoneTests().Is();
   1857   HeapTests().Is();
   1858 }
   1859 
   1860 
   1861 TEST(NowIs) {
   1862   CcTest::InitializeVM();
   1863   ZoneTests().NowIs();
   1864   HeapTests().NowIs();
   1865 }
   1866 
   1867 
   1868 TEST(Contains) {
   1869   CcTest::InitializeVM();
   1870   ZoneTests().Contains();
   1871   HeapTests().Contains();
   1872 }
   1873 
   1874 
   1875 TEST(NowContains) {
   1876   CcTest::InitializeVM();
   1877   ZoneTests().NowContains();
   1878   HeapTests().NowContains();
   1879 }
   1880 
   1881 
   1882 TEST(Maybe) {
   1883   CcTest::InitializeVM();
   1884   ZoneTests().Maybe();
   1885   HeapTests().Maybe();
   1886 }
   1887 
   1888 
   1889 TEST(Union1) {
   1890   CcTest::InitializeVM();
   1891   ZoneTests().Union1();
   1892   HeapTests().Union1();
   1893 }
   1894 
   1895 
   1896 TEST(Union2) {
   1897   CcTest::InitializeVM();
   1898   ZoneTests().Union2();
   1899   HeapTests().Union2();
   1900 }
   1901 
   1902 
   1903 TEST(Intersect1) {
   1904   CcTest::InitializeVM();
   1905   ZoneTests().Intersect1();
   1906   HeapTests().Intersect1();
   1907 }
   1908 
   1909 
   1910 TEST(Intersect2) {
   1911   CcTest::InitializeVM();
   1912   ZoneTests().Intersect2();
   1913   HeapTests().Intersect2();
   1914 }
   1915 
   1916 
   1917 TEST(Distributivity1) {
   1918   CcTest::InitializeVM();
   1919   ZoneTests().Distributivity1();
   1920   HeapTests().Distributivity1();
   1921 }
   1922 
   1923 
   1924 TEST(Distributivity2) {
   1925   CcTest::InitializeVM();
   1926   ZoneTests().Distributivity2();
   1927   HeapTests().Distributivity2();
   1928 }
   1929 
   1930 
   1931 TEST(Convert) {
   1932   CcTest::InitializeVM();
   1933   ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
   1934   HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
   1935 }
   1936 
   1937 
   1938 TEST(HTypeFromType) {
   1939   CcTest::InitializeVM();
   1940   ZoneTests().HTypeFromType();
   1941   HeapTests().HTypeFromType();
   1942 }
   1943