Revert "Implement structural function and array types"
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 16 Apr 2014 15:59:39 +0000 (15:59 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 16 Apr 2014 15:59:39 +0000 (15:59 +0000)
TBR=jarin@chromium.org
BUG=

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

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

15 files changed:
src/accessors.cc
src/arm/stub-cache-arm.cc
src/arm64/stub-cache-arm64.cc
src/hydrogen.cc
src/hydrogen.h
src/ia32/stub-cache-ia32.cc
src/ic.cc
src/objects-debug.cc
src/objects-inl.h
src/stub-cache.cc
src/types-inl.h
src/types.cc
src/types.h
src/x64/stub-cache-x64.cc
test/cctest/test-types.cc

index 32c501a..2e3bfb8 100644 (file)
@@ -126,7 +126,7 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
   }
 
   if (!type->IsClass()) return false;
-  Handle<Map> map = type->AsClass()->Map();
+  Handle<Map> map = type->AsClass();
 
   switch (map->instance_type()) {
     case JS_ARRAY_TYPE:
index 6875dcf..ebbfce6 100644 (file)
@@ -432,7 +432,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = descriptors->GetFieldType(descriptor);
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
+      __ CheckMap(value_reg, scratch1, field_type->AsClass(),
                   miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
@@ -601,7 +601,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = lookup->GetFieldType();
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
+      __ CheckMap(value_reg, scratch1, field_type->AsClass(),
                   miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
@@ -850,9 +850,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
   int depth = 0;
 
   Handle<JSObject> current = Handle<JSObject>::null();
-  if (type->IsConstant()) {
-    current = Handle<JSObject>::cast(type->AsConstant()->Value());
-  }
+  if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
   Handle<JSObject> prototype = Handle<JSObject>::null();
   Handle<Map> current_map = receiver_map;
   Handle<Map> holder_map(holder->map());
index bf12840..e5383f1 100644 (file)
@@ -394,7 +394,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = descriptors->GetFieldType(descriptor);
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
+      __ CheckMap(value_reg, scratch1, field_type->AsClass(),
                   miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
@@ -550,7 +550,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = lookup->GetFieldType();
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
+      __ CheckMap(value_reg, scratch1, field_type->AsClass(),
                   miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
@@ -802,7 +802,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
 
   Handle<JSObject> current = Handle<JSObject>::null();
   if (type->IsConstant()) {
-    current = Handle<JSObject>::cast(type->AsConstant()->Value());
+    current = Handle<JSObject>::cast(type->AsConstant());
   }
   Handle<JSObject> prototype = Handle<JSObject>::null();
   Handle<Map> current_map = receiver_map;
index 833dc51..7a9dc90 100644 (file)
@@ -4926,7 +4926,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
         Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
         if (cell->type()->IsConstant()) {
           PropertyCell::AddDependentCompilationInfo(cell, top_info());
-          Handle<Object> constant_object = cell->type()->AsConstant()->Value();
+          Handle<Object> constant_object = cell->type()->AsConstant();
           if (constant_object->IsConsString()) {
             constant_object =
                 String::Flatten(Handle<String>::cast(constant_object));
@@ -4999,7 +4999,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
 static bool CanInlinePropertyAccess(Type* type) {
   if (type->Is(Type::NumberOrString())) return true;
   if (!type->IsClass()) return false;
-  Handle<Map> map = type->AsClass()->Map();
+  Handle<Map> map = type->AsClass();
   return map->IsJSObjectMap() &&
       !map->is_dictionary_map() &&
       !map->has_named_interceptor();
@@ -5991,7 +5991,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
     Handle<GlobalObject> global(current_info()->global_object());
     Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
     if (cell->type()->IsConstant()) {
-      Handle<Object> constant = cell->type()->AsConstant()->Value();
+      Handle<Object> constant = cell->type()->AsConstant();
       if (value->IsConstant()) {
         HConstant* c_value = HConstant::cast(value);
         if (!constant.is_identical_to(c_value->handle(isolate()))) {
@@ -9943,7 +9943,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
       HValue* operand_to_check =
           left->block()->block_id() < right->block()->block_id() ? left : right;
       if (combined_type->IsClass()) {
-        Handle<Map> map = combined_type->AsClass()->Map();
+        Handle<Map> map = combined_type->AsClass();
         AddCheckMap(operand_to_check, map);
         HCompareObjectEqAndBranch* result =
             New<HCompareObjectEqAndBranch>(left, right);
index c561ab1..b7915e6 100644 (file)
@@ -2380,7 +2380,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
         context = context->native_context();
         return handle(context->string_function()->initial_map());
       } else {
-        return type_->AsClass()->Map();
+        return type_->AsClass();
       }
     }
     Type* type() const { return type_; }
index 9c82692..209bfa6 100644 (file)
@@ -530,8 +530,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = descriptors->GetFieldType(descriptor);
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, field_type->AsClass()->Map(),
-                  miss_label, DO_SMI_CHECK);
+      __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
       __ JumpIfSmi(value_reg, miss_label);
@@ -707,8 +706,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = lookup->GetFieldType();
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, field_type->AsClass()->Map(),
-                  miss_label, DO_SMI_CHECK);
+      __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
       __ JumpIfSmi(value_reg, miss_label);
@@ -838,8 +836,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
   int depth = 0;
 
   Handle<JSObject> current = Handle<JSObject>::null();
-  if (type->IsConstant()) current =
-      Handle<JSObject>::cast(type->AsConstant()->Value());
+  if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
   Handle<JSObject> prototype = Handle<JSObject>::null();
   Handle<Map> current_map = receiver_map;
   Handle<Map> holder_map(holder->map());
index 86bef05..ecf0e9a 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -680,8 +680,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
 
   for (int i = 0; i < number_of_types; i++) {
     Handle<HeapType> current_type = types.at(i);
-    if (current_type->IsClass() &&
-        current_type->AsClass()->Map()->is_deprecated()) {
+    if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
       // Filter out deprecated maps to ensure their instances get migrated.
       ++deprecated_types;
     } else if (type->NowIs(current_type)) {
@@ -692,8 +691,8 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
     } else if (handler_to_overwrite == -1 &&
                current_type->IsClass() &&
                type->IsClass() &&
-               IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(),
-                                               *type->AsClass()->Map())) {
+               IsTransitionOfMonomorphicTarget(*current_type->AsClass(),
+                                               *type->AsClass())) {
       handler_to_overwrite = i;
     }
   }
@@ -735,11 +734,10 @@ Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) {
     return isolate->factory()->heap_number_map();
   if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map();
   if (type->IsConstant()) {
-    return handle(
-        Handle<JSGlobalObject>::cast(type->AsConstant()->Value())->map());
+    return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map());
   }
   ASSERT(type->IsClass());
-  return type->AsClass()->Map();
+  return type->AsClass();
 }
 
 
index 40132cb..2ff7058 100644 (file)
@@ -301,7 +301,7 @@ void JSObject::JSObjectVerify() {
         if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
         HeapType* field_type = descriptors->GetFieldType(i);
         if (field_type->IsClass()) {
-          Map* map = *field_type->AsClass()->Map();
+          Map* map = *field_type->AsClass();
           CHECK(!map->is_stable() || HeapObject::cast(value)->map() == map);
         } else if (r.IsNone()) {
           CHECK(field_type->Is(HeapType::None()));
index 023caa5..96433ea 100644 (file)
@@ -87,6 +87,13 @@ PropertyDetails PropertyDetails::AsDeleted() const {
   }
 
 
+#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type)   \
+  template<>                                    \
+  type* type::cast(Object* object) {            \
+    SLOW_ASSERT(object->Is##type());            \
+    return reinterpret_cast<type*>(object);     \
+  }
+
 #define INT_ACCESSORS(holder, name, offset)                             \
   int holder::name() { return READ_INT_FIELD(this, offset); }           \
   void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
index 91d31ea..e7bf069 100644 (file)
@@ -901,7 +901,7 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
   // check that the global property cell is empty.
   if (last_map->IsJSGlobalObjectMap()) {
     Handle<JSGlobalObject> global = last.is_null()
-        ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value())
+        ? Handle<JSGlobalObject>::cast(type->AsConstant())
         : Handle<JSGlobalObject>::cast(last);
     GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
   }
index 6f3f670..ad1107b 100644 (file)
 namespace v8 {
 namespace internal {
 
-// -------------------------------------------------------------------------- //
-// TypeImpl
-
-template<class Config>
-typename TypeImpl<Config>::template Iterator<i::Map>
-TypeImpl<Config>::Classes() {
-  if (this->IsBitset()) return Iterator<i::Map>();
-  return Iterator<i::Map>(Config::handle(this));
-}
-
-
-template<class Config>
-typename TypeImpl<Config>::template Iterator<i::Object>
-TypeImpl<Config>::Constants() {
-  if (this->IsBitset()) return Iterator<i::Object>();
-  return Iterator<i::Object>(Config::handle(this));
-}
-
-
-template<class Config>
-TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
-  TypeImpl* t = static_cast<TypeImpl*>(object);
-  ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() ||
-         t->IsUnion() || t->IsArray() || t->IsFunction());
-  return t;
-}
-
-
 template<class Config>
 bool TypeImpl<Config>::NowContains(i::Object* value) {
   DisallowHeapAllocation no_allocation;
@@ -55,44 +27,33 @@ bool TypeImpl<Config>::NowContains(i::Object* value) {
 }
 
 
-// -------------------------------------------------------------------------- //
-// ZoneTypeConfig
-
 // static
-template<class T>
-T* ZoneTypeConfig::handle(T* type) {
+Type* ZoneTypeConfig::handle(Type* type) {
   return type;
 }
 
 
 // static
-template<class T>
-T* ZoneTypeConfig::cast(Type* type) {
-  return static_cast<T*>(type);
-}
-
-
-// static
 bool ZoneTypeConfig::is_bitset(Type* type) {
   return reinterpret_cast<intptr_t>(type) & 1;
 }
 
 
 // static
-bool ZoneTypeConfig::is_struct(Type* type, int tag) {
-  return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
+bool ZoneTypeConfig::is_struct(Type* type) {
+  return !is_bitset(type);
 }
 
 
 // static
 bool ZoneTypeConfig::is_class(Type* type) {
-  return is_struct(type, Type::StructuralType::kClassTag);
+  return is_struct(type) && struct_tag(as_struct(type)) == Type::kClassTag;
 }
 
 
 // static
 bool ZoneTypeConfig::is_constant(Type* type) {
-  return is_struct(type, Type::StructuralType::kConstantTag);
+  return is_struct(type) && struct_tag(as_struct(type)) == Type::kConstantTag;
 }
 
 
@@ -105,7 +66,7 @@ int ZoneTypeConfig::as_bitset(Type* type) {
 
 // static
 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
-  ASSERT(!is_bitset(type));
+  ASSERT(is_struct(type));
   return reinterpret_cast<Struct*>(type);
 }
 
@@ -146,7 +107,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) {
 // static
 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
     i::Handle<i::Map> map, int lub, Zone* zone) {
-  Struct* structured = struct_create(Type::StructuralType::kClassTag, 2, zone);
+  Struct* structured = struct_create(Type::kClassTag, 2, zone);
   structured[2] = from_bitset(lub);
   structured[3] = map.location();
   return from_struct(structured);
@@ -156,8 +117,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
 // static
 ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
     i::Handle<i::Object> value, int lub, Zone* zone) {
-  Struct* structured =
-      struct_create(Type::StructuralType::kConstantTag, 2, zone);
+  Struct* structured = struct_create(Type::kConstantTag, 2, zone);
   structured[2] = from_bitset(lub);
   structured[3] = value.location();
   return from_struct(structured);
@@ -214,25 +174,15 @@ int ZoneTypeConfig::lub_bitset(Type* type) {
   return as_bitset(struct_get(as_struct(type), 0));
 }
 
-
 // -------------------------------------------------------------------------- //
-// HeapTypeConfig
 
 // static
-template<class T>
-i::Handle<T> HeapTypeConfig::handle(T* type) {
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::handle(Type* type) {
   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
 }
 
 
 // static
-template<class T>
-i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
-  return i::Handle<T>::cast(type);
-}
-
-
-// static
 bool HeapTypeConfig::is_bitset(Type* type) {
   return type->IsSmi();
 }
@@ -251,14 +201,14 @@ bool HeapTypeConfig::is_constant(Type* type) {
 
 
 // static
-bool HeapTypeConfig::is_struct(Type* type, int tag) {
-  return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
+bool HeapTypeConfig::is_struct(Type* type) {
+  return type->IsFixedArray();
 }
 
 
 // static
 int HeapTypeConfig::as_bitset(Type* type) {
-  return i::Smi::cast(type)->value();
+  return Smi::cast(type)->value();
 }
 
 
index f359362..4ddc14b 100644 (file)
@@ -12,14 +12,13 @@ namespace internal {
 
 template<class Config>
 int TypeImpl<Config>::NumClasses() {
-  DisallowHeapAllocation no_allocation;
   if (this->IsClass()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
+    StructHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->IsClass()) ++result;
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      if (Config::struct_get(unioned, i)->IsClass()) ++result;
     }
     return result;
   } else {
@@ -30,14 +29,13 @@ int TypeImpl<Config>::NumClasses() {
 
 template<class Config>
 int TypeImpl<Config>::NumConstants() {
-  DisallowHeapAllocation no_allocation;
   if (this->IsConstant()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
+    StructHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->IsConstant()) ++result;
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      if (Config::struct_get(unioned, i)->IsConstant()) ++result;
     }
     return result;
   } else {
@@ -50,7 +48,8 @@ template<class Config> template<class T>
 typename TypeImpl<Config>::TypeHandle
 TypeImpl<Config>::Iterator<T>::get_type() {
   ASSERT(!Done());
-  return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
+  return type_->IsUnion()
+      ? Config::struct_get(type_->AsUnion(), index_) : type_;
 }
 
 
@@ -68,7 +67,7 @@ struct TypeImplIteratorAux<Config, i::Map> {
     return type->IsClass();
   }
   static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
-    return type->AsClass()->Map();
+    return type->AsClass();
   }
 };
 
@@ -79,7 +78,7 @@ struct TypeImplIteratorAux<Config, i::Object> {
   }
   static i::Handle<i::Object> current(
       typename TypeImpl<Config>::TypeHandle type) {
-    return type->AsConstant()->Value();
+    return type->AsConstant();
   }
 };
 
@@ -96,12 +95,11 @@ i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
 
 template<class Config> template<class T>
 void TypeImpl<Config>::Iterator<T>::Advance() {
-  DisallowHeapAllocation no_allocation;
   ++index_;
   if (type_->IsUnion()) {
-    UnionHandle unioned = handle(type_->AsUnion());
-    for (; index_ < unioned->Length(); ++index_) {
-      if (matches(unioned->Get(index_))) return;
+    StructHandle unioned = type_->AsUnion();
+    for (; index_ < Config::struct_length(unioned); ++index_) {
+      if (matches(Config::struct_get(unioned, index_))) return;
     }
   } else if (index_ == 0 && matches(type_)) {
     return;
@@ -110,54 +108,30 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
 }
 
 
-// Get the largest bitset subsumed by this type.
-template<class Config>
-int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
-  DisallowHeapAllocation no_allocation;
-  if (type->IsBitset()) {
-    return type->AsBitset();
-  } else if (type->IsUnion()) {
-    // All but the first are non-bitsets and thus would yield kNone anyway.
-    return type->AsUnion()->Get(0)->BitsetGlb();
-  } else {
-    return kNone;
-  }
-}
-
-
 // Get the smallest bitset subsuming this type.
 template<class Config>
-int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
-  DisallowHeapAllocation no_allocation;
-  if (type->IsBitset()) {
-    return type->AsBitset();
-  } else if (type->IsUnion()) {
-    UnionHandle unioned = handle(type->AsUnion());
+int TypeImpl<Config>::LubBitset() {
+  if (this->IsBitset()) {
+    return this->AsBitset();
+  } else if (this->IsUnion()) {
+    StructHandle unioned = this->AsUnion();
     int bitset = kNone;
-    for (int i = 0; i < unioned->Length(); ++i) {
-      bitset |= unioned->Get(i)->BitsetLub();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      bitset |= Config::struct_get(unioned, i)->LubBitset();
     }
     return bitset;
-  } else if (type->IsClass()) {
-    int bitset = Config::lub_bitset(type);
-    return bitset ? bitset : Lub(*type->AsClass()->Map());
-  } else if (type->IsConstant()) {
-    int bitset = Config::lub_bitset(type);
-    return bitset ? bitset : Lub(*type->AsConstant()->Value());
-  } else if (type->IsArray()) {
-    return kArray;
-  } else if (type->IsFunction()) {
-    return kFunction;
+  } else if (this->IsClass()) {
+    int bitset = Config::lub_bitset(this);
+    return bitset ? bitset : LubBitset(*this->AsClass());
   } else {
-    UNREACHABLE();
-    return kNone;
+    int bitset = Config::lub_bitset(this);
+    return bitset ? bitset : LubBitset(*this->AsConstant());
   }
 }
 
 
 template<class Config>
-int TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
-  DisallowHeapAllocation no_allocation;
+int TypeImpl<Config>::LubBitset(i::Object* value) {
   if (value->IsSmi()) return kSignedSmall & kTaggedInt;
   i::Map* map = i::HeapObject::cast(value)->map();
   if (map->instance_type() == HEAP_NUMBER_TYPE) {
@@ -167,13 +141,12 @@ int TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
         value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) :
         value->ToUint32(&u) ? kUnsigned32 : kFloat);
   }
-  return Lub(map);
+  return LubBitset(map);
 }
 
 
 template<class Config>
-int TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
-  DisallowHeapAllocation no_allocation;
+int TypeImpl<Config>::LubBitset(i::Map* map) {
   switch (map->instance_type()) {
     case STRING_TYPE:
     case ASCII_STRING_TYPE:
@@ -262,6 +235,20 @@ int TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
 }
 
 
+// Get the largest bitset subsumed by this type.
+template<class Config>
+int TypeImpl<Config>::GlbBitset() {
+  if (this->IsBitset()) {
+    return this->AsBitset();
+  } else if (this->IsUnion()) {
+    // All but the first are non-bitsets and thus would yield kNone anyway.
+    return Config::struct_get(this->AsUnion(), 0)->GlbBitset();
+  } else {
+    return kNone;
+  }
+}
+
+
 // Most precise _current_ type of a value (usually its class).
 template<class Config>
 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
@@ -277,48 +264,25 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
 // Check this <= that.
 template<class Config>
 bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
-  DisallowHeapAllocation no_allocation;
-
   // Fast path for bitsets.
   if (this->IsNone()) return true;
   if (that->IsBitset()) {
-    return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset();
+    return (this->LubBitset() | that->AsBitset()) == that->AsBitset();
   }
 
   if (that->IsClass()) {
-    return this->IsClass()
-        && *this->AsClass()->Map() == *that->AsClass()->Map();
+    return this->IsClass() && *this->AsClass() == *that->AsClass();
   }
   if (that->IsConstant()) {
-    return this->IsConstant()
-        && *this->AsConstant()->Value() == *that->AsConstant()->Value();
-  }
-  if (that->IsArray()) {
-    return this->IsArray()
-        && this->AsArray()->Element()->Equals(that->AsArray()->Element());
-  }
-  if (that->IsFunction()) {
-    // We currently do not allow for any variance here, in order to keep
-    // Union and Intersect operations simple.
-    if (!this->IsFunction()) return false;
-    FunctionType* this_fun = this->AsFunction();
-    FunctionType* that_fun = that->AsFunction();
-    if (this_fun->Arity() != that_fun->Arity() ||
-        !this_fun->Result()->Equals(that_fun->Result()) ||
-        !that_fun->Receiver()->Equals(this_fun->Receiver())) {
-      return false;
-    }
-    for (int i = 0; i < this_fun->Arity(); ++i) {
-      if (!that_fun->Parameter(i)->Equals(this_fun->Parameter(i))) return false;
-    }
-    return true;
+    return this->IsConstant() && *this->AsConstant() == *that->AsConstant();
   }
 
   // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
   if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (!unioned->Get(i)->Is(that)) return false;
+    StructHandle unioned = this->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle this_i = Config::struct_get(unioned, i);
+      if (!this_i->Is(that)) return false;
     }
     return true;
   }
@@ -327,9 +291,10 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
   // (iff T is not a union)
   ASSERT(!this->IsUnion());
   if (that->IsUnion()) {
-    UnionHandle unioned = handle(that->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (this->Is(unioned->Get(i))) return true;
+    StructHandle unioned = that->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle that_i = Config::struct_get(unioned, i);
+      if (this->Is(that_i)) return true;
       if (this->IsBitset()) break;  // Fast fail, only first field is a bitset.
     }
     return false;
@@ -341,13 +306,12 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
 
 template<class Config>
 bool TypeImpl<Config>::NowIs(TypeImpl* that) {
-  DisallowHeapAllocation no_allocation;
-
   // TODO(rossberg): this is incorrect for
   //   Union(Constant(V), T)->NowIs(Class(M))
   // but fuzzing does not cover that!
+  DisallowHeapAllocation no_allocation;
   if (this->IsConstant()) {
-    i::Object* object = *this->AsConstant()->Value();
+    i::Object* object = *this->AsConstant();
     if (object->IsHeapObject()) {
       i::Map* map = i::HeapObject::cast(object)->map();
       for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
@@ -362,48 +326,39 @@ bool TypeImpl<Config>::NowIs(TypeImpl* that) {
 // Check this overlaps that.
 template<class Config>
 bool TypeImpl<Config>::Maybe(TypeImpl* that) {
-  DisallowHeapAllocation no_allocation;
-
   // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
   if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->Maybe(that)) return true;
+    StructHandle unioned = this->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle this_i = Config::struct_get(unioned, i);
+      if (this_i->Maybe(that)) return true;
     }
     return false;
   }
 
   // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
   if (that->IsUnion()) {
-    UnionHandle unioned = handle(that->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (this->Maybe(unioned->Get(i))) return true;
+    StructHandle unioned = that->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle that_i = Config::struct_get(unioned, i);
+      if (this->Maybe(that_i)) return true;
     }
     return false;
   }
 
   ASSERT(!this->IsUnion() && !that->IsUnion());
   if (this->IsBitset()) {
-    return BitsetType::IsInhabited(this->AsBitset() & that->BitsetLub());
+    return IsInhabited(this->AsBitset() & that->LubBitset());
   }
   if (that->IsBitset()) {
-    return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset());
+    return IsInhabited(this->LubBitset() & that->AsBitset());
   }
+
   if (this->IsClass()) {
-    return that->IsClass()
-        && *this->AsClass()->Map() == *that->AsClass()->Map();
+    return that->IsClass() && *this->AsClass() == *that->AsClass();
   }
   if (this->IsConstant()) {
-    return that->IsConstant()
-        && *this->AsConstant()->Value() == *that->AsConstant()->Value();
-  }
-  if (this->IsArray()) {
-    // There is no variance!
-    return this->Equals(that);
-  }
-  if (this->IsFunction()) {
-    // There is no variance!
-    return this->Equals(that);
+    return that->IsConstant() && *this->AsConstant() == *that->AsConstant();
   }
 
   return false;
@@ -412,20 +367,19 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
 
 template<class Config>
 bool TypeImpl<Config>::Contains(i::Object* value) {
-  DisallowHeapAllocation no_allocation;
-
   for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
     if (*it.Current() == value) return true;
   }
-  return BitsetType::New(BitsetType::Lub(value))->Is(this);
+  return Config::from_bitset(LubBitset(value))->Is(this);
 }
 
 
 template<class Config>
-bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) {
+bool TypeImpl<Config>::InUnion(StructHandle unioned, int current_size) {
   ASSERT(!this->IsUnion());
   for (int i = 0; i < current_size; ++i) {
-    if (this->Is(unioned->Get(i))) return true;
+    TypeHandle type = Config::struct_get(unioned, i);
+    if (this->Is(type)) return true;
   }
   return false;
 }
@@ -435,24 +389,22 @@ bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) {
 // starting at index. Returns updated index.
 template<class Config>
 int TypeImpl<Config>::ExtendUnion(
-    UnionHandle result, TypeHandle type, int current_size) {
+    StructHandle result, TypeHandle type, int current_size) {
   int old_size = current_size;
-  if (type->IsUnion()) {
-    UnionHandle unioned = handle(type->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      TypeHandle type = unioned->Get(i);
-      ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
+  if (type->IsClass() || type->IsConstant()) {
+    if (!type->InUnion(result, old_size)) {
+      Config::struct_set(result, current_size++, type);
+    }
+  } else if (type->IsUnion()) {
+    StructHandle unioned = type->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle type = Config::struct_get(unioned, i);
+      ASSERT(i == 0 ||
+             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
       if (!type->IsBitset() && !type->InUnion(result, old_size)) {
-        result->Set(current_size++, type);
+        Config::struct_set(result, current_size++, type);
       }
     }
-  } else if (!type->IsBitset()) {
-    // For all structural types, subtyping implies equivalence.
-    ASSERT(type->IsClass() || type->IsConstant() ||
-           type->IsArray() || type->IsFunction());
-    if (!type->InUnion(result, old_size)) {
-      result->Set(current_size++, type);
-    }
   }
   return current_size;
 }
@@ -464,7 +416,7 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
     TypeHandle type1, TypeHandle type2, Region* region) {
   // Fast case: bit sets.
   if (type1->IsBitset() && type2->IsBitset()) {
-    return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
+    return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region);
   }
 
   // Fast case: top or bottom types.
@@ -480,28 +432,28 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
   // Slow case: may need to produce a Unioned object.
   int size = 0;
   if (!type1->IsBitset()) {
-    size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1);
+    size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
-    size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
+    size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
   }
-  int bitset = type1->BitsetGlb() | type2->BitsetGlb();
-  if (bitset != BitsetType::kNone) ++size;
+  int bitset = type1->GlbBitset() | type2->GlbBitset();
+  if (bitset != kNone) ++size;
   ASSERT(size >= 1);
+  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 
-  UnionHandle unioned = UnionType::New(size, region);
   size = 0;
-  if (bitset != BitsetType::kNone) {
-    unioned->Set(size++, BitsetType::New(bitset, region));
+  if (bitset != kNone) {
+    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendUnion(unioned, type1, size);
   size = ExtendUnion(unioned, type2, size);
 
   if (size == 1) {
-    return unioned->Get(0);
+    return Config::struct_get(unioned, 0);
   } else {
-    unioned->Shrink(size);
-    return unioned;
+    Config::struct_shrink(unioned, size);
+    return Config::from_struct(unioned);
   }
 }
 
@@ -510,37 +462,36 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
 // starting at index. Returns updated index.
 template<class Config>
 int TypeImpl<Config>::ExtendIntersection(
-    UnionHandle result, TypeHandle type, TypeHandle other, int current_size) {
+    StructHandle result, TypeHandle type, TypeHandle other, int current_size) {
   int old_size = current_size;
-  if (type->IsUnion()) {
-    UnionHandle unioned = handle(type->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      TypeHandle type = unioned->Get(i);
-      ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
+  if (type->IsClass() || type->IsConstant()) {
+    if (type->Is(other) && !type->InUnion(result, old_size)) {
+      Config::struct_set(result, current_size++, type);
+    }
+  } else if (type->IsUnion()) {
+    StructHandle unioned = type->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle type = Config::struct_get(unioned, i);
+      ASSERT(i == 0 ||
+             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
       if (!type->IsBitset() && type->Is(other) &&
           !type->InUnion(result, old_size)) {
-        result->Set(current_size++, type);
+        Config::struct_set(result, current_size++, type);
       }
     }
-  } else if (!type->IsBitset()) {
-    // For all structural types, subtyping implies equivalence.
-    ASSERT(type->IsClass() || type->IsConstant() ||
-           type->IsArray() || type->IsFunction());
-    if (type->Is(other) && !type->InUnion(result, old_size)) {
-      result->Set(current_size++, type);
-    }
   }
   return current_size;
 }
 
 
 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
+// TODO(rossberg): Should we use object sets somehow? Is it worth it?
 template<class Config>
 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
     TypeHandle type1, TypeHandle type2, Region* region) {
   // Fast case: bit sets.
   if (type1->IsBitset() && type2->IsBitset()) {
-    return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
+    return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region);
   }
 
   // Fast case: top or bottom types.
@@ -556,19 +507,19 @@ 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() : 1);
+    size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
-    size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
+    size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
   }
-  int bitset = type1->BitsetGlb() & type2->BitsetGlb();
-  if (bitset != BitsetType::kNone) ++size;
+  int bitset = type1->GlbBitset() & type2->GlbBitset();
+  if (bitset != kNone) ++size;
   ASSERT(size >= 1);
+  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 
-  UnionHandle unioned = UnionType::New(size, region);
   size = 0;
-  if (bitset != BitsetType::kNone) {
-    unioned->Set(size++, BitsetType::New(bitset, region));
+  if (bitset != kNone) {
+    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendIntersection(unioned, type1, type2, size);
   size = ExtendIntersection(unioned, type2, type1, size);
@@ -576,10 +527,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
   if (size == 0) {
     return None(region);
   } else if (size == 1) {
-    return unioned->Get(0);
+    return Config::struct_get(unioned, 0);
   } else {
-    unioned->Shrink(size);
-    return unioned;
+    Config::struct_shrink(unioned, size);
+    return Config::from_struct(unioned);
   }
 }
 
@@ -589,41 +540,27 @@ template<class OtherType>
 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
     typename OtherType::TypeHandle type, Region* region) {
   if (type->IsBitset()) {
-    return BitsetType::New(type->AsBitset(), region);
+    return Config::from_bitset(type->AsBitset(), region);
   } else if (type->IsClass()) {
-    return ClassType::New(type->AsClass()->Map(), region);
+    return Config::from_class(type->AsClass(), type->LubBitset(), region);
   } else if (type->IsConstant()) {
-    return ConstantType::New(type->AsConstant()->Value(), region);
-  } else if (type->IsUnion()) {
-    int length = type->AsUnion()->Length();
-    UnionHandle unioned = UnionType::New(length, region);
+    return Config::from_constant(type->AsConstant(), type->LubBitset(), region);
+  } else {
+    ASSERT(type->IsUnion());
+    typename OtherType::StructHandle unioned = type->AsUnion();
+    int length = OtherType::StructLength(unioned);
+    StructHandle new_unioned = Config::struct_create(kUnionTag, length, region);
     for (int i = 0; i < length; ++i) {
-      unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
-    }
-    return unioned;
-  } else if (type->IsArray()) {
-    return ArrayType::New(
-        Convert<OtherType>(type->AsArray()->Element(), region), region);
-  } else if (type->IsFunction()) {
-    FunctionHandle function = FunctionType::New(
-        Convert<OtherType>(type->AsFunction()->Result(), region),
-        Convert<OtherType>(type->AsFunction()->Receiver(), region),
-        type->AsFunction()->Arity(), region);
-    for (int i = 0; i < function->Arity(); ++i) {
-      function->InitParameter(i,
-          Convert<OtherType>(type->AsFunction()->Parameter(i), region));
+      Config::struct_set(new_unioned, i,
+          Convert<OtherType>(OtherType::StructGet(unioned, i), region));
     }
-    return function;
-  } else {
-    UNREACHABLE();
-    return None(region);
+    return Config::from_struct(new_unioned);
   }
 }
 
 
 // TODO(rossberg): this does not belong here.
 Representation Representation::FromType(Type* type) {
-  DisallowHeapAllocation no_allocation;
   if (type->Is(Type::None())) return Representation::None();
   if (type->Is(Type::SignedSmall())) return Representation::Smi();
   if (type->Is(Type::Signed32())) return Representation::Integer32();
@@ -641,7 +578,7 @@ void TypeImpl<Config>::TypePrint(PrintDimension dim) {
 
 
 template<class Config>
-const char* TypeImpl<Config>::BitsetType::Name(int bitset) {
+const char* TypeImpl<Config>::bitset_name(int bitset) {
   switch (bitset) {
     case kAny & kRepresentation: return "Any";
     #define PRINT_COMPOSED_TYPE(type, value) \
@@ -661,9 +598,8 @@ const char* TypeImpl<Config>::BitsetType::Name(int bitset) {
 
 
 template<class Config>
-void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) {
-  DisallowHeapAllocation no_allocation;
-  const char* name = Name(bitset);
+void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
+  const char* name = bitset_name(bitset);
   if (name != NULL) {
     PrintF(out, "%s", name);
   } else {
@@ -684,7 +620,7 @@ void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) {
       if ((bitset & subset) == subset) {
         if (!is_first) PrintF(out, " | ");
         is_first = false;
-        PrintF(out, "%s", Name(subset));
+        PrintF(out, "%s", bitset_name(subset));
         bitset -= subset;
       }
     }
@@ -696,58 +632,38 @@ void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) {
 
 template<class Config>
 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
-  DisallowHeapAllocation no_allocation;
   if (this->IsBitset()) {
     int bitset = this->AsBitset();
     switch (dim) {
       case BOTH_DIMS:
-        BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
+        BitsetTypePrint(out, bitset & kSemantic);
         PrintF(out, "/");
-        BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
+        BitsetTypePrint(out, bitset & kRepresentation);
         break;
       case SEMANTIC_DIM:
-        BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
+        BitsetTypePrint(out, bitset & kSemantic);
         break;
       case REPRESENTATION_DIM:
-        BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
+        BitsetTypePrint(out, bitset & kRepresentation);
         break;
     }
   } else if (this->IsConstant()) {
-    PrintF(out, "Constant(%p : ",
-        static_cast<void*>(*this->AsConstant()->Value()));
-    BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
+    PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
+    Config::from_bitset(this->LubBitset())->TypePrint(out, dim);
     PrintF(out, ")");
   } else if (this->IsClass()) {
-    PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map()));
-    BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
+    PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
+    Config::from_bitset(this->LubBitset())->TypePrint(out, dim);
     PrintF(out, ")");
   } else if (this->IsUnion()) {
     PrintF(out, "(");
-    UnionHandle unioned = handle(this->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      TypeHandle type_i = unioned->Get(i);
+    StructHandle unioned = this->AsUnion();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      TypeHandle type_i = Config::struct_get(unioned, i);
       if (i > 0) PrintF(out, " | ");
       type_i->TypePrint(out, dim);
     }
     PrintF(out, ")");
-  } else if (this->IsArray()) {
-    PrintF(out, "[");
-    AsArray()->Element()->TypePrint(out, dim);
-    PrintF(out, "]");
-  } else if (this->IsFunction()) {
-    if (!this->AsFunction()->Receiver()->IsAny()) {
-      this->AsFunction()->Receiver()->TypePrint(out, dim);
-      PrintF(out, ".");
-    }
-    PrintF(out, "(");
-    for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
-      if (i > 0) PrintF(out, ", ");
-      this->AsFunction()->Parameter(i)->TypePrint(out, dim);
-    }
-    PrintF(out, ")->");
-    this->AsFunction()->Result()->TypePrint(out, dim);
-  } else {
-    UNREACHABLE();
   }
 }
 
index 363d45f..3a3bc3b 100644 (file)
@@ -43,11 +43,7 @@ namespace internal {
 //
 //   Class(map) < T   iff instance_type(map) < T
 //   Constant(x) < T  iff instance_type(map(x)) < T
-//   Array(T) < Array
-//   Function(R, S, T0, T1, ...) < Function
 //
-// Both structural Array and Function types are invariant in all parameters.
-// Relaxing this would make Union and Intersect operations more involved.
 // Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
 // change! (Its instance type cannot, however.)
 // TODO(rossberg): the latter is not currently true for proxies, because of fix,
@@ -96,7 +92,7 @@ namespace internal {
 // lattice. That is intentional. It should always be possible to refine the
 // lattice (e.g., splitting up number types further) without invalidating any
 // existing assumptions or tests.
-// Consequently, do not normally use Equals for type tests, always use Is!
+// Consequently, do not use pointer equality for type tests, always use Is!
 //
 // The NowIs operator implements state-sensitive subtying, as described above.
 // Any compilation decision based on such temporary properties requires runtime
@@ -193,17 +189,15 @@ namespace internal {
 
 
 // struct Config {
-//   typedef TypeImpl<Config> Type;
 //   typedef Base;
 //   typedef Struct;
 //   typedef Region;
 //   template<class> struct Handle { typedef type; }  // No template typedefs...
-//   template<class T> static Handle<T>::type handle(T* t);  // !is_bitset(t)
-//   template<class T> static Handle<T>::type cast(Handle<Type>::type);
+//   static Handle<Type>::type handle(Type* type);    // !is_bitset(type)
 //   static bool is_bitset(Type*);
 //   static bool is_class(Type*);
 //   static bool is_constant(Type*);
-//   static bool is_struct(Type*, int tag);
+//   static bool is_struct(Type*);
 //   static int as_bitset(Type*);
 //   static i::Handle<i::Map> as_class(Type*);
 //   static i::Handle<i::Object> as_constant(Type*);
@@ -212,7 +206,7 @@ namespace internal {
 //   static Handle<Type>::type from_bitset(int bitset, Region*);
 //   static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*);
 //   static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
-//   static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
+//   static Handle<Type>::type from_struct(Handle<Struct>::type);
 //   static Handle<Struct>::type struct_create(int tag, int length, Region*);
 //   static void struct_shrink(Handle<Struct>::type, int length);
 //   static int struct_tag(Handle<Struct>::type);
@@ -224,73 +218,36 @@ namespace internal {
 template<class Config>
 class TypeImpl : public Config::Base {
  public:
-  class BitsetType;      // Internal
-  class StructuralType;  // Internal
-  class UnionType;       // Internal
-
-  class ClassType;
-  class ConstantType;
-  class ArrayType;
-  class FunctionType;
-
   typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
-  typedef typename Config::template Handle<ClassType>::type ClassHandle;
-  typedef typename Config::template Handle<ConstantType>::type ConstantHandle;
-  typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
-  typedef typename Config::template Handle<FunctionType>::type FunctionHandle;
-  typedef typename Config::template Handle<UnionType>::type UnionHandle;
   typedef typename Config::Region Region;
 
-  #define DEFINE_TYPE_CONSTRUCTOR(type, value)                                \
-    static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); }  \
-    static TypeHandle type(Region* region) {                                  \
-      return BitsetType::New(BitsetType::k##type, region);                    \
+  #define DEFINE_TYPE_CONSTRUCTOR(type, value)                        \
+    static TypeImpl* type() { return Config::from_bitset(k##type); }  \
+    static TypeHandle type(Region* region) {                          \
+      return Config::from_bitset(k##type, region);                    \
     }
   BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
   #undef DEFINE_TYPE_CONSTRUCTOR
 
   static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
-    return ClassType::New(map, region);
+    return Config::from_class(map, LubBitset(*map), region);
   }
   static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
-    return ConstantType::New(value, region);
-  }
-  static TypeHandle Array(TypeHandle element, Region* region) {
-    return ArrayType::New(element, region);
-  }
-  static FunctionHandle Function(
-      TypeHandle result, TypeHandle receiver, int arity, Region* region) {
-    return FunctionType::New(result, receiver, arity, region);
-  }
-  static TypeHandle Function(TypeHandle result, Region* region) {
-    return Function(result, Any(region), 0, region);
-  }
-  static TypeHandle Function(
-      TypeHandle result, TypeHandle param0, Region* region) {
-    FunctionHandle function = Function(result, Any(region), 1, region);
-    function->InitParameter(0, param0);
-    return function;
-  }
-  static TypeHandle Function(
-      TypeHandle result, TypeHandle param0, TypeHandle param1, Region* region) {
-    FunctionHandle function = Function(result, Any(region), 2, region);
-    function->InitParameter(0, param0);
-    function->InitParameter(1, param1);
-    return function;
+    return Config::from_constant(value, LubBitset(*value), region);
   }
 
   static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
   static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
 
   static TypeHandle Of(i::Object* value, Region* region) {
-    return Config::from_bitset(BitsetType::Lub(value), region);
+    return Config::from_bitset(LubBitset(value), region);
   }
   static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
     return Of(*value, region);
   }
 
   bool IsInhabited() {
-    return !this->IsBitset() || BitsetType::IsInhabited(this->AsBitset());
+    return !this->IsBitset() || IsInhabited(this->AsBitset());
   }
 
   bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
@@ -301,10 +258,6 @@ class TypeImpl : public Config::Base {
   template<class TypeHandle>
   bool Maybe(TypeHandle that) { return this->Maybe(*that); }
 
-  bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
-  template<class TypeHandle>
-  bool Equals(TypeHandle that) { return this->Equals(*that); }
-
   // Equivalent to Constant(value)->Is(this), but avoiding allocation.
   bool Contains(i::Object* val);
   bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
@@ -323,256 +276,127 @@ class TypeImpl : public Config::Base {
 
   bool IsClass() { return Config::is_class(this); }
   bool IsConstant() { return Config::is_constant(this); }
-  bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); }
-  bool IsFunction() {
-    return Config::is_struct(this, StructuralType::kFunctionTag);
-  }
-
-  ClassType* AsClass() { return ClassType::cast(this); }
-  ConstantType* AsConstant() { return ConstantType::cast(this); }
-  ArrayType* AsArray() { return ArrayType::cast(this); }
-  FunctionType* AsFunction() { return FunctionType::cast(this); }
+  i::Handle<i::Map> AsClass() { return Config::as_class(this); }
+  i::Handle<i::Object> AsConstant() { return Config::as_constant(this); }
 
   int NumClasses();
   int NumConstants();
 
-  template<class T> class Iterator;
-  inline Iterator<i::Map> Classes();
-  inline Iterator<i::Object> Constants();
-
-  static inline TypeImpl* cast(typename Config::Base* object);
-
-  template<class OtherTypeImpl>
-  static TypeHandle Convert(
-      typename OtherTypeImpl::TypeHandle type, Region* region);
-
-  enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
-  void TypePrint(PrintDimension = BOTH_DIMS);
-  void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
-
- protected:
-  template<class> friend class Iterator;
-  template<class> friend class TypeImpl;
-
   template<class T>
-  static typename Config::template Handle<T>::type handle(T* type) {
-    return Config::handle(type);
-  }
-
-  bool IsNone() { return this == None(); }
-  bool IsAny() { return this == Any(); }
-  bool IsBitset() { return Config::is_bitset(this); }
-  bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); }
-
-  int AsBitset() {
-    ASSERT(this->IsBitset());
-    return static_cast<BitsetType*>(this)->Bitset();
-  }
-  UnionType* AsUnion() { return UnionType::cast(this); }
-
-  bool SlowIs(TypeImpl* that);
-
-  bool InUnion(UnionHandle unioned, int current_size);
-  static int ExtendUnion(
-      UnionHandle unioned, TypeHandle t, int current_size);
-  static int ExtendIntersection(
-      UnionHandle unioned, TypeHandle t, TypeHandle other, int current_size);
-
-  int BitsetGlb() { return BitsetType::Glb(this); }
-  int BitsetLub() { return BitsetType::Lub(this); }
-};
-
+  class Iterator {
+   public:
+    bool Done() const { return index_ < 0; }
+    i::Handle<T> Current();
+    void Advance();
+
+   private:
+    template<class> friend class TypeImpl;
+
+    Iterator() : index_(-1) {}
+    explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
+      Advance();
+    }
 
-template<class Config>
-class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
- private:
-  friend class TypeImpl<Config>;
+    inline bool matches(TypeHandle type);
+    inline TypeHandle get_type();
 
-  enum {
-    #define DECLARE_TYPE(type, value) k##type = (value),
-    BITSET_TYPE_LIST(DECLARE_TYPE)
-    #undef DECLARE_TYPE
-    kUnusedEOL = 0
+    TypeHandle type_;
+    int index_;
   };
 
-  int Bitset() { return Config::as_bitset(this); }
-
-  static BitsetType* New(int bitset) {
-    return static_cast<BitsetType*>(Config::from_bitset(bitset));
+  Iterator<i::Map> Classes() {
+    if (this->IsBitset()) return Iterator<i::Map>();
+    return Iterator<i::Map>(Config::handle(this));
   }
-  static TypeHandle New(int bitset, Region* region) {
-    return Config::from_bitset(bitset, region);
+  Iterator<i::Object> Constants() {
+    if (this->IsBitset()) return Iterator<i::Object>();
+    return Iterator<i::Object>(Config::handle(this));
   }
 
-  static bool IsInhabited(int bitset) {
-    return (bitset & kRepresentation) && (bitset & kSemantic);
+  static TypeImpl* cast(typename Config::Base* object) {
+    TypeImpl* t = static_cast<TypeImpl*>(object);
+    ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
+    return t;
   }
 
-  static int Glb(TypeImpl* type);  // greatest lower bound that's a bitset
-  static int Lub(TypeImpl* type);  // least upper bound that's a bitset
-  static int Lub(i::Object* value);
-  static int Lub(i::Map* map);
-
-  static const char* Name(int bitset);
-  static void BitsetTypePrint(FILE* out, int bitset);
-};
+  template<class OtherTypeImpl>
+  static TypeHandle Convert(
+      typename OtherTypeImpl::TypeHandle type, Region* region);
 
+  enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
+  void TypePrint(PrintDimension = BOTH_DIMS);
+  void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
 
-// Internal
-// A structured type contains a tag and a variable number of type fields.
-template<class Config>
-class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
- protected:
+ private:
+  template<class> friend class Iterator;
   template<class> friend class TypeImpl;
-  friend struct ZoneTypeConfig;  // For tags.
+  friend struct ZoneTypeConfig;
   friend struct HeapTypeConfig;
 
   enum Tag {
     kClassTag,
     kConstantTag,
-    kArrayTag,
-    kFunctionTag,
     kUnionTag
   };
 
-  int Length() {
-    return Config::struct_length(Config::as_struct(this));
-  }
-  TypeHandle Get(int i) {
-    return Config::struct_get(Config::as_struct(this), i);
-  }
-  void Set(int i, TypeHandle type) {
-    Config::struct_set(Config::as_struct(this), i, type);
-  }
-  void Shrink(int length) {
-    Config::struct_shrink(Config::as_struct(this), length);
-  }
-
-  static TypeHandle New(Tag tag, int length, Region* region) {
-    return Config::from_struct(Config::struct_create(tag, length, region));
-  }
-};
-
-
-template<class Config>
-class TypeImpl<Config>::ClassType : public TypeImpl<Config> {
- public:
-  i::Handle<i::Map> Map() { return Config::as_class(this); }
-
-  static ClassHandle New(i::Handle<i::Map> map, Region* region) {
-    return Config::template cast<ClassType>(
-        Config::from_class(map, BitsetType::Lub(*map), region));
-  }
-
-  static ClassType* cast(TypeImpl* type) {
-    ASSERT(type->IsClass());
-    return static_cast<ClassType*>(type);
-  }
-};
-
-
-template<class Config>
-class TypeImpl<Config>::ConstantType : public TypeImpl<Config> {
- public:
-  i::Handle<i::Object> Value() { return Config::as_constant(this); }
-
-  static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
-    return Config::template cast<ConstantType>(
-        Config::from_constant(value, BitsetType::Lub(*value), region));
-  }
-
-  static ConstantType* cast(TypeImpl* type) {
-    ASSERT(type->IsConstant());
-    return static_cast<ConstantType*>(type);
-  }
-};
+  // A structured type contains a tag an a variable number of type fields.
+  // A union is a structured type with the following invariants:
+  // - its length is at least 2
+  // - at most one field is a bitset, and it must go into index 0
+  // - no field is a union
+  typedef typename Config::Struct Struct;
+  typedef typename Config::template Handle<Struct>::type StructHandle;
 
+  enum {
+    #define DECLARE_TYPE(type, value) k##type = (value),
+    BITSET_TYPE_LIST(DECLARE_TYPE)
+    #undef DECLARE_TYPE
+    kUnusedEOL = 0
+  };
 
-// Internal
-// A union is a structured type with the following invariants:
-// - its length is at least 2
-// - at most one field is a bitset, and it must go into index 0
-// - no field is a union
-template<class Config>
-class TypeImpl<Config>::UnionType : public StructuralType {
- public:
-  static UnionHandle New(int length, Region* region) {
-    return Config::template cast<UnionType>(
-        StructuralType::New(StructuralType::kUnionTag, length, region));
+  bool IsNone() { return this == None(); }
+  bool IsAny() { return this == Any(); }
+  bool IsBitset() { return Config::is_bitset(this); }
+  bool IsStruct(Tag tag) {
+    return Config::is_struct(this)
+        && Config::struct_tag(Config::as_struct(this)) == tag;
   }
+  bool IsUnion() { return IsStruct(kUnionTag); }
 
-  static UnionType* cast(TypeImpl* type) {
-    ASSERT(type->IsUnion());
-    return static_cast<UnionType*>(type);
+  int AsBitset() { return Config::as_bitset(this); }
+  StructHandle AsStruct(Tag tag) {
+    ASSERT(IsStruct(tag));
+    return Config::as_struct(this);
   }
-};
+  StructHandle AsUnion() { return AsStruct(kUnionTag); }
 
-
-template<class Config>
-class TypeImpl<Config>::ArrayType : public StructuralType {
- public:
-  TypeHandle Element() { return this->Get(0); }
-
-  static ArrayHandle New(TypeHandle element, Region* region) {
-    ArrayHandle type = Config::template cast<ArrayType>(
-        StructuralType::New(StructuralType::kArrayTag, 1, region));
-    type->Set(0, element);
-    return type;
+  static int StructLength(StructHandle structured) {
+    return Config::struct_length(structured);
   }
-
-  static ArrayType* cast(TypeImpl* type) {
-    ASSERT(type->IsArray());
-    return static_cast<ArrayType*>(type);
+  static TypeHandle StructGet(StructHandle structured, int i) {
+    return Config::struct_get(structured, i);
   }
-};
-
 
-template<class Config>
-class TypeImpl<Config>::FunctionType : public StructuralType {
- public:
-  int Arity() { return this->Length() - 2; }
-  TypeHandle Result() { return this->Get(0); }
-  TypeHandle Receiver() { return this->Get(1); }
-  TypeHandle Parameter(int i) { return this->Get(2 + i); }
-
-  void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
-
-  static FunctionHandle New(
-      TypeHandle result, TypeHandle receiver, int arity, Region* region) {
-    FunctionHandle type = Config::template cast<FunctionType>(
-        StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
-    type->Set(0, result);
-    type->Set(1, receiver);
-    return type;
-  }
+  bool SlowIs(TypeImpl* that);
 
-  static FunctionType* cast(TypeImpl* type) {
-    ASSERT(type->IsFunction());
-    return static_cast<FunctionType*>(type);
+  static bool IsInhabited(int bitset) {
+    return (bitset & kRepresentation) && (bitset & kSemantic);
   }
-};
 
+  int LubBitset();  // least upper bound that's a bitset
+  int GlbBitset();  // greatest lower bound that's a bitset
 
-template<class Config> template<class T>
-class TypeImpl<Config>::Iterator {
- public:
-  bool Done() const { return index_ < 0; }
-  i::Handle<T> Current();
-  void Advance();
+  static int LubBitset(i::Object* value);
+  static int LubBitset(i::Map* map);
 
- private:
-  template<class> friend class TypeImpl;
-
-  Iterator() : index_(-1) {}
-  explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
-    Advance();
-  }
-
-  inline bool matches(TypeHandle type);
-  inline TypeHandle get_type();
+  bool InUnion(StructHandle unioned, int current_size);
+  static int ExtendUnion(
+      StructHandle unioned, TypeHandle t, int current_size);
+  static int ExtendIntersection(
+      StructHandle unioned, TypeHandle t, TypeHandle other, int current_size);
 
-  TypeHandle type_;
-  int index_;
+  static const char* bitset_name(int bitset);
+  static void BitsetTypePrint(FILE* out, int bitset);
 };
 
 
@@ -585,33 +409,27 @@ struct ZoneTypeConfig {
   typedef i::Zone Region;
   template<class T> struct Handle { typedef T* type; };
 
-  template<class T> static inline T* handle(T* type);
-  template<class T> static inline T* cast(Type* type);
-
+  static inline Type* handle(Type* type);
   static inline bool is_bitset(Type* type);
   static inline bool is_class(Type* type);
   static inline bool is_constant(Type* type);
-  static inline bool is_struct(Type* type, int tag);
-
+  static inline bool is_struct(Type* type);
   static inline int as_bitset(Type* type);
   static inline Struct* as_struct(Type* type);
   static inline i::Handle<i::Map> as_class(Type* type);
   static inline i::Handle<i::Object> as_constant(Type* type);
-
   static inline Type* from_bitset(int bitset);
   static inline Type* from_bitset(int bitset, Zone* zone);
   static inline Type* from_struct(Struct* structured);
   static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
   static inline Type* from_constant(
       i::Handle<i::Object> value, int lub, Zone* zone);
-
   static inline Struct* struct_create(int tag, int length, Zone* zone);
   static inline void struct_shrink(Struct* structured, int length);
   static inline int struct_tag(Struct* structured);
   static inline int struct_length(Struct* structured);
   static inline Type* struct_get(Struct* structured, int i);
   static inline void struct_set(Struct* structured, int i, Type* type);
-
   static inline int lub_bitset(Type* type);
 };
 
@@ -627,19 +445,15 @@ struct HeapTypeConfig {
   typedef i::Isolate Region;
   template<class T> struct Handle { typedef i::Handle<T> type; };
 
-  template<class T> static inline i::Handle<T> handle(T* type);
-  template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
-
+  static inline i::Handle<Type> handle(Type* type);
   static inline bool is_bitset(Type* type);
   static inline bool is_class(Type* type);
   static inline bool is_constant(Type* type);
-  static inline bool is_struct(Type* type, int tag);
-
+  static inline bool is_struct(Type* type);
   static inline int as_bitset(Type* type);
   static inline i::Handle<i::Map> as_class(Type* type);
   static inline i::Handle<i::Object> as_constant(Type* type);
   static inline i::Handle<Struct> as_struct(Type* type);
-
   static inline Type* from_bitset(int bitset);
   static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
   static inline i::Handle<Type> from_class(
@@ -647,7 +461,6 @@ struct HeapTypeConfig {
   static inline i::Handle<Type> from_constant(
       i::Handle<i::Object> value, int lub, Isolate* isolate);
   static inline i::Handle<Type> from_struct(i::Handle<Struct> structured);
-
   static inline i::Handle<Struct> struct_create(
       int tag, int length, Isolate* isolate);
   static inline void struct_shrink(i::Handle<Struct> structured, int length);
@@ -656,7 +469,6 @@ struct HeapTypeConfig {
   static inline i::Handle<Type> struct_get(i::Handle<Struct> structured, int i);
   static inline void struct_set(
       i::Handle<Struct> structured, int i, i::Handle<Type> type);
-
   static inline int lub_bitset(Type* type);
 };
 
index 0981114..88e7f38 100644 (file)
@@ -496,8 +496,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = descriptors->GetFieldType(descriptor);
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, field_type->AsClass()->Map(),
-                  miss_label, DO_SMI_CHECK);
+      __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
       __ JumpIfSmi(value_reg, miss_label);
@@ -647,8 +646,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
   } else if (representation.IsHeapObject()) {
     HeapType* field_type = lookup->GetFieldType();
     if (field_type->IsClass()) {
-      __ CheckMap(value_reg, field_type->AsClass()->Map(),
-                  miss_label, DO_SMI_CHECK);
+      __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
     } else {
       ASSERT(HeapType::Any()->Is(field_type));
       __ JumpIfSmi(value_reg, miss_label);
@@ -755,9 +753,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
   int depth = 0;
 
   Handle<JSObject> current = Handle<JSObject>::null();
-  if (type->IsConstant()) {
-    current = Handle<JSObject>::cast(type->AsConstant()->Value());
-  }
+  if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
   Handle<JSObject> prototype = Handle<JSObject>::null();
   Handle<Map> current_map = receiver_map;
   Handle<Map> holder_map(holder->map());
index 59a8f08..62ec698 100644 (file)
@@ -43,9 +43,7 @@ struct ZoneRep {
   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
   static bool IsClass(Type* t) { return IsStruct(t, 0); }
   static bool IsConstant(Type* t) { return IsStruct(t, 1); }
-  static bool IsArray(Type* t) { return IsStruct(t, 2); }
-  static bool IsFunction(Type* t) { return IsStruct(t, 3); }
-  static bool IsUnion(Type* t) { return IsStruct(t, 4); }
+  static bool IsUnion(Type* t) { return IsStruct(t, 2); }
 
   static Struct* AsStruct(Type* t) {
     return reinterpret_cast<Struct*>(t);
@@ -79,9 +77,7 @@ struct HeapRep {
   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
   static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
   static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
-  static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 2); }
-  static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 3); }
-  static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 4); }
+  static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 2); }
 
   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
   static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
@@ -143,31 +139,11 @@ class Types {
       types.push_back(Type::Constant(*it, region));
     }
 
-    FloatArray = Type::Array(Float, region);
-    StringArray = Type::Array(String, region);
-    AnyArray = Type::Array(Any, region);
-
-    SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
-    NumberFunction1 = Type::Function(Number, Number, region);
-    NumberFunction2 = Type::Function(Number, Number, Number, region);
-    MethodFunction = Type::Function(String, Object, 0, region);
-
     for (int i = 0; i < 50; ++i) {
       types.push_back(Fuzz());
     }
   }
 
-  Handle<i::Map> object_map;
-  Handle<i::Map> array_map;
-  Handle<i::Map> uninitialized_map;
-
-  Handle<i::Smi> smi;
-  Handle<i::HeapNumber> signed32;
-  Handle<i::JSObject> object1;
-  Handle<i::JSObject> object2;
-  Handle<i::JSArray> array;
-  Handle<i::Oddball> uninitialized;
-
   #define DECLARE_TYPE(name, value) TypeHandle name;
   BITSET_TYPE_LIST(DECLARE_TYPE)
   #undef DECLARE_TYPE
@@ -183,14 +159,16 @@ class Types {
   TypeHandle ArrayConstant;
   TypeHandle UninitializedConstant;
 
-  TypeHandle FloatArray;
-  TypeHandle StringArray;
-  TypeHandle AnyArray;
+  Handle<i::Map> object_map;
+  Handle<i::Map> array_map;
+  Handle<i::Map> uninitialized_map;
 
-  TypeHandle SignedFunction1;
-  TypeHandle NumberFunction1;
-  TypeHandle NumberFunction2;
-  TypeHandle MethodFunction;
+  Handle<i::Smi> smi;
+  Handle<i::HeapNumber> signed32;
+  Handle<i::JSObject> object1;
+  Handle<i::JSObject> object2;
+  Handle<i::JSArray> array;
+  Handle<i::Oddball> uninitialized;
 
   typedef std::vector<TypeHandle> TypeVector;
   typedef std::vector<Handle<i::Map> > MapVector;
@@ -215,24 +193,6 @@ class Types {
     return Type::Class(map, region_);
   }
 
-  TypeHandle Array1(TypeHandle element) {
-    return Type::Array(element, region_);
-  }
-
-  TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
-    return Type::Function(result, receiver, 0, region_);
-  }
-
-  TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
-    TypeHandle type = Type::Function(result, receiver, 1, region_);
-    type->AsFunction()->InitParameter(0, arg);
-    return type;
-  }
-
-  TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
-    return Type::Function(result, arg1, arg2, region_);
-  }
-
   TypeHandle Union(TypeHandle t1, TypeHandle t2) {
     return Type::Union(t1, t2, region_);
   }
@@ -245,10 +205,6 @@ class Types {
     return Type::template Convert<Type2>(t, region_);
   }
 
-  TypeHandle Random() {
-    return types[rng_.NextInt(static_cast<int>(types.size()))];
-  }
-
   TypeHandle Fuzz(int depth = 5) {
     switch (rng_.NextInt(depth == 0 ? 3 : 20)) {
       case 0: {  // bitset
@@ -272,17 +228,6 @@ class Types {
         int i = rng_.NextInt(static_cast<int>(values.size()));
         return Type::Constant(values[i], region_);
       }
-      case 3:  // array
-        return Type::Array(Fuzz(depth / 2), region_);
-      case 4:
-      case 5:
-      case 6: {  // function
-        TypeHandle type = Type::Function(
-            Fuzz(depth / 2), Fuzz(depth / 2), rand() % 3, region_);
-        for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
-          type->AsFunction()->InitParameter(i, Fuzz(depth - 1));
-        }
-      }
       default: {  // union
         int n = rng_.NextInt(10);
         TypeHandle type = None;
@@ -461,7 +406,7 @@ struct Tests : Rep {
     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
       Handle<i::Map> map = *mt;
       TypeHandle type = T.Class(map);
-      CHECK(*map == *type->AsClass()->Map());
+      CHECK(*map == *type->AsClass());
     }
 
     // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
@@ -488,10 +433,10 @@ struct Tests : Rep {
     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
       Handle<i::Object> value = *vt;
       TypeHandle type = T.Constant(value);
-      CHECK(*value == *type->AsConstant()->Value());
+      CHECK(*value == *type->AsConstant());
     }
 
-    // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
+    // Functionality & Injectivity: Constant(V1) = Constant(v2) iff V1 = V2
     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
         Handle<i::Object> value1 = *vt1;
@@ -503,102 +448,6 @@ struct Tests : Rep {
     }
   }
 
-  void Array() {
-    // Constructor
-    for (int i = 0; i < 20; ++i) {
-      TypeHandle type = T.Random();
-      TypeHandle array = T.Array1(type);
-      CHECK(this->IsArray(array));
-    }
-
-    // Attributes
-    for (int i = 0; i < 20; ++i) {
-      TypeHandle type = T.Random();
-      TypeHandle array = T.Array1(type);
-      CheckEqual(type, array->AsArray()->Element());
-    }
-
-    // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
-    for (int i = 0; i < 20; ++i) {
-      for (int j = 0; j < 20; ++j) {
-        TypeHandle type1 = T.Random();
-        TypeHandle type2 = T.Random();
-        TypeHandle array1 = T.Array1(type1);
-        TypeHandle array2 = T.Array1(type2);
-        CHECK(Equal(array1, array2) == Equal(type1, type2));
-      }
-    }
-  }
-
-  void Function() {
-    // Constructors
-    for (int i = 0; i < 20; ++i) {
-      for (int j = 0; j < 20; ++j) {
-        for (int k = 0; k < 20; ++k) {
-          TypeHandle type1 = T.Random();
-          TypeHandle type2 = T.Random();
-          TypeHandle type3 = T.Random();
-          TypeHandle function0 = T.Function0(type1, type2);
-          TypeHandle function1 = T.Function1(type1, type2, type3);
-          TypeHandle function2 = T.Function2(type1, type2, type3);
-          CHECK(function0->IsFunction());
-          CHECK(function1->IsFunction());
-          CHECK(function2->IsFunction());
-        }
-      }
-    }
-
-    // Attributes
-    for (int i = 0; i < 20; ++i) {
-      for (int j = 0; j < 20; ++j) {
-        for (int k = 0; k < 20; ++k) {
-          TypeHandle type1 = T.Random();
-          TypeHandle type2 = T.Random();
-          TypeHandle type3 = T.Random();
-          TypeHandle function0 = T.Function0(type1, type2);
-          TypeHandle function1 = T.Function1(type1, type2, type3);
-          TypeHandle function2 = T.Function2(type1, type2, type3);
-          CHECK_EQ(0, function0->AsFunction()->Arity());
-          CHECK_EQ(1, function1->AsFunction()->Arity());
-          CHECK_EQ(2, function2->AsFunction()->Arity());
-          CheckEqual(type1, function0->AsFunction()->Result());
-          CheckEqual(type1, function1->AsFunction()->Result());
-          CheckEqual(type1, function2->AsFunction()->Result());
-          CheckEqual(type2, function0->AsFunction()->Receiver());
-          CheckEqual(type2, function1->AsFunction()->Receiver());
-          CheckEqual(T.Any, function2->AsFunction()->Receiver());
-          CheckEqual(type3, function1->AsFunction()->Parameter(0));
-          CheckEqual(type2, function2->AsFunction()->Parameter(0));
-          CheckEqual(type3, function2->AsFunction()->Parameter(1));
-        }
-      }
-    }
-
-    // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
-    for (int i = 0; i < 20; ++i) {
-      for (int j = 0; j < 20; ++j) {
-        for (int k = 0; k < 20; ++k) {
-          TypeHandle type1 = T.Random();
-          TypeHandle type2 = T.Random();
-          TypeHandle type3 = T.Random();
-          TypeHandle function01 = T.Function0(type1, type2);
-          TypeHandle function02 = T.Function0(type1, type3);
-          TypeHandle function03 = T.Function0(type3, type2);
-          TypeHandle function11 = T.Function1(type1, type2, type2);
-          TypeHandle function12 = T.Function1(type1, type2, type3);
-          TypeHandle function21 = T.Function2(type1, type2, type2);
-          TypeHandle function22 = T.Function2(type1, type2, type3);
-          TypeHandle function23 = T.Function2(type1, type3, type2);
-          CHECK(Equal(function01, function02) == Equal(type2, type3));
-          CHECK(Equal(function01, function03) == Equal(type1, type3));
-          CHECK(Equal(function11, function12) == Equal(type2, type3));
-          CHECK(Equal(function21, function22) == Equal(type2, type3));
-          CHECK(Equal(function21, function23) == Equal(type2, type3));
-        }
-      }
-    }
-  }
-
   void Of() {
     // Constant(V)->Is(Of(V))
     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
@@ -792,7 +641,6 @@ struct Tests : Rep {
     // Structural types
     CheckSub(T.ObjectClass, T.Object);
     CheckSub(T.ArrayClass, T.Object);
-    CheckSub(T.ArrayClass, T.Array);
     CheckSub(T.UninitializedClass, T.Internal);
     CheckUnordered(T.ObjectClass, T.ArrayClass);
     CheckUnordered(T.UninitializedClass, T.Null);
@@ -816,15 +664,6 @@ struct Tests : Rep {
     CheckUnordered(T.ObjectConstant1, T.ArrayClass);
     CheckUnordered(T.ObjectConstant2, T.ArrayClass);
     CheckUnordered(T.ArrayConstant, T.ObjectClass);
-
-    CheckSub(T.FloatArray, T.Array);
-    CheckSub(T.FloatArray, T.Object);
-    CheckUnordered(T.StringArray, T.AnyArray);
-
-    CheckSub(T.MethodFunction, T.Function);
-    CheckSub(T.NumberFunction1, T.Object);
-    CheckUnordered(T.SignedFunction1, T.NumberFunction1);
-    CheckUnordered(T.NumberFunction1, T.NumberFunction2);
   }
 
   void NowIs() {
@@ -1153,19 +992,9 @@ struct Tests : Rep {
     CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
     CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
     CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic);
-
-    CheckOverlap(T.FloatArray, T.Array, T.Semantic);
-    CheckDisjoint(T.FloatArray, T.AnyArray, T.Semantic);
-    CheckDisjoint(T.FloatArray, T.StringArray, T.Semantic);
-
-    CheckOverlap(T.MethodFunction, T.Function, T.Semantic);
-    CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic);
-    CheckDisjoint(T.SignedFunction1, T.NumberFunction2, T.Semantic);
-    CheckDisjoint(T.NumberFunction1, T.NumberFunction2, T.Semantic);
-    CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic);
   }
 
-  void Union1() {
+  void Union() {
     // Identity: Union(T, None) = T
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
       TypeHandle type = *it;
@@ -1234,9 +1063,7 @@ struct Tests : Rep {
         if (type1->Is(type2)) CheckEqual(union12, type2);
       }
     }
-  }
 
-  void Union2() {
     // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1295,28 +1122,6 @@ struct Tests : Rep {
     CheckDisjoint(
         T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic);
 
-    // Bitset-array
-    CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
-    CHECK(this->IsUnion(T.Union(T.FloatArray, T.Number)));
-
-    CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
-    CheckSub(T.None, T.Union(T.FloatArray, T.Number));
-    CheckSub(T.Union(T.FloatArray, T.Number), T.Any);
-    CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
-    CheckOverlap(T.Union(T.FloatArray, T.String), T.Object, T.Semantic);
-    CheckDisjoint(T.Union(T.FloatArray, T.String), T.Number, T.Semantic);
-
-    // Bitset-function
-    CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
-    CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
-
-    CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
-    CheckSub(T.None, T.Union(T.MethodFunction, T.Number));
-    CheckSub(T.Union(T.MethodFunction, T.Number), T.Any);
-    CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
-    CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic);
-    CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic);
-
     // Bitset-class
     CheckSub(
         T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
@@ -1372,18 +1177,6 @@ struct Tests : Rep {
         T.Union(
             T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
 
-    // Array-union
-    CheckEqual(
-        T.Union(T.AnyArray, T.Union(T.FloatArray, T.AnyArray)),
-        T.Union(T.AnyArray, T.FloatArray));
-    CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Array);
-
-    // Function-union
-    CheckEqual(
-        T.Union(T.NumberFunction1, T.NumberFunction2),
-        T.Union(T.NumberFunction2, T.NumberFunction1));
-    CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
-
     // Union-union
     CheckEqual(
         T.Union(
@@ -1397,7 +1190,7 @@ struct Tests : Rep {
         T.Union(T.Number, T.Array));
   }
 
-  void Intersect1() {
+  void Intersect() {
     // Identity: Intersect(T, Any) = T
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
       TypeHandle type = *it;
@@ -1467,9 +1260,7 @@ struct Tests : Rep {
         if (type1->Is(type2)) CheckEqual(intersect12, type1);
       }
     }
-  }
 
-  void Intersect2() {
     // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1517,13 +1308,9 @@ struct Tests : Rep {
     CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
     CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
 
-    // Bitset-array
-    CheckEqual(T.Intersect(T.FloatArray, T.Object), T.FloatArray);
-    CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation);
-
-    // Bitset-function
-    CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
-    CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation);
+    // Class-constant
+    CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
+    CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
 
     // Bitset-union
     CheckEqual(
@@ -1533,32 +1320,6 @@ struct Tests : Rep {
         T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
         T.None);
 
-    // Class-constant
-    CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
-    CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
-
-    // Array-union
-    CheckEqual(
-        T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)),
-        T.FloatArray);
-    CheckEqual(
-        T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
-        T.AnyArray);
-    CheckEqual(
-        T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray),
-        T.None);
-
-    // Function-union
-    CheckEqual(
-        T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
-        T.MethodFunction);
-    CheckEqual(
-        T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
-        T.NumberFunction1);
-    CheckEqual(
-        T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2),
-        T.None);
-
     // Class-union
     CheckEqual(
         T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
@@ -1626,41 +1387,27 @@ typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
 
 
-TEST(BitsetType) {
+TEST(Bitset) {
   CcTest::InitializeVM();
   ZoneTests().Bitset();
   HeapTests().Bitset();
 }
 
 
-TEST(ClassType) {
+TEST(Class) {
   CcTest::InitializeVM();
   ZoneTests().Class();
   HeapTests().Class();
 }
 
 
-TEST(ConstantType) {
+TEST(Constant) {
   CcTest::InitializeVM();
   ZoneTests().Constant();
   HeapTests().Constant();
 }
 
 
-TEST(ArrayType) {
-  CcTest::InitializeVM();
-  ZoneTests().Array();
-  HeapTests().Array();
-}
-
-
-TEST(FunctionType) {
-  CcTest::InitializeVM();
-  ZoneTests().Function();
-  HeapTests().Function();
-}
-
-
 TEST(Of) {
   CcTest::InitializeVM();
   ZoneTests().Of();
@@ -1710,31 +1457,17 @@ TEST(Maybe) {
 }
 
 
-TEST(Union1) {
-  CcTest::InitializeVM();
-  ZoneTests().Union1();
-  HeapTests().Union1();
-}
-
-
-TEST(Union2) {
-  CcTest::InitializeVM();
-  ZoneTests().Union2();
-  HeapTests().Union2();
-}
-
-
-TEST(Intersect1) {
+TEST(Union) {
   CcTest::InitializeVM();
-  ZoneTests().Intersect1();
-  HeapTests().Intersect1();
+  ZoneTests().Union();
+  HeapTests().Union();
 }
 
 
-TEST(Intersect2) {
+TEST(Intersect) {
   CcTest::InitializeVM();
-  ZoneTests().Intersect2();
-  HeapTests().Intersect2();
+  ZoneTests().Intersect();
+  HeapTests().Intersect();
 }