Retry landing "Implement zone-allocated types"
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 Jan 2014 14:14:12 +0000 (14:14 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 Jan 2014 14:14:12 +0000 (14:14 +0000)
Works around apparent scoping bug in VS, the only change to before being a method rename in the test suite:

--- a/test/cctest/test-types.cc
+++ b/test/cctest/test-types.cc
@@ -153,7 +153,7 @@ struct ZoneRep {
     return reinterpret_cast<ZoneList<ZoneType*>*>(AsTagged(t));
   }

-  static Zone* Region(Zone* zone, Isolate* isolate) { return zone; }
+  static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
 };

@@ -168,7 +168,7 @@ struct HeapRep {
   static Object* AsConstant(Handle<Type> t) { return Box::cast(*t)->value(); }
   static FixedArray* AsUnion(Handle<Type> t) { return FixedArray::cast(*t); }

-  static Isolate* Region(Zone* zone, Isolate* isolate) { return isolate; }
+  static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
 };

@@ -183,7 +183,7 @@ struct Tests : Rep {
       isolate(CcTest::i_isolate()),
       scope(isolate),
       zone(isolate),
-      T(Rep::Region(&zone, isolate), isolate) {
+      T(Rep::ToRegion(&zone, isolate), isolate) {
   }

   static void CheckEqual(TypeHandle type1, TypeHandle type2) {

R=titzer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/143693003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18711 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/list-inl.h
src/objects.cc
src/objects.h
src/types.cc
src/types.h
test/cctest/test-types.cc

index 143c830ee92ad3d11fe62372dc2a6947557ef8c3..a80aa674341afd94b44e62f438484843f5a1af44 100644 (file)
@@ -166,6 +166,7 @@ void List<T, P>::Clear() {
 
 template<typename T, class P>
 void List<T, P>::Rewind(int pos) {
+  ASSERT(0 <= pos && pos <= length_);
   length_ = pos;
 }
 
index 9c1a9cd69f5ee0ceba6416fdba0a2309660f541b..636113d439e3f21288435e1dae6df74b27bab3b1 100644 (file)
@@ -7905,6 +7905,14 @@ MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
 }
 
 
+void FixedArray::Shrink(int new_length) {
+  ASSERT(0 <= new_length && new_length <= length());
+  if (new_length < length()) {
+    RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), this, length() - new_length);
+  }
+}
+
+
 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
   ElementsAccessor* accessor = array->GetElementsAccessor();
   MaybeObject* maybe_result =
index 85cae02da4b0231dba2f9074abc800319c44058a..2081e0a3cea811cfde52f6895e75db7e5df0ee0b 100644 (file)
@@ -2980,6 +2980,9 @@ class FixedArray: public FixedArrayBase {
   // Gives access to raw memory which stores the array's data.
   inline Object** data_start();
 
+  // Shrink length and insert filler objects.
+  void Shrink(int length);
+
   // Copy operations.
   MUST_USE_RESULT inline MaybeObject* Copy();
   MUST_USE_RESULT MaybeObject* CopySize(int new_length,
index 2aa60817e5f4f30e221085507ef3ae497a846e8e..9354965a7b7a57475a7568b08b2adaa9eee24411 100644 (file)
@@ -38,7 +38,7 @@ int TypeImpl<Config>::NumClasses() {
   } else if (this->IsUnion()) {
     UnionedHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       if (Config::union_get(unioned, i)->IsClass()) ++result;
     }
     return result;
@@ -55,7 +55,7 @@ int TypeImpl<Config>::NumConstants() {
   } else if (this->IsUnion()) {
     UnionedHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       if (Config::union_get(unioned, i)->IsConstant()) ++result;
     }
     return result;
@@ -118,7 +118,7 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
   ++index_;
   if (type_->IsUnion()) {
     UnionedHandle unioned = type_->AsUnion();
-    for (; index_ < unioned->length(); ++index_) {
+    for (; index_ < Config::union_length(unioned); ++index_) {
       if (matches(Config::union_get(unioned, index_))) return;
     }
   } else if (index_ == 0 && matches(type_)) {
@@ -136,7 +136,7 @@ int TypeImpl<Config>::LubBitset() {
   } else if (this->IsUnion()) {
     UnionedHandle unioned = this->AsUnion();
     int bitset = kNone;
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       bitset |= Config::union_get(unioned, i)->LubBitset();
     }
     return bitset;
@@ -299,7 +299,7 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
   // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
   if (this->IsUnion()) {
     UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle this_i = Config::union_get(unioned, i);
       if (!this_i->Is(that)) return false;
     }
@@ -311,7 +311,7 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
   ASSERT(!this->IsUnion());
   if (that->IsUnion()) {
     UnionedHandle unioned = that->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle that_i = Config::union_get(unioned, i);
       if (this->Is(that_i)) return true;
       if (this->IsBitset()) break;  // Fast fail, only first field is a bitset.
@@ -346,7 +346,7 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
   // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
   if (this->IsUnion()) {
     UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle this_i = Config::union_get(unioned, i);
       if (this_i->Maybe(that)) return true;
     }
@@ -356,7 +356,7 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
   // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
   if (that->IsUnion()) {
     UnionedHandle unioned = that->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle that_i = Config::union_get(unioned, i);
       if (this->Maybe(that_i)) return true;
     }
@@ -389,18 +389,21 @@ bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
 // Get non-bitsets from this which are not subsumed by union, store at unioned,
 // starting at index. Returns updated index.
 template<class Config>
-int TypeImpl<Config>::ExtendUnion(UnionedHandle result, int current_size) {
+int TypeImpl<Config>::ExtendUnion(
+    UnionedHandle result, TypeHandle type, int current_size) {
   int old_size = current_size;
-  if (this->IsClass() || this->IsConstant()) {
-    if (!this->InUnion(result, old_size)) result->set(current_size++, this);
-  } else if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+  if (type->IsClass() || type->IsConstant()) {
+    if (!type->InUnion(result, old_size)) {
+      Config::union_set(result, current_size++, type);
+    }
+  } else if (type->IsUnion()) {
+    UnionedHandle unioned = type->AsUnion();
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle type = Config::union_get(unioned, i);
       ASSERT(i == 0 ||
              !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
       if (!type->IsBitset() && !type->InUnion(result, old_size)) {
-        result->set(current_size++, *type);
+        Config::union_set(result, current_size++, type);
       }
     }
   }
@@ -433,51 +436,50 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
   // Slow case: may need to produce a Unioned object.
   int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
   if (!type1->IsBitset()) {
-    size += (type1->IsUnion() ? type1->AsUnion()->length() : 1);
+    size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
-    size += (type2->IsUnion() ? type2->AsUnion()->length() : 1);
+    size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
   }
   ASSERT(size >= 2);
   UnionedHandle unioned = Config::union_create(size, region);
   size = 0;
 
   int bitset = type1->GlbBitset() | type2->GlbBitset();
-  if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
-  size = type1->ExtendUnion(unioned, size);
-  size = type2->ExtendUnion(unioned, size);
+  if (bitset != kNone) {
+    Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+  }
+  size = ExtendUnion(unioned, type1, size);
+  size = ExtendUnion(unioned, type2, size);
 
   if (size == 1) {
     return Config::union_get(unioned, 0);
-  } else if (size == unioned->length()) {
+  } else {
+    Config::union_shrink(unioned, size);
     return Config::from_union(unioned);
   }
-
-  // There was an overlap. Copy to smaller union.
-  UnionedHandle result = Config::union_create(size, region);
-  for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
-  return Config::from_union(result);
 }
 
 
-// Get non-bitsets from this which are also in that, store at unioned,
+// Get non-bitsets from type which are also in other, store at unioned,
 // starting at index. Returns updated index.
 template<class Config>
 int TypeImpl<Config>::ExtendIntersection(
-    UnionedHandle result, TypeHandle that, int current_size) {
+    UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
   int old_size = current_size;
-  if (this->IsClass() || this->IsConstant()) {
-    if (this->Is(that) && !this->InUnion(result, old_size))
-      result->set(current_size++, this);
-  } else if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+  if (type->IsClass() || type->IsConstant()) {
+    if (type->Is(other) && !type->InUnion(result, old_size)) {
+      Config::union_set(result, current_size++, type);
+    }
+  } else if (type->IsUnion()) {
+    UnionedHandle unioned = type->AsUnion();
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle type = Config::union_get(unioned, i);
       ASSERT(i == 0 ||
              !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
-      if (!type->IsBitset() && type->Is(that) &&
+      if (!type->IsBitset() && type->Is(other) &&
           !type->InUnion(result, old_size)) {
-        result->set(current_size++, *type);
+        Config::union_set(result, current_size++, type);
       }
     }
   }
@@ -510,10 +512,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
   // Slow case: may need to produce a Unioned object.
   int size = 0;
   if (!type1->IsBitset()) {
-    size = (type1->IsUnion() ? type1->AsUnion()->length() : 2);
+    size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
   }
   if (!type2->IsBitset()) {
-    int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2);
+    int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
     size = (size == 0 ? size2 : Min(size, size2));
   }
   ASSERT(size >= 2);
@@ -521,22 +523,20 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
   size = 0;
 
   int bitset = type1->GlbBitset() & type2->GlbBitset();
-  if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
-  size = type1->ExtendIntersection(unioned, type2, size);
-  size = type2->ExtendIntersection(unioned, type1, size);
+  if (bitset != kNone) {
+    Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+  }
+  size = ExtendIntersection(unioned, type1, type2, size);
+  size = ExtendIntersection(unioned, type2, type1, size);
 
   if (size == 0) {
     return None(region);
   } else if (size == 1) {
     return Config::union_get(unioned, 0);
-  } else if (size == unioned->length()) {
+  } else {
+    Config::union_shrink(unioned, size);
     return Config::from_union(unioned);
   }
-
-  // There were dropped cases. Copy to smaller union.
-  UnionedHandle result = Config::union_create(size, region);
-  for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
-  return Config::from_union(result);
 }
 
 
@@ -601,7 +601,7 @@ void TypeImpl<Config>::TypePrint(FILE* out) {
   } else if (this->IsUnion()) {
     PrintF(out, "(");
     UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < unioned->length(); ++i) {
+    for (int i = 0; i < Config::union_length(unioned); ++i) {
       TypeHandle type_i = Config::union_get(unioned, i);
       if (i > 0) PrintF(out, " | ");
       type_i->TypePrint(out);
@@ -612,6 +612,10 @@ void TypeImpl<Config>::TypePrint(FILE* out) {
 #endif
 
 
+template class TypeImpl<ZoneTypeConfig>;
+template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
+template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
+
 template class TypeImpl<HeapTypeConfig>;
 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
index 4d8557e68b35696566e3efe19b293dbb9305767c..7dcf6f6bdc0599b8590d7503bbdc5675e6a92bfc 100644 (file)
@@ -137,22 +137,24 @@ namespace internal {
 //   typedef Region;
 //   template<class> struct Handle { typedef type; }  // No template typedefs...
 //   static Handle<Type>::type handle(Type* type);    // !is_bitset(type)
-//   static bool is_bitset(Type* type);
-//   static bool is_class(Type* type);
-//   static bool is_constant(Type* type);
-//   static bool is_union(Type* type);
-//   static int as_bitset(Type* type);
-//   static i::Handle<i::Map> as_class(Type* type);
-//   static i::Handle<i::Object> as_constant(Type* type);
-//   static Handle<Unioned>::type as_union(Type* type);
+//   static bool is_bitset(Type*);
+//   static bool is_class(Type*);
+//   static bool is_constant(Type*);
+//   static bool is_union(Type*);
+//   static int as_bitset(Type*);
+//   static i::Handle<i::Map> as_class(Type*);
+//   static i::Handle<i::Object> as_constant(Type*);
+//   static Handle<Unioned>::type as_union(Type*);
 //   static Type* from_bitset(int bitset);
-//   static Handle<Type>::type from_bitset(int bitset, Region* region);
-//   static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region)
-//   static Handle<Type>::type from_constant(
-//                               i::Handle<i::Object> value, Region* region);
-//   static Handle<Type>::type from_union(Handle<Unioned>::T unioned);
-//   static Handle<Unioned>::type union_create(int size, Region* region);
-//   static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i);
+//   static Handle<Type>::type from_bitset(int bitset, Region*);
+//   static Handle<Type>::type from_class(i::Handle<i::Map>, Region*)
+//   static Handle<Type>::type from_constant(i::Handle<i::Object>, Region*);
+//   static Handle<Type>::type from_union(Handle<Unioned>::type);
+//   static Handle<Unioned>::type union_create(int size, Region*);
+//   static void union_shrink(Handle<Unioned>::type, int size);
+//   static Handle<Type>::type union_get(Handle<Unioned>::type, int);
+//   static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
+//   static int union_length(Handle<Unioned>::type);
 // }
 template<class Config>
 class TypeImpl : public Config::Base {
@@ -183,14 +185,17 @@ class TypeImpl : public Config::Base {
   }
 
   bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
+  template<class TypeHandle>
   bool Is(TypeHandle that) { return this->Is(*that); }
   bool Maybe(TypeImpl* that);
+  template<class TypeHandle>
   bool Maybe(TypeHandle that) { return this->Maybe(*that); }
 
   // State-dependent versions of Of and Is that consider subtyping between
   // a constant and its map class.
   static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
   bool IsCurrently(TypeImpl* that);
+  template<class TypeHandle>
   bool IsCurrently(TypeHandle that)  { return this->IsCurrently(*that); }
 
   bool IsClass() { return Config::is_class(this); }
@@ -232,7 +237,7 @@ class TypeImpl : public Config::Base {
     return Iterator<i::Object>(Config::handle(this));
   }
 
-  static TypeImpl* cast(i::Object* object) {
+  static TypeImpl* cast(typename Config::Base* object) {
     TypeImpl* t = static_cast<TypeImpl*>(object);
     ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
     return t;
@@ -276,9 +281,10 @@ class TypeImpl : public Config::Base {
   static int LubBitset(i::Map* map);
 
   bool InUnion(UnionedHandle unioned, int current_size);
-  int ExtendUnion(UnionedHandle unioned, int current_size);
-  int ExtendIntersection(
-      UnionedHandle unioned, TypeHandle type, int current_size);
+  static int ExtendUnion(
+      UnionedHandle unioned, TypeHandle t, int current_size);
+  static int ExtendIntersection(
+      UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
 
 #ifdef OBJECT_PRINT
   static const char* bitset_name(int bitset);
@@ -286,6 +292,141 @@ class TypeImpl : public Config::Base {
 };
 
 
+// Zone-allocated types are either (odd) integers to represent bitsets, or
+// (even) pointers to zone lists for everything else. The first slot of every
+// list is an explicit tag value to distinguish representation.
+struct ZoneTypeConfig {
+ private:
+  typedef i::ZoneList<void*> Tagged;
+
+  enum Tag {
+    kClassTag,
+    kConstantTag,
+    kUnionTag
+  };
+
+  static Tagged* tagged_create(Tag tag, int size, Zone* zone) {
+    Tagged* tagged = new(zone) Tagged(size + 1, zone);
+    tagged->Add(reinterpret_cast<void*>(tag), zone);
+    tagged->AddBlock(NULL, size, zone);
+    return tagged;
+  }
+  static void tagged_shrink(Tagged* tagged, int size) {
+    tagged->Rewind(size + 1);
+  }
+  static Tag tagged_tag(Tagged* tagged) {
+    return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
+  }
+  template<class T>
+  static T tagged_get(Tagged* tagged, int i) {
+    return reinterpret_cast<T>(tagged->at(i + 1));
+  }
+  template<class T>
+  static void tagged_set(Tagged* tagged, int i, T value) {
+    tagged->at(i + 1) = reinterpret_cast<T>(value);
+  }
+  static int tagged_length(Tagged* tagged) {
+    return tagged->length() - 1;
+  }
+
+ public:
+  typedef TypeImpl<ZoneTypeConfig> Type;
+  class Base {};
+  typedef i::ZoneList<Type*> Unioned;
+  typedef i::Zone Region;
+  template<class T> struct Handle { typedef T* type; };
+
+  static Type* handle(Type* type) { return type; }
+
+  static bool is(Type* type, Tag tag) {
+    return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
+  }
+
+  static bool is_bitset(Type* type) {
+    return reinterpret_cast<intptr_t>(type) & 1;
+  }
+  static bool is_tagged(Type* type) { return !is_bitset(type); }
+  static bool is_class(Type* type) { return is(type, kClassTag); }
+  static bool is_constant(Type* type) { return is(type, kConstantTag); }
+  static bool is_union(Type* type) { return is(type, kUnionTag); }
+  static bool tagged_is_union(Tagged* tagged) {
+    return is(from_tagged(tagged), kUnionTag);
+  }
+
+  static int as_bitset(Type* type) {
+    ASSERT(is_bitset(type));
+    return reinterpret_cast<intptr_t>(type) >> 1;
+  }
+  static Tagged* as_tagged(Type* type) {
+    ASSERT(is_tagged(type));
+    return reinterpret_cast<Tagged*>(type);
+  }
+  static i::Handle<i::Map> as_class(Type* type) {
+    ASSERT(is_class(type));
+    return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 0));
+  }
+  static i::Handle<i::Object> as_constant(Type* type) {
+    ASSERT(is_constant(type));
+    return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 0));
+  }
+  static Unioned* as_union(Type* type) {
+    ASSERT(is_union(type));
+    return tagged_as_union(as_tagged(type));
+  }
+  static Unioned* tagged_as_union(Tagged* tagged) {
+    ASSERT(tagged_is_union(tagged));
+    return reinterpret_cast<Unioned*>(tagged);
+  }
+
+  static Type* from_bitset(int bitset) {
+    return reinterpret_cast<Type*>((bitset << 1) | 1);
+  }
+  static Type* from_bitset(int bitset, Zone* Zone) {
+    return from_bitset(bitset);
+  }
+  static Type* from_tagged(Tagged* tagged) {
+    return reinterpret_cast<Type*>(tagged);
+  }
+  static Type* from_class(i::Handle<i::Map> map, Zone* zone) {
+    Tagged* tagged = tagged_create(kClassTag, 1, zone);
+    tagged_set(tagged, 0, map.location());
+    return from_tagged(tagged);
+  }
+  static Type* from_constant(i::Handle<i::Object> value, Zone* zone) {
+    Tagged* tagged = tagged_create(kConstantTag, 1, zone);
+    tagged_set(tagged, 0, value.location());
+    return from_tagged(tagged);
+  }
+  static Type* from_union(Unioned* unioned) {
+    return from_tagged(tagged_from_union(unioned));
+  }
+  static Tagged* tagged_from_union(Unioned* unioned) {
+    return reinterpret_cast<Tagged*>(unioned);
+  }
+
+  static Unioned* union_create(int size, Zone* zone) {
+    return tagged_as_union(tagged_create(kUnionTag, size, zone));
+  }
+  static void union_shrink(Unioned* unioned, int size) {
+    tagged_shrink(tagged_from_union(unioned), size);
+  }
+  static Type* union_get(Unioned* unioned, int i) {
+    Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
+    ASSERT(!is_union(type));
+    return type;
+  }
+  static void union_set(Unioned* unioned, int i, Type* type) {
+    ASSERT(!is_union(type));
+    tagged_set(tagged_from_union(unioned), i, type);
+  }
+  static int union_length(Unioned* unioned) {
+    return tagged_length(tagged_from_union(unioned));
+  }
+};
+
+
+// Heap-allocated types are either smis for bitsets, maps for classes, boxes for
+// constants, or fixed arrays for unions.
 struct HeapTypeConfig {
   typedef TypeImpl<HeapTypeConfig> Type;
   typedef i::Object Base;
@@ -327,8 +468,6 @@ struct HeapTypeConfig {
   }
   static i::Handle<Type> from_constant(
       i::Handle<i::Object> value, Isolate* isolate) {
-    ASSERT(isolate || value->IsHeapObject());
-    if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate();
     i::Handle<Box> box = isolate->factory()->NewBox(value);
     return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
   }
@@ -339,13 +478,25 @@ struct HeapTypeConfig {
   static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
     return isolate->factory()->NewFixedArray(size);
   }
+  static void union_shrink(i::Handle<Unioned> unioned, int size) {
+    unioned->Shrink(size);
+  }
   static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
     Type* type = static_cast<Type*>(unioned->get(i));
     ASSERT(!is_union(type));
     return i::handle(type, unioned->GetIsolate());
   }
+  static void union_set(
+      i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
+    ASSERT(!is_union(*type));
+    unioned->set(i, *type);
+  }
+  static int union_length(i::Handle<Unioned> unioned) {
+    return unioned->length();
+  }
 };
 
+typedef TypeImpl<ZoneTypeConfig> ZoneType;
 typedef TypeImpl<HeapTypeConfig> Type;
 
 
@@ -399,6 +550,7 @@ struct BoundsImpl {
   }
 };
 
+typedef BoundsImpl<ZoneTypeConfig> ZoneBounds;
 typedef BoundsImpl<HeapTypeConfig> Bounds;
 
 
index adcc156940734cd3ece867c762d4dc0fe343aaa4..a3de98513dc917eff31f752b63503b0ff11c9945 100644 (file)
 
 using namespace v8::internal;
 
+template<class Type, class TypeHandle, class Region>
+class Types {
+ public:
+  Types(Region* region, Isolate* isolate) :
+      None(Type::None(region)),
+      Any(Type::Any(region)),
+      Oddball(Type::Oddball(region)),
+      Boolean(Type::Boolean(region)),
+      Null(Type::Null(region)),
+      Undefined(Type::Undefined(region)),
+      Number(Type::Number(region)),
+      Smi(Type::Smi(region)),
+      Signed32(Type::Signed32(region)),
+      Double(Type::Double(region)),
+      Name(Type::Name(region)),
+      UniqueName(Type::UniqueName(region)),
+      String(Type::String(region)),
+      InternalizedString(Type::InternalizedString(region)),
+      Symbol(Type::Symbol(region)),
+      Receiver(Type::Receiver(region)),
+      Object(Type::Object(region)),
+      Array(Type::Array(region)),
+      Function(Type::Function(region)),
+      Proxy(Type::Proxy(region)),
+      object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
+      array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
+      region_(region) {
+    smi = handle(Smi::FromInt(666), isolate);
+    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
+    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
+    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
+    array = isolate->factory()->NewJSArray(20);
+    ObjectClass = Type::Class(object_map, region);
+    ArrayClass = Type::Class(array_map, region);
+    SmiConstant = Type::Constant(smi, region);
+    Signed32Constant = Type::Constant(signed32, region);
+    ObjectConstant1 = Type::Constant(object1, region);
+    ObjectConstant2 = Type::Constant(object2, region);
+    ArrayConstant1 = Type::Constant(array, region);
+    ArrayConstant2 = Type::Constant(array, region);
+  }
+
+  TypeHandle None;
+  TypeHandle Any;
+  TypeHandle Oddball;
+  TypeHandle Boolean;
+  TypeHandle Null;
+  TypeHandle Undefined;
+  TypeHandle Number;
+  TypeHandle Smi;
+  TypeHandle Signed32;
+  TypeHandle Double;
+  TypeHandle Name;
+  TypeHandle UniqueName;
+  TypeHandle String;
+  TypeHandle InternalizedString;
+  TypeHandle Symbol;
+  TypeHandle Receiver;
+  TypeHandle Object;
+  TypeHandle Array;
+  TypeHandle Function;
+  TypeHandle Proxy;
+
+  TypeHandle ObjectClass;
+  TypeHandle ArrayClass;
+
+  TypeHandle SmiConstant;
+  TypeHandle Signed32Constant;
+  TypeHandle ObjectConstant1;
+  TypeHandle ObjectConstant2;
+  TypeHandle ArrayConstant1;
+  TypeHandle ArrayConstant2;
+
+  Handle<i::Map> object_map;
+  Handle<i::Map> array_map;
+
+  Handle<i::Smi> smi;
+  Handle<i::HeapNumber> signed32;
+  Handle<i::JSObject> object1;
+  Handle<i::JSObject> object2;
+  Handle<i::JSArray> array;
+
+  TypeHandle Union(TypeHandle t1, TypeHandle t2) {
+    return Type::Union(t1, t2, region_);
+  }
+  TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
+    return Type::Intersect(t1, t2, region_);
+  }
+
+ private:
+  Region* region_;
+};
+
+
 // Testing auxiliaries (breaking the Type abstraction).
-static bool IsBitset(Handle<Type> t) { return t->IsSmi(); }
-static bool IsClass(Handle<Type> t) { return t->IsMap(); }
-static bool IsConstant(Handle<Type> t) { return t->IsBox(); }
-static bool IsUnion(Handle<Type> t) { return t->IsFixedArray(); }
-
-static int AsBitset(Handle<Type> t) { return Smi::cast(*t)->value(); }
-static Map* AsClass(Handle<Type> t) { return Map::cast(*t); }
-static Object* AsConstant(Handle<Type> t) { return Box::cast(*t)->value(); }
-static FixedArray* AsUnion(Handle<Type> t) { return FixedArray::cast(*t); }
-
-
-static void CheckEqual(Handle<Type> type1, Handle<Type> type2) {
-  CHECK_EQ(IsBitset(type1), IsBitset(type2));
-  CHECK_EQ(IsClass(type1), IsClass(type2));
-  CHECK_EQ(IsConstant(type1), IsConstant(type2));
-  CHECK_EQ(IsUnion(type1), IsUnion(type2));
-  CHECK_EQ(type1->NumClasses(), type2->NumClasses());
-  CHECK_EQ(type1->NumConstants(), type2->NumConstants());
-  if (IsBitset(type1)) {
-    CHECK_EQ(AsBitset(type1), AsBitset(type2));
-  } else if (IsClass(type1)) {
-    CHECK_EQ(AsClass(type1), AsClass(type2));
-  } else if (IsConstant(type1)) {
-    CHECK_EQ(AsConstant(type1), AsConstant(type2));
-  } else if (IsUnion(type1)) {
-    CHECK_EQ(AsUnion(type1)->length(), AsUnion(type2)->length());
+struct ZoneRep {
+  static bool IsTagged(ZoneType* t, int tag) {
+    return !IsBitset(t)
+        && reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag;
   }
-  CHECK(type1->Is(type2));
-  CHECK(type2->Is(type1));
-}
+  static bool IsBitset(ZoneType* t) {
+    return reinterpret_cast<intptr_t>(t) & 1;
+  }
+  static bool IsClass(ZoneType* t) { return IsTagged(t, 0); }
+  static bool IsConstant(ZoneType* t) { return IsTagged(t, 1); }
+  static bool IsUnion(ZoneType* t) { return IsTagged(t, 2); }
+
+  static ZoneList<void*>* AsTagged(ZoneType* t) {
+    return reinterpret_cast<ZoneList<void*>*>(t);
+  }
+  static int AsBitset(ZoneType* t) {
+    return reinterpret_cast<intptr_t>(t) >> 1;
+  }
+  static Map* AsClass(ZoneType* t) {
+    return *reinterpret_cast<Map**>(AsTagged(t)->at(1));
+  }
+  static Object* AsConstant(ZoneType* t) {
+    return *reinterpret_cast<Object**>(AsTagged(t)->at(1));
+  }
+  static ZoneList<ZoneType*>* AsUnion(ZoneType* t) {
+    return reinterpret_cast<ZoneList<ZoneType*>*>(AsTagged(t));
+  }
+
+  static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
+};
+
 
+struct HeapRep {
+  static bool IsBitset(Handle<Type> t) { return t->IsSmi(); }
+  static bool IsClass(Handle<Type> t) { return t->IsMap(); }
+  static bool IsConstant(Handle<Type> t) { return t->IsBox(); }
+  static bool IsUnion(Handle<Type> t) { return t->IsFixedArray(); }
 
-static void CheckSub(Handle<Type> type1, Handle<Type> type2) {
-  CHECK(type1->Is(type2));
-  CHECK(!type2->Is(type1));
-  if (IsBitset(type1) && IsBitset(type2)) {
-    CHECK_NE(AsBitset(type1), AsBitset(type2));
+  static int AsBitset(Handle<Type> t) { return Smi::cast(*t)->value(); }
+  static Map* AsClass(Handle<Type> t) { return Map::cast(*t); }
+  static Object* AsConstant(Handle<Type> t) { return Box::cast(*t)->value(); }
+  static FixedArray* AsUnion(Handle<Type> t) { return FixedArray::cast(*t); }
+
+  static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
+};
+
+
+template<class Type, class TypeHandle, class Region, class Rep>
+struct Tests : Rep {
+  Isolate* isolate;
+  HandleScope scope;
+  Zone zone;
+  Types<Type, TypeHandle, Region> T;
+
+  Tests() :
+      isolate(CcTest::i_isolate()),
+      scope(isolate),
+      zone(isolate),
+      T(Rep::ToRegion(&zone, isolate), isolate) {
   }
-}
 
+  static void CheckEqual(TypeHandle type1, TypeHandle type2) {
+    CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2));
+    CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2));
+    CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2));
+    CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2));
+    CHECK_EQ(type1->NumClasses(), type2->NumClasses());
+    CHECK_EQ(type1->NumConstants(), type2->NumConstants());
+    if (Rep::IsBitset(type1)) {
+      CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2));
+    } else if (Rep::IsClass(type1)) {
+      CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2));
+    } else if (Rep::IsConstant(type1)) {
+      CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2));
+    } else if (Rep::IsUnion(type1)) {
+      CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length());
+    }
+    CHECK(type1->Is(type2));
+    CHECK(type2->Is(type1));
+  }
 
-static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) {
-  CHECK(!type1->Is(type2));
-  CHECK(!type2->Is(type1));
-  if (IsBitset(type1) && IsBitset(type2)) {
-    CHECK_NE(AsBitset(type1), AsBitset(type2));
+  static void CheckSub(TypeHandle type1, TypeHandle type2) {
+    CHECK(type1->Is(type2));
+    CHECK(!type2->Is(type1));
+    if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
+      CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
+    }
   }
-}
 
+  static void CheckUnordered(TypeHandle type1, TypeHandle type2) {
+    CHECK(!type1->Is(type2));
+    CHECK(!type2->Is(type1));
+    if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
+      CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
+    }
+  }
 
-static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) {
-  CHECK(type1->Maybe(type2));
-  CHECK(type2->Maybe(type1));
-  if (IsBitset(type1) && IsBitset(type2)) {
-    CHECK_NE(0, AsBitset(type1) & AsBitset(type2));
+  static void CheckOverlap(TypeHandle type1, TypeHandle type2) {
+    CHECK(type1->Maybe(type2));
+    CHECK(type2->Maybe(type1));
+    if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
+      CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
+    }
+  }
+
+  static void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
+    CHECK(!type1->Is(type2));
+    CHECK(!type2->Is(type1));
+    CHECK(!type1->Maybe(type2));
+    CHECK(!type2->Maybe(type1));
+    if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
+      CHECK_EQ(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
+    }
   }
-}
 
+  void Bitset() {
+    CHECK(IsBitset(T.None));
+    CHECK(IsBitset(T.Any));
+    CHECK(IsBitset(T.String));
+    CHECK(IsBitset(T.Object));
 
-static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) {
-  CHECK(!type1->Is(type2));
-  CHECK(!type2->Is(type1));
-  CHECK(!type1->Maybe(type2));
-  CHECK(!type2->Maybe(type1));
-  if (IsBitset(type1) && IsBitset(type2)) {
-    CHECK_EQ(0, AsBitset(type1) & AsBitset(type2));
+    CHECK(IsBitset(T.Union(T.String, T.Number)));
+    CHECK(IsBitset(T.Union(T.String, T.Receiver)));
+
+    CHECK_EQ(0, AsBitset(T.None));
+    CHECK_EQ(AsBitset(T.Number) | AsBitset(T.String),
+             AsBitset(T.Union(T.String, T.Number)));
+    CHECK_EQ(AsBitset(T.Receiver),
+             AsBitset(T.Union(T.Receiver, T.Object)));
   }
-}
 
+  void Class() {
+    CHECK(IsClass(T.ObjectClass));
+    CHECK(IsClass(T.ArrayClass));
 
-class HandlifiedTypes {
- public:
-  explicit HandlifiedTypes(Isolate* isolate) :
-      None(Type::None(isolate)),
-      Any(Type::Any(isolate)),
-      Oddball(Type::Oddball(isolate)),
-      Boolean(Type::Boolean(isolate)),
-      Null(Type::Null(isolate)),
-      Undefined(Type::Undefined(isolate)),
-      Number(Type::Number(isolate)),
-      Smi(Type::Smi(isolate)),
-      Signed32(Type::Signed32(isolate)),
-      Double(Type::Double(isolate)),
-      Name(Type::Name(isolate)),
-      UniqueName(Type::UniqueName(isolate)),
-      String(Type::String(isolate)),
-      InternalizedString(Type::InternalizedString(isolate)),
-      Symbol(Type::Symbol(isolate)),
-      Receiver(Type::Receiver(isolate)),
-      Object(Type::Object(isolate)),
-      Array(Type::Array(isolate)),
-      Function(Type::Function(isolate)),
-      Proxy(Type::Proxy(isolate)),
-      object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
-      array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
-      isolate_(isolate) {
-    smi = handle(Smi::FromInt(666), isolate);
-    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
-    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
-    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
-    array = isolate->factory()->NewJSArray(20);
-    ObjectClass = Type::Class(object_map, isolate);
-    ArrayClass = Type::Class(array_map, isolate);
-    SmiConstant = Type::Constant(smi, isolate);
-    Signed32Constant = Type::Constant(signed32, isolate);
-    ObjectConstant1 = Type::Constant(object1, isolate);
-    ObjectConstant2 = Type::Constant(object2, isolate);
-    ArrayConstant1 = Type::Constant(array, isolate);
-    ArrayConstant2 = Type::Constant(array, isolate);
+    CHECK(*T.object_map == AsClass(T.ObjectClass));
+    CHECK(*T.array_map == AsClass(T.ArrayClass));
   }
 
-  Handle<Type> None;
-  Handle<Type> Any;
-  Handle<Type> Oddball;
-  Handle<Type> Boolean;
-  Handle<Type> Null;
-  Handle<Type> Undefined;
-  Handle<Type> Number;
-  Handle<Type> Smi;
-  Handle<Type> Signed32;
-  Handle<Type> Double;
-  Handle<Type> Name;
-  Handle<Type> UniqueName;
-  Handle<Type> String;
-  Handle<Type> InternalizedString;
-  Handle<Type> Symbol;
-  Handle<Type> Receiver;
-  Handle<Type> Object;
-  Handle<Type> Array;
-  Handle<Type> Function;
-  Handle<Type> Proxy;
-
-  Handle<Type> ObjectClass;
-  Handle<Type> ArrayClass;
-
-  Handle<Type> SmiConstant;
-  Handle<Type> Signed32Constant;
-  Handle<Type> ObjectConstant1;
-  Handle<Type> ObjectConstant2;
-  Handle<Type> ArrayConstant1;
-  Handle<Type> ArrayConstant2;
-
-  Handle<Map> object_map;
-  Handle<Map> array_map;
+  void Constant() {
+    CHECK(IsConstant(T.SmiConstant));
+    CHECK(IsConstant(T.ObjectConstant1));
+    CHECK(IsConstant(T.ObjectConstant2));
+    CHECK(IsConstant(T.ArrayConstant1));
+    CHECK(IsConstant(T.ArrayConstant2));
+
+    CHECK(*T.smi == AsConstant(T.SmiConstant));
+    CHECK(*T.object1 == AsConstant(T.ObjectConstant1));
+    CHECK(*T.object2 == AsConstant(T.ObjectConstant2));
+    CHECK(*T.object1 != AsConstant(T.ObjectConstant2));
+    CHECK(*T.array == AsConstant(T.ArrayConstant1));
+    CHECK(*T.array == AsConstant(T.ArrayConstant2));
+  }
 
-  Handle<i::Smi> smi;
-  Handle<HeapNumber> signed32;
-  Handle<JSObject> object1;
-  Handle<JSObject> object2;
-  Handle<JSArray> array;
+  void Is() {
+    // Reflexivity
+    CHECK(T.None->Is(T.None));
+    CHECK(T.Any->Is(T.Any));
+    CHECK(T.Object->Is(T.Object));
+
+    CHECK(T.ObjectClass->Is(T.ObjectClass));
+    CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
+    CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
+
+    // Symmetry and Transitivity
+    CheckSub(T.None, T.Number);
+    CheckSub(T.None, T.Any);
+
+    CheckSub(T.Oddball, T.Any);
+    CheckSub(T.Boolean, T.Oddball);
+    CheckSub(T.Null, T.Oddball);
+    CheckSub(T.Undefined, T.Oddball);
+    CheckUnordered(T.Boolean, T.Null);
+    CheckUnordered(T.Undefined, T.Null);
+    CheckUnordered(T.Boolean, T.Undefined);
+
+    CheckSub(T.Number, T.Any);
+    CheckSub(T.Smi, T.Number);
+    CheckSub(T.Signed32, T.Number);
+    CheckSub(T.Double, T.Number);
+    CheckSub(T.Smi, T.Signed32);
+    CheckUnordered(T.Smi, T.Double);
+    CheckUnordered(T.Signed32, T.Double);
+
+    CheckSub(T.Name, T.Any);
+    CheckSub(T.UniqueName, T.Any);
+    CheckSub(T.UniqueName, T.Name);
+    CheckSub(T.String, T.Name);
+    CheckSub(T.InternalizedString, T.String);
+    CheckSub(T.InternalizedString, T.UniqueName);
+    CheckSub(T.InternalizedString, T.Name);
+    CheckSub(T.Symbol, T.UniqueName);
+    CheckSub(T.Symbol, T.Name);
+    CheckUnordered(T.String, T.UniqueName);
+    CheckUnordered(T.String, T.Symbol);
+    CheckUnordered(T.InternalizedString, T.Symbol);
+
+    CheckSub(T.Receiver, T.Any);
+    CheckSub(T.Object, T.Any);
+    CheckSub(T.Object, T.Receiver);
+    CheckSub(T.Array, T.Object);
+    CheckSub(T.Function, T.Object);
+    CheckSub(T.Proxy, T.Receiver);
+    CheckUnordered(T.Object, T.Proxy);
+    CheckUnordered(T.Array, T.Function);
+
+    // Structured subtyping
+    CheckSub(T.None, T.ObjectClass);
+    CheckSub(T.None, T.ObjectConstant1);
+    CheckSub(T.ObjectClass, T.Any);
+    CheckSub(T.ObjectConstant1, T.Any);
+
+    CheckSub(T.ObjectClass, T.Object);
+    CheckSub(T.ArrayClass, T.Object);
+    CheckUnordered(T.ObjectClass, T.ArrayClass);
+
+    CheckSub(T.SmiConstant, T.Smi);
+    CheckSub(T.SmiConstant, T.Signed32);
+    CheckSub(T.SmiConstant, T.Number);
+    CheckSub(T.ObjectConstant1, T.Object);
+    CheckSub(T.ObjectConstant2, T.Object);
+    CheckSub(T.ArrayConstant1, T.Object);
+    CheckSub(T.ArrayConstant1, T.Array);
+    CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
+    CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
+
+    CheckUnordered(T.ObjectConstant1, T.ObjectClass);
+    CheckUnordered(T.ObjectConstant2, T.ObjectClass);
+    CheckUnordered(T.ObjectConstant1, T.ArrayClass);
+    CheckUnordered(T.ObjectConstant2, T.ArrayClass);
+    CheckUnordered(T.ArrayConstant1, T.ObjectClass);
+  }
 
-  Handle<Type> Union(Handle<Type> t1, Handle<Type> t2) {
-    return Type::Union(t1, t2, isolate_);
+  void Maybe() {
+    CheckOverlap(T.Any, T.Any);
+    CheckOverlap(T.Object, T.Object);
+
+    CheckOverlap(T.Oddball, T.Any);
+    CheckOverlap(T.Boolean, T.Oddball);
+    CheckOverlap(T.Null, T.Oddball);
+    CheckOverlap(T.Undefined, T.Oddball);
+    CheckDisjoint(T.Boolean, T.Null);
+    CheckDisjoint(T.Undefined, T.Null);
+    CheckDisjoint(T.Boolean, T.Undefined);
+
+    CheckOverlap(T.Number, T.Any);
+    CheckOverlap(T.Smi, T.Number);
+    CheckOverlap(T.Double, T.Number);
+    CheckDisjoint(T.Signed32, T.Double);
+
+    CheckOverlap(T.Name, T.Any);
+    CheckOverlap(T.UniqueName, T.Any);
+    CheckOverlap(T.UniqueName, T.Name);
+    CheckOverlap(T.String, T.Name);
+    CheckOverlap(T.InternalizedString, T.String);
+    CheckOverlap(T.InternalizedString, T.UniqueName);
+    CheckOverlap(T.InternalizedString, T.Name);
+    CheckOverlap(T.Symbol, T.UniqueName);
+    CheckOverlap(T.Symbol, T.Name);
+    CheckOverlap(T.String, T.UniqueName);
+    CheckDisjoint(T.String, T.Symbol);
+    CheckDisjoint(T.InternalizedString, T.Symbol);
+
+    CheckOverlap(T.Receiver, T.Any);
+    CheckOverlap(T.Object, T.Any);
+    CheckOverlap(T.Object, T.Receiver);
+    CheckOverlap(T.Array, T.Object);
+    CheckOverlap(T.Function, T.Object);
+    CheckOverlap(T.Proxy, T.Receiver);
+    CheckDisjoint(T.Object, T.Proxy);
+    CheckDisjoint(T.Array, T.Function);
+
+    CheckOverlap(T.ObjectClass, T.Any);
+    CheckOverlap(T.ObjectConstant1, T.Any);
+
+    CheckOverlap(T.ObjectClass, T.Object);
+    CheckOverlap(T.ArrayClass, T.Object);
+    CheckOverlap(T.ObjectClass, T.ObjectClass);
+    CheckOverlap(T.ArrayClass, T.ArrayClass);
+    CheckDisjoint(T.ObjectClass, T.ArrayClass);
+
+    CheckOverlap(T.SmiConstant, T.Smi);
+    CheckOverlap(T.SmiConstant, T.Signed32);
+    CheckOverlap(T.SmiConstant, T.Number);
+    CheckDisjoint(T.SmiConstant, T.Double);
+    CheckOverlap(T.ObjectConstant1, T.Object);
+    CheckOverlap(T.ObjectConstant2, T.Object);
+    CheckOverlap(T.ArrayConstant1, T.Object);
+    CheckOverlap(T.ArrayConstant1, T.Array);
+    CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
+    CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
+    CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
+    CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
+
+    CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
+    CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
+    CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
+    CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
+    CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
   }
-  Handle<Type> Intersect(Handle<Type> t1, Handle<Type> t2) {
-    return Type::Intersect(t1, t2, isolate_);
+
+  void Union() {
+    // Bitset-bitset
+    CHECK(IsBitset(T.Union(T.Object, T.Number)));
+    CHECK(IsBitset(T.Union(T.Object, T.Object)));
+    CHECK(IsBitset(T.Union(T.Any, T.None)));
+
+    CheckEqual(T.Union(T.None, T.Number), T.Number);
+    CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
+    CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
+    CheckSub(T.Union(T.Number, T.String), T.Any);
+
+    // Class-class
+    CHECK(IsClass(T.Union(T.ObjectClass, T.ObjectClass)));
+    CHECK(IsUnion(T.Union(T.ObjectClass, T.ArrayClass)));
+
+    CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
+    CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
+    CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
+    CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
+    CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
+    CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
+    CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
+    CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
+    CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
+
+    // Constant-constant
+    CHECK(IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
+    CHECK(IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1)));
+    CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2)));
+
+    CheckEqual(
+        T.Union(T.ObjectConstant1, T.ObjectConstant1),
+        T.ObjectConstant1);
+    CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
+    CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
+    CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
+    CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
+    CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
+    CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
+    CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
+    CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
+    CheckUnordered(
+        T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
+    CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
+    CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
+    CheckOverlap(
+        T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
+    CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
+    CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
+
+    // Bitset-class
+    CHECK(IsBitset(T.Union(T.ObjectClass, T.Object)));
+    CHECK(IsUnion(T.Union(T.ObjectClass, T.Number)));
+
+    CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
+    CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
+    CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
+    CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
+    CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
+    CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
+    CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
+    CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
+
+    // Bitset-constant
+    CHECK(IsBitset(T.Union(T.SmiConstant, T.Number)));
+    CHECK(IsBitset(T.Union(T.ObjectConstant1, T.Object)));
+    CHECK(IsUnion(T.Union(T.ObjectConstant2, T.Number)));
+
+    CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
+    CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
+    CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
+    CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
+    CheckSub(
+        T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
+    CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
+    CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
+    CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
+    CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
+    CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
+
+    // Class-constant
+    CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass)));
+    CHECK(IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2)));
+
+    CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
+    CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
+    CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
+    CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
+    CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
+    CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
+    CheckSub(
+        T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
+    CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
+    CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
+    CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
+
+    // Bitset-union
+    CHECK(IsBitset(
+        T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
+    CHECK(IsUnion(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
+
+    CheckEqual(
+        T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
+        T.Object);
+    CheckEqual(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
+        T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
+    CheckSub(
+        T.Double,
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
+    CheckSub(
+        T.ObjectConstant1,
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+    CheckSub(
+        T.None,
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+    CheckSub(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+        T.Any);
+    CheckSub(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+        T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
+
+    // Class-union
+    CHECK(IsUnion(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
+    CHECK(IsUnion(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
+
+    CheckEqual(
+        T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
+        T.Union(T.ObjectClass, T.ObjectConstant1));
+    CheckSub(
+        T.None,
+        T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
+    CheckSub(
+        T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
+        T.Any);
+    CheckSub(
+        T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
+        T.Object);
+    CheckEqual(
+        T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
+        T.Union(T.ArrayClass, T.ObjectConstant2));
+
+    // Constant-union
+    CHECK(IsUnion(T.Union(
+        T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
+    CHECK(IsUnion(T.Union(
+        T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
+    CHECK(IsUnion(T.Union(
+        T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
+
+    CheckEqual(
+        T.Union(
+            T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+        T.Union(T.ObjectConstant2, T.ObjectConstant1));
+    CheckEqual(
+        T.Union(
+            T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
+        T.Union(
+            T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
+
+    // Union-union
+    CHECK(IsBitset(T.Union(
+        T.Union(T.Number, T.ArrayClass),
+        T.Union(T.Signed32, T.Array))));
+    CHECK(IsUnion(T.Union(
+        T.Union(T.Number, T.ArrayClass),
+        T.Union(T.ObjectClass, T.ArrayClass))));
+
+    CheckEqual(
+        T.Union(
+            T.Union(T.ObjectConstant2, T.ObjectConstant1),
+            T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+        T.Union(T.ObjectConstant2, T.ObjectConstant1));
+    CheckEqual(
+        T.Union(
+            T.Union(T.ObjectConstant2, T.ArrayConstant1),
+            T.Union(T.ObjectConstant1, T.ArrayConstant2)),
+        T.Union(
+            T.Union(T.ObjectConstant1, T.ObjectConstant2),
+            T.ArrayConstant1));
+    CheckEqual(
+        T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
+        T.Union(T.Number, T.Array));
   }
 
- private:
-  Isolate* isolate_;
+  void Intersect() {
+    // Bitset-bitset
+    CHECK(IsBitset(T.Intersect(T.Object, T.Number)));
+    CHECK(IsBitset(T.Intersect(T.Object, T.Object)));
+    CHECK(IsBitset(T.Intersect(T.Any, T.None)));
+
+    CheckEqual(T.Intersect(T.None, T.Number), T.None);
+    CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
+    CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
+    CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
+
+    // Class-class
+    CHECK(IsClass(T.Intersect(T.ObjectClass, T.ObjectClass)));
+    CHECK(IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass)));
+
+    CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
+    CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
+
+    // Constant-constant
+    CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1)));
+    CHECK(IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2)));
+    CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2)));
+
+    CheckEqual(
+        T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
+    CheckEqual(
+        T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
+    CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
+
+    // Bitset-class
+    CHECK(IsClass(T.Intersect(T.ObjectClass, T.Object)));
+    CHECK(IsBitset(T.Intersect(T.ObjectClass, T.Number)));
+
+    CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
+    CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
+    CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
+
+    // Bitset-constant
+    CHECK(IsBitset(T.Intersect(T.Smi, T.Number)));
+    CHECK(IsConstant(T.Intersect(T.SmiConstant, T.Number)));
+    CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
+
+    CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
+    CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
+    CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
+
+    // Class-constant
+    CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass)));
+    CHECK(IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2)));
+
+    CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
+    CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
+
+    // Bitset-union
+    CHECK(IsUnion(
+        T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
+    CHECK(IsBitset(
+        T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
+
+    CheckEqual(
+        T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
+        T.Union(T.ObjectConstant1, T.ObjectClass));
+    CheckEqual(
+        T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
+        T.None);
+
+    // Class-union
+    CHECK(IsClass(
+        T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
+    CHECK(IsClass(
+        T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
+    CHECK(IsBitset(
+        T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
+
+    CheckEqual(
+        T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
+        T.ArrayClass);
+    CheckEqual(
+        T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
+        T.ArrayClass);
+    CheckEqual(
+        T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
+        T.None);
+
+    // Constant-union
+    CHECK(IsConstant(T.Intersect(
+        T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
+    CHECK(IsConstant(T.Intersect(
+        T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
+    CHECK(IsBitset(T.Intersect(
+        T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
+
+    CheckEqual(
+        T.Intersect(
+            T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+        T.ObjectConstant1);
+    CheckEqual(
+        T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
+        T.SmiConstant);
+    CheckEqual(
+        T.Intersect(
+            T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
+        T.None);
+
+    // Union-union
+    CHECK(IsUnion(T.Intersect(
+        T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
+    CHECK(IsBitset(T.Intersect(
+        T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
+
+    CheckEqual(
+        T.Intersect(
+            T.Union(T.Number, T.ArrayClass),
+            T.Union(T.Smi, T.Array)),
+        T.Union(T.Smi, T.ArrayClass));
+    CheckEqual(
+        T.Intersect(
+            T.Union(T.Number, T.ObjectClass),
+            T.Union(T.Signed32, T.Array)),
+        T.Signed32);
+    CheckEqual(
+        T.Intersect(
+            T.Union(T.ObjectConstant2, T.ObjectConstant1),
+            T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+        T.Union(T.ObjectConstant2, T.ObjectConstant1));
+    CheckEqual(
+        T.Intersect(
+            T.Union(
+                T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
+            T.Union(
+                T.ObjectConstant1,
+                T.Union(T.ArrayConstant1, T.ObjectConstant2))),
+        T.Union(T.ObjectConstant2, T.ObjectConstant1));
+    CheckEqual(
+        T.Intersect(
+            T.Union(T.ObjectConstant2, T.ArrayConstant1),
+            T.Union(T.ObjectConstant1, T.ArrayConstant2)),
+        T.ArrayConstant1);
+  }
 };
 
+typedef Tests<ZoneType, ZoneType*, Zone, ZoneRep> ZoneTests;
+typedef Tests<Type, Handle<Type>, Isolate, HeapRep> HeapTests;
+
 
 TEST(Bitset) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  CHECK(IsBitset(T.None));
-  CHECK(IsBitset(T.Any));
-  CHECK(IsBitset(T.String));
-  CHECK(IsBitset(T.Object));
-
-  CHECK(IsBitset(T.Union(T.String, T.Number)));
-  CHECK(IsBitset(T.Union(T.String, T.Receiver)));
-
-  CHECK_EQ(0, AsBitset(T.None));
-  CHECK_EQ(AsBitset(T.Number) | AsBitset(T.String),
-           AsBitset(T.Union(T.String, T.Number)));
-  CHECK_EQ(AsBitset(T.Receiver),
-           AsBitset(T.Union(T.Receiver, T.Object)));
+  ZoneTests().Bitset();
+  HeapTests().Bitset();
 }
 
 
 TEST(Class) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  CHECK(IsClass(T.ObjectClass));
-  CHECK(IsClass(T.ArrayClass));
-
-  CHECK(*T.object_map == AsClass(T.ObjectClass));
-  CHECK(*T.array_map == AsClass(T.ArrayClass));
+  ZoneTests().Class();
+  HeapTests().Class();
 }
 
 
 TEST(Constant) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  CHECK(IsConstant(T.SmiConstant));
-  CHECK(IsConstant(T.ObjectConstant1));
-  CHECK(IsConstant(T.ObjectConstant2));
-  CHECK(IsConstant(T.ArrayConstant1));
-  CHECK(IsConstant(T.ArrayConstant2));
-
-  CHECK(*T.smi == AsConstant(T.SmiConstant));
-  CHECK(*T.object1 == AsConstant(T.ObjectConstant1));
-  CHECK(*T.object2 == AsConstant(T.ObjectConstant2));
-  CHECK(*T.object1 != AsConstant(T.ObjectConstant2));
-  CHECK(*T.array == AsConstant(T.ArrayConstant1));
-  CHECK(*T.array == AsConstant(T.ArrayConstant2));
+  ZoneTests().Constant();
+  HeapTests().Constant();
 }
 
 
 TEST(Is) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  // Reflexivity
-  CHECK(T.None->Is(T.None));
-  CHECK(T.Any->Is(T.Any));
-  CHECK(T.Object->Is(T.Object));
-
-  CHECK(T.ObjectClass->Is(T.ObjectClass));
-  CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
-  CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
-
-  // Symmetry and Transitivity
-  CheckSub(T.None, T.Number);
-  CheckSub(T.None, T.Any);
-
-  CheckSub(T.Oddball, T.Any);
-  CheckSub(T.Boolean, T.Oddball);
-  CheckSub(T.Null, T.Oddball);
-  CheckSub(T.Undefined, T.Oddball);
-  CheckUnordered(T.Boolean, T.Null);
-  CheckUnordered(T.Undefined, T.Null);
-  CheckUnordered(T.Boolean, T.Undefined);
-
-  CheckSub(T.Number, T.Any);
-  CheckSub(T.Smi, T.Number);
-  CheckSub(T.Signed32, T.Number);
-  CheckSub(T.Double, T.Number);
-  CheckSub(T.Smi, T.Signed32);
-  CheckUnordered(T.Smi, T.Double);
-  CheckUnordered(T.Signed32, T.Double);
-
-  CheckSub(T.Name, T.Any);
-  CheckSub(T.UniqueName, T.Any);
-  CheckSub(T.UniqueName, T.Name);
-  CheckSub(T.String, T.Name);
-  CheckSub(T.InternalizedString, T.String);
-  CheckSub(T.InternalizedString, T.UniqueName);
-  CheckSub(T.InternalizedString, T.Name);
-  CheckSub(T.Symbol, T.UniqueName);
-  CheckSub(T.Symbol, T.Name);
-  CheckUnordered(T.String, T.UniqueName);
-  CheckUnordered(T.String, T.Symbol);
-  CheckUnordered(T.InternalizedString, T.Symbol);
-
-  CheckSub(T.Receiver, T.Any);
-  CheckSub(T.Object, T.Any);
-  CheckSub(T.Object, T.Receiver);
-  CheckSub(T.Array, T.Object);
-  CheckSub(T.Function, T.Object);
-  CheckSub(T.Proxy, T.Receiver);
-  CheckUnordered(T.Object, T.Proxy);
-  CheckUnordered(T.Array, T.Function);
-
-  // Structured subtyping
-  CheckSub(T.None, T.ObjectClass);
-  CheckSub(T.None, T.ObjectConstant1);
-  CheckSub(T.ObjectClass, T.Any);
-  CheckSub(T.ObjectConstant1, T.Any);
-
-  CheckSub(T.ObjectClass, T.Object);
-  CheckSub(T.ArrayClass, T.Object);
-  CheckUnordered(T.ObjectClass, T.ArrayClass);
-
-  CheckSub(T.SmiConstant, T.Smi);
-  CheckSub(T.SmiConstant, T.Signed32);
-  CheckSub(T.SmiConstant, T.Number);
-  CheckSub(T.ObjectConstant1, T.Object);
-  CheckSub(T.ObjectConstant2, T.Object);
-  CheckSub(T.ArrayConstant1, T.Object);
-  CheckSub(T.ArrayConstant1, T.Array);
-  CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
-  CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
-
-  CheckUnordered(T.ObjectConstant1, T.ObjectClass);
-  CheckUnordered(T.ObjectConstant2, T.ObjectClass);
-  CheckUnordered(T.ObjectConstant1, T.ArrayClass);
-  CheckUnordered(T.ObjectConstant2, T.ArrayClass);
-  CheckUnordered(T.ArrayConstant1, T.ObjectClass);
+  ZoneTests().Is();
+  HeapTests().Is();
 }
 
 
 TEST(Maybe) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  CheckOverlap(T.Any, T.Any);
-  CheckOverlap(T.Object, T.Object);
-
-  CheckOverlap(T.Oddball, T.Any);
-  CheckOverlap(T.Boolean, T.Oddball);
-  CheckOverlap(T.Null, T.Oddball);
-  CheckOverlap(T.Undefined, T.Oddball);
-  CheckDisjoint(T.Boolean, T.Null);
-  CheckDisjoint(T.Undefined, T.Null);
-  CheckDisjoint(T.Boolean, T.Undefined);
-
-  CheckOverlap(T.Number, T.Any);
-  CheckOverlap(T.Smi, T.Number);
-  CheckOverlap(T.Double, T.Number);
-  CheckDisjoint(T.Signed32, T.Double);
-
-  CheckOverlap(T.Name, T.Any);
-  CheckOverlap(T.UniqueName, T.Any);
-  CheckOverlap(T.UniqueName, T.Name);
-  CheckOverlap(T.String, T.Name);
-  CheckOverlap(T.InternalizedString, T.String);
-  CheckOverlap(T.InternalizedString, T.UniqueName);
-  CheckOverlap(T.InternalizedString, T.Name);
-  CheckOverlap(T.Symbol, T.UniqueName);
-  CheckOverlap(T.Symbol, T.Name);
-  CheckOverlap(T.String, T.UniqueName);
-  CheckDisjoint(T.String, T.Symbol);
-  CheckDisjoint(T.InternalizedString, T.Symbol);
-
-  CheckOverlap(T.Receiver, T.Any);
-  CheckOverlap(T.Object, T.Any);
-  CheckOverlap(T.Object, T.Receiver);
-  CheckOverlap(T.Array, T.Object);
-  CheckOverlap(T.Function, T.Object);
-  CheckOverlap(T.Proxy, T.Receiver);
-  CheckDisjoint(T.Object, T.Proxy);
-  CheckDisjoint(T.Array, T.Function);
-
-  CheckOverlap(T.ObjectClass, T.Any);
-  CheckOverlap(T.ObjectConstant1, T.Any);
-
-  CheckOverlap(T.ObjectClass, T.Object);
-  CheckOverlap(T.ArrayClass, T.Object);
-  CheckOverlap(T.ObjectClass, T.ObjectClass);
-  CheckOverlap(T.ArrayClass, T.ArrayClass);
-  CheckDisjoint(T.ObjectClass, T.ArrayClass);
-
-  CheckOverlap(T.SmiConstant, T.Smi);
-  CheckOverlap(T.SmiConstant, T.Signed32);
-  CheckOverlap(T.SmiConstant, T.Number);
-  CheckDisjoint(T.SmiConstant, T.Double);
-  CheckOverlap(T.ObjectConstant1, T.Object);
-  CheckOverlap(T.ObjectConstant2, T.Object);
-  CheckOverlap(T.ArrayConstant1, T.Object);
-  CheckOverlap(T.ArrayConstant1, T.Array);
-  CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
-  CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
-  CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
-  CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
-
-  CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
-  CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
-  CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
-  CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
-  CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
+  ZoneTests().Maybe();
+  HeapTests().Maybe();
 }
 
 
 TEST(Union) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  // Bitset-bitset
-  CHECK(IsBitset(T.Union(T.Object, T.Number)));
-  CHECK(IsBitset(T.Union(T.Object, T.Object)));
-  CHECK(IsBitset(T.Union(T.Any, T.None)));
-
-  CheckEqual(T.Union(T.None, T.Number), T.Number);
-  CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
-  CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
-  CheckSub(T.Union(T.Number, T.String), T.Any);
-
-  // Class-class
-  CHECK(IsClass(T.Union(T.ObjectClass, T.ObjectClass)));
-  CHECK(IsUnion(T.Union(T.ObjectClass, T.ArrayClass)));
-
-  CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
-  CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
-  CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
-  CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
-  CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
-  CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
-  CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
-  CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
-  CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
-
-  // Constant-constant
-  CHECK(IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
-  CHECK(IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1)));
-  CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2)));
-
-  CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
-  CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
-  CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
-  CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
-  CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
-  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
-  CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
-  CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
-  CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
-  CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
-  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
-  CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
-  CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
-  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
-  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
-
-  // Bitset-class
-  CHECK(IsBitset(T.Union(T.ObjectClass, T.Object)));
-  CHECK(IsUnion(T.Union(T.ObjectClass, T.Number)));
-
-  CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
-  CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
-  CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
-  CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
-  CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
-  CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
-  CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
-  CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
-
-  // Bitset-constant
-  CHECK(IsBitset(T.Union(T.SmiConstant, T.Number)));
-  CHECK(IsBitset(T.Union(T.ObjectConstant1, T.Object)));
-  CHECK(IsUnion(T.Union(T.ObjectConstant2, T.Number)));
-
-  CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
-  CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
-  CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
-  CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
-  CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
-  CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
-  CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
-  CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
-  CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
-  CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
-
-  // Class-constant
-  CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass)));
-  CHECK(IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2)));
-
-  CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
-  CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
-  CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
-  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
-  CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
-  CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
-  CheckSub(
-      T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
-  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
-  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
-  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
-
-  // Bitset-union
-  CHECK(IsBitset(T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
-  CHECK(IsUnion(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
-
-  CheckEqual(
-      T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
-      T.Object);
-  CheckEqual(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
-      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
-  CheckSub(
-      T.Double,
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
-  CheckSub(
-      T.ObjectConstant1,
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
-  CheckSub(
-      T.None,
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
-  CheckSub(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
-      T.Any);
-  CheckSub(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
-      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
-
-  // Class-union
-  CHECK(IsUnion(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
-  CHECK(IsUnion(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
-
-  CheckEqual(
-      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
-      T.Union(T.ObjectClass, T.ObjectConstant1));
-  CheckSub(
-      T.None,
-      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
-  CheckSub(
-      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
-      T.Any);
-  CheckSub(
-      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
-      T.Object);
-  CheckEqual(
-      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
-      T.Union(T.ArrayClass, T.ObjectConstant2));
-
-  // Constant-union
-  CHECK(IsUnion(T.Union(
-      T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
-  CHECK(IsUnion(T.Union(
-      T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
-  CHECK(IsUnion(T.Union(
-      T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
-
-  CheckEqual(
-      T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
-      T.Union(T.ObjectConstant2, T.ObjectConstant1));
-  CheckEqual(
-      T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
-      T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
-
-  // Union-union
-  CHECK(IsBitset(T.Union(
-      T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
-  CHECK(IsUnion(T.Union(
-      T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass))));
-
-  CheckEqual(
-      T.Union(
-          T.Union(T.ObjectConstant2, T.ObjectConstant1),
-          T.Union(T.ObjectConstant1, T.ObjectConstant2)),
-      T.Union(T.ObjectConstant2, T.ObjectConstant1));
-  CheckEqual(
-      T.Union(
-          T.Union(T.ObjectConstant2, T.ArrayConstant1),
-          T.Union(T.ObjectConstant1, T.ArrayConstant2)),
-      T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1));
-  CheckEqual(
-      T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
-      T.Union(T.Number, T.Array));
+  ZoneTests().Union();
+  HeapTests().Union();
 }
 
 
 TEST(Intersect) {
   CcTest::InitializeVM();
-  Isolate* isolate = CcTest::i_isolate();
-  HandleScope scope(isolate);
-  HandlifiedTypes T(isolate);
-
-  // Bitset-bitset
-  CHECK(IsBitset(T.Intersect(T.Object, T.Number)));
-  CHECK(IsBitset(T.Intersect(T.Object, T.Object)));
-  CHECK(IsBitset(T.Intersect(T.Any, T.None)));
-
-  CheckEqual(T.Intersect(T.None, T.Number), T.None);
-  CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
-  CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
-  CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
-
-  // Class-class
-  CHECK(IsClass(T.Intersect(T.ObjectClass, T.ObjectClass)));
-  CHECK(IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass)));
-
-  CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
-  CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
-
-  // Constant-constant
-  CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1)));
-  CHECK(IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2)));
-  CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2)));
-
-  CheckEqual(
-      T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
-  CheckEqual(
-      T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
-  CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
-
-  // Bitset-class
-  CHECK(IsClass(T.Intersect(T.ObjectClass, T.Object)));
-  CHECK(IsBitset(T.Intersect(T.ObjectClass, T.Number)));
-
-  CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
-  CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
-  CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
-
-  // Bitset-constant
-  CHECK(IsBitset(T.Intersect(T.Smi, T.Number)));
-  CHECK(IsConstant(T.Intersect(T.SmiConstant, T.Number)));
-  CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
-
-  CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
-  CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
-  CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
-
-  // Class-constant
-  CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass)));
-  CHECK(IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2)));
-
-  CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
-  CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
-
-  // Bitset-union
-  CHECK(IsUnion(
-      T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
-  CHECK(IsBitset(
-      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
-
-  CheckEqual(
-      T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
-      T.Union(T.ObjectConstant1, T.ObjectClass));
-  CheckEqual(
-      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
-      T.None);
-
-  // Class-union
-  CHECK(IsClass(
-      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
-  CHECK(IsClass(
-      T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
-  CHECK(IsBitset(
-      T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
-
-  CheckEqual(
-      T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
-      T.ArrayClass);
-  CheckEqual(
-      T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
-      T.ArrayClass);
-  CheckEqual(
-      T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
-      T.None);
-
-  // Constant-union
-  CHECK(IsConstant(T.Intersect(
-      T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
-  CHECK(IsConstant(T.Intersect(
-      T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
-  CHECK(IsBitset(T.Intersect(
-      T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
-
-  CheckEqual(
-      T.Intersect(
-          T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
-      T.ObjectConstant1);
-  CheckEqual(
-      T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
-      T.SmiConstant);
-  CheckEqual(
-      T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
-      T.None);
-
-  // Union-union
-  CHECK(IsUnion(T.Intersect(
-      T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
-  CHECK(IsBitset(T.Intersect(
-      T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
-
-  CheckEqual(
-      T.Intersect(
-          T.Union(T.Number, T.ArrayClass),
-          T.Union(T.Smi, T.Array)),
-      T.Union(T.Smi, T.ArrayClass));
-  CheckEqual(
-      T.Intersect(
-          T.Union(T.Number, T.ObjectClass),
-          T.Union(T.Signed32, T.Array)),
-      T.Signed32);
-  CheckEqual(
-      T.Intersect(
-          T.Union(T.ObjectConstant2, T.ObjectConstant1),
-          T.Union(T.ObjectConstant1, T.ObjectConstant2)),
-      T.Union(T.ObjectConstant2, T.ObjectConstant1));
-  CheckEqual(
-      T.Intersect(
-          T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
-          T.Union(
-              T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))),
-      T.Union(T.ObjectConstant2, T.ObjectConstant1));
-  CheckEqual(
-      T.Intersect(
-          T.Union(T.ObjectConstant2, T.ArrayConstant1),
-          T.Union(T.ObjectConstant1, T.ArrayConstant2)),
-      T.ArrayConstant1);
+  ZoneTests().Intersect();
+  HeapTests().Intersect();
 }