Retry "Templatise type representation" after making clang happy
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 10 Jan 2014 12:19:01 +0000 (12:19 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 10 Jan 2014 12:19:01 +0000 (12:19 +0000)
The only thing different now is line types.h:208/236, which had a static_cast<Type*> before.

R=mstarzinger@chromium.org
BUG=

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

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

17 files changed:
src/ast.cc
src/ast.h
src/code-stubs-hydrogen.cc
src/code-stubs.cc
src/hydrogen.cc
src/ic.cc
src/ic.h
src/list.h
src/objects.cc
src/objects.h
src/property-details.h
src/stub-cache.cc
src/type-info.cc
src/types.cc
src/types.h
src/typing.cc
test/cctest/test-types.cc

index 21ea50bf1d0b9dcf82d725c35a92f2bd3df92c30..6c0ef7c5a4784f67c334e91dd36d620fd5e7e1eb 100644 (file)
@@ -1141,7 +1141,7 @@ CaseClause::CaseClause(Isolate* isolate,
     : Expression(isolate, pos),
       label_(label),
       statements_(statements),
-      compare_type_(Type::None(), isolate),
+      compare_type_(Type::None(isolate)),
       compare_id_(AstNode::GetNextId(isolate)),
       entry_id_(AstNode::GetNextId(isolate)) {
 }
index 64a56e9df0f767c97948e7d2b134f9b5a914dc62..97ef4ff5b74101a2169f6f9d963a868ae6462ad3 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -2068,7 +2068,7 @@ class CompareOperation V8_FINAL : public Expression {
         op_(op),
         left_(left),
         right_(right),
-        combined_type_(Type::None(), isolate) {
+        combined_type_(Type::None(isolate)) {
     ASSERT(Token::IsCompareOp(op));
   }
 
index 783384d45285f3e5325038a34ea6d3705e45042e..67f9dc8fd7361ba02a70b469a3d18d6cebf00ec1 100644 (file)
@@ -323,7 +323,7 @@ template <>
 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
   info()->MarkAsSavesCallerDoubles();
   HValue* number = GetParameter(NumberToStringStub::kNumber);
-  return BuildNumberToString(number, handle(Type::Number(), isolate()));
+  return BuildNumberToString(number, Type::Number(isolate()));
 }
 
 
@@ -896,7 +896,7 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
       {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
-                    handle(Type::String(), isolate()), right_type,
+                    Type::String(isolate()), right_type,
                     result_type, state.fixed_right_arg(),
                     allocation_mode));
       }
@@ -916,7 +916,7 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
       {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
-                    left_type, handle(Type::String(), isolate()),
+                    left_type, Type::String(isolate()),
                     result_type, state.fixed_right_arg(),
                     allocation_mode));
       }
index d27a458fa41313e26e806f11c3c350269f7c0535..f524bb6bfbddb5d95db67d7af157ef216440639e 100644 (file)
@@ -480,21 +480,20 @@ Handle<Type> CompareNilICStub::GetType(
     Isolate* isolate,
     Handle<Map> map) {
   if (state_.Contains(CompareNilICStub::GENERIC)) {
-    return handle(Type::Any(), isolate);
+    return Type::Any(isolate);
   }
 
-  Handle<Type> result(Type::None(), isolate);
+  Handle<Type> result = Type::None(isolate);
   if (state_.Contains(CompareNilICStub::UNDEFINED)) {
-    result = handle(Type::Union(result, handle(Type::Undefined(), isolate)),
-                    isolate);
+    result = Type::Union(result, Type::Undefined(isolate), isolate);
   }
   if (state_.Contains(CompareNilICStub::NULL_TYPE)) {
-    result = handle(Type::Union(result, handle(Type::Null(), isolate)),
-                    isolate);
+    result = Type::Union(result, Type::Null(isolate), isolate);
   }
   if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
-    Type* type = map.is_null() ? Type::Detectable() : Type::Class(map);
-    result = handle(Type::Union(result, handle(type, isolate)), isolate);
+    Handle<Type> type = map.is_null()
+        ? Type::Detectable(isolate) : Type::Class(map, isolate);
+    result = Type::Union(result, type, isolate);
   }
 
   return result;
@@ -505,9 +504,9 @@ Handle<Type> CompareNilICStub::GetInputType(
     Isolate* isolate,
     Handle<Map> map) {
   Handle<Type> output_type = GetType(isolate, map);
-  Handle<Type> nil_type = handle(nil_value_ == kNullValue
-      ? Type::Null() : Type::Undefined(), isolate);
-  return handle(Type::Union(output_type, nil_type), isolate);
+  Handle<Type> nil_type = nil_value_ == kNullValue
+      ? Type::Null(isolate) : Type::Undefined(isolate);
+  return Type::Union(output_type, nil_type, isolate);
 }
 
 
index 0dfcca67cc456e23e04e70192b19957e18a94e33..7c6b2cbf0da4a4ffa9cac432504bdb0f1d7e480d 100644 (file)
@@ -8772,7 +8772,7 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
     HConstant* constant = HConstant::cast(value);
     Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
     if (number.has_value) {
-      *expected = handle(Type::Number(), isolate());
+      *expected = Type::Number(isolate());
       return AddInstruction(number.value);
     }
   }
@@ -8785,10 +8785,10 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
   Handle<Type> expected_type = *expected;
 
   // Separate the number type from the rest.
-  Handle<Type> expected_obj = handle(Type::Intersect(
-      expected_type, handle(Type::NonNumber(), isolate())), isolate());
-  Handle<Type> expected_number = handle(Type::Intersect(
-      expected_type, handle(Type::Number(), isolate())), isolate());
+  Handle<Type> expected_obj = Type::Intersect(
+      expected_type, Type::NonNumber(isolate()), isolate());
+  Handle<Type> expected_number = Type::Intersect(
+      expected_type, Type::Number(isolate()), isolate());
 
   // We expect to get a number.
   // (We need to check first, since Type::None->Is(Type::Any()) == true.
@@ -8799,8 +8799,8 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
 
   if (expected_obj->Is(Type::Undefined())) {
     // This is already done by HChange.
-    *expected = handle(Type::Union(
-          expected_number, handle(Type::Double(), isolate())), isolate());
+    *expected = Type::Union(
+          expected_number, Type::Double(isolate()), isolate());
     return value;
   }
 
@@ -8862,7 +8862,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
                      Deoptimizer::SOFT);
     // TODO(rossberg): we should be able to get rid of non-continuous
     // defaults.
-    left_type = handle(Type::Any(), isolate());
+    left_type = Type::Any(isolate());
   } else {
     if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
     left_rep = Representation::FromType(left_type);
@@ -8871,7 +8871,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
   if (right_type->Is(Type::None())) {
     Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
                      Deoptimizer::SOFT);
-    right_type = handle(Type::Any(), isolate());
+    right_type = Type::Any(isolate());
   } else {
     if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
     right_rep = Representation::FromType(right_type);
@@ -9369,7 +9369,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
     Add<HDeoptimize>("Insufficient type feedback for combined type "
                      "of binary operation",
                      Deoptimizer::SOFT);
-    combined_type = left_type = right_type = handle(Type::Any(), isolate());
+    combined_type = left_type = right_type = Type::Any(isolate());
   }
 
   Representation left_rep = Representation::FromType(left_type);
@@ -9466,8 +9466,7 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
   } else {
     ASSERT_EQ(Token::EQ, expr->op());
     Handle<Type> type = expr->combined_type()->Is(Type::None())
-        ? handle(Type::Any(), isolate_)
-        : expr->combined_type();
+        ? Type::Any(isolate_) : expr->combined_type();
     HIfContinuation continuation;
     BuildCompareNil(value, type, &continuation);
     return ast_context()->ReturnContinuation(&continuation, expr->id());
@@ -10236,8 +10235,7 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
   ASSERT_EQ(1, call->arguments()->length());
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* number = Pop();
-  HValue* result = BuildNumberToString(
-      number, handle(Type::Number(), isolate()));
+  HValue* result = BuildNumberToString(number, Type::Number(isolate()));
   return ast_context()->ReturnValue(result);
 }
 
index 8e5f0ae6b2e6c467da242cdcfe1d2337bce0f26f..23697a9c98d1093b545a78e7660b823bccc9bd5c 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -997,10 +997,9 @@ bool IC::UpdatePolymorphicIC(Handle<Type> type,
 
 
 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
-  Type* type = object->IsJSGlobalObject()
-      ? Type::Constant(Handle<JSGlobalObject>::cast(object))
-      : Type::OfCurrently(object);
-  return handle(type, isolate);
+  return object->IsJSGlobalObject()
+      ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate)
+      : Type::OfCurrently(object, isolate);
 }
 
 
@@ -1015,11 +1014,12 @@ Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) {
 }
 
 
-Type* IC::MapToType(Handle<Map> map) {
-  if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number();
+Handle<Type> IC::MapToType(Handle<Map> map) {
+  Isolate* isolate = map->GetIsolate();
+  if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate);
   // The only oddballs that can be recorded in ICs are booleans.
-  if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean();
-  return Type::Class(map);
+  if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate);
+  return Type::Class(map, isolate);
 }
 
 
@@ -1044,7 +1044,7 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
 }
 
 
-bool IC::IsTransitionOfMonomorphicTarget(Type* type) {
+bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) {
   if (!type->IsClass()) return false;
   Map* receiver_map = *type->AsClass();
   Map* current_map = target()->FindFirstMap();
@@ -1076,7 +1076,7 @@ void IC::PatchCache(Handle<Type> type,
              target()->is_keyed_call_stub() ||
              !target().is_identical_to(code));
       Code* old_handler = target()->FindFirstHandler();
-      if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) {
+      if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
         UpdateMonomorphicIC(type, code, name);
         break;
       }
@@ -2620,10 +2620,9 @@ Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const {
   if (HasSideEffects()) {
     result_kind = NONE;
   } else if (result_kind == GENERIC && op_ == Token::ADD) {
-    return handle(Type::Union(handle(Type::Number(), isolate),
-                              handle(Type::String(), isolate)), isolate);
+    return Type::Union(Type::Number(isolate), Type::String(isolate), isolate);
   } else if (result_kind == NUMBER && op_ == Token::SHR) {
-    return handle(Type::Unsigned32(), isolate);
+    return Type::Unsigned32(isolate);
   }
   ASSERT_NE(GENERIC, result_kind);
   return KindToType(result_kind, isolate);
@@ -2758,16 +2757,16 @@ const char* BinaryOpIC::State::KindToString(Kind kind) {
 
 // static
 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) {
-  Type* type = NULL;
   switch (kind) {
-    case NONE: type = Type::None(); break;
-    case SMI: type = Type::Smi(); break;
-    case INT32: type = Type::Signed32(); break;
-    case NUMBER: type = Type::Number(); break;
-    case STRING: type = Type::String(); break;
-    case GENERIC: type = Type::Any(); break;
+    case NONE: return Type::None(isolate);
+    case SMI: return Type::Smi(isolate);
+    case INT32: return Type::Signed32(isolate);
+    case NUMBER: return Type::Number(isolate);
+    case STRING: return Type::String(isolate);
+    case GENERIC: return Type::Any(isolate);
   }
-  return handle(type, isolate);
+  UNREACHABLE();
+  return Handle<Type>();
 }
 
 
@@ -2902,25 +2901,18 @@ Handle<Type> CompareIC::StateToType(
     CompareIC::State state,
     Handle<Map> map) {
   switch (state) {
-    case CompareIC::UNINITIALIZED:
-      return handle(Type::None(), isolate);
-    case CompareIC::SMI:
-      return handle(Type::Smi(), isolate);
-    case CompareIC::NUMBER:
-      return handle(Type::Number(), isolate);
-    case CompareIC::STRING:
-      return handle(Type::String(), isolate);
+    case CompareIC::UNINITIALIZED: return Type::None(isolate);
+    case CompareIC::SMI: return Type::Smi(isolate);
+    case CompareIC::NUMBER: return Type::Number(isolate);
+    case CompareIC::STRING: return Type::String(isolate);
     case CompareIC::INTERNALIZED_STRING:
-      return handle(Type::InternalizedString(), isolate);
-    case CompareIC::UNIQUE_NAME:
-      return handle(Type::UniqueName(), isolate);
-    case CompareIC::OBJECT:
-      return handle(Type::Receiver(), isolate);
+      return Type::InternalizedString(isolate);
+    case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate);
+    case CompareIC::OBJECT: return Type::Receiver(isolate);
     case CompareIC::KNOWN_OBJECT:
-      return handle(
-          map.is_null() ? Type::Receiver() : Type::Class(map), isolate);
-    case CompareIC::GENERIC:
-      return handle(Type::Any(), isolate);
+      return map.is_null()
+          ? Type::Receiver(isolate) : Type::Class(map, isolate);
+    case CompareIC::GENERIC: return Type::Any(isolate);
   }
   UNREACHABLE();
   return Handle<Type>();
index 688c227643b7bef37d4f324410e6805c9d503683..9a42b75fc1894fe2026c88ba5baa29e7103c3b23 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -171,7 +171,7 @@ class IC {
   //   well as smis.
   // - The oddball map is only used for booleans.
   static Handle<Map> TypeToMap(Type* type, Isolate* isolate);
-  static Type* MapToType(Handle<Map> type);
+  static Handle<Type> MapToType(Handle<Map> type);
   static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate);
 
   ContextualMode contextual_mode() const {
@@ -243,7 +243,7 @@ class IC {
   virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code);
 
   void CopyICToMegamorphicCache(Handle<String> name);
-  bool IsTransitionOfMonomorphicTarget(Type* type);
+  bool IsTransitionOfMonomorphicTarget(Handle<Type> type);
   void PatchCache(Handle<Type> type,
                   Handle<String> name,
                   Handle<Code> code);
index 6ba55b64ac30d4abb360125ee1398eaa18a3e256..e498ae162aaa3f6526f23f26e31496023cb59723 100644 (file)
@@ -204,7 +204,9 @@ size_t GetMemoryUsedByList(const List<T, P>& list) {
 
 
 class Map;
-class Type;
+template<class> class TypeImpl;
+struct HeapTypeConfig;
+typedef TypeImpl<HeapTypeConfig> Type;
 class Code;
 template<typename T> class Handle;
 typedef List<Map*> MapList;
index fe2f8242e26b0208955cfc7d273426060c8277d9..539d4afb01bac1da3bfd1487e9fe545503531852 100644 (file)
@@ -10544,13 +10544,12 @@ void Code::FindAllTypes(TypeHandleList* types) {
   ASSERT(is_inline_cache_stub());
   DisallowHeapAllocation no_allocation;
   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
-  Isolate* isolate = GetIsolate();
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
     Object* object = info->target_object();
     if (object->IsMap()) {
       Handle<Map> map(Map::cast(object));
-      types->Add(handle(IC::MapToType(map), isolate));
+      types->Add(IC::MapToType(map));
     }
   }
 }
@@ -16625,9 +16624,8 @@ Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell,
   Handle<Type> old_type(cell->type(), isolate);
   // TODO(2803): Do not track ConsString as constant because they cannot be
   // embedded into code.
-  Handle<Type> new_type(value->IsConsString() || value->IsTheHole()
-                        ? Type::Any()
-                        : Type::Constant(value, isolate), isolate);
+  Handle<Type> new_type = value->IsConsString() || value->IsTheHole()
+      ? Type::Any(isolate) : Type::Constant(value, isolate);
 
   if (new_type->Is(old_type)) {
     return old_type;
@@ -16640,7 +16638,7 @@ Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell,
     return new_type;
   }
 
-  return handle(Type::Any(), isolate);
+  return Type::Any(isolate);
 }
 
 
index d609eb03d6ee15f98bf413cfcc6b0c308e26f0f4..1dc54b206e39cc72cf133d4b006d65352f09098f 100644 (file)
@@ -881,7 +881,10 @@ class FixedArrayBase;
 class GlobalObject;
 class ObjectVisitor;
 class StringStream;
-class Type;
+// We cannot just say "class Type;" if it is created from a template... =8-?
+template<class> class TypeImpl;
+struct HeapTypeConfig;
+typedef TypeImpl<HeapTypeConfig> Type;
 
 
 // A template-ized version of the IsXXX functions.
index 71ac8bb6fbf091978a8dea894fab31589d9ee0a1..5686ed074430be4198dd040fa6458f4e68f59cf0 100644 (file)
@@ -58,7 +58,9 @@ namespace v8 {
 namespace internal {
 
 class Smi;
-class Type;
+template<class> class TypeImpl;
+struct HeapTypeConfig;
+typedef TypeImpl<HeapTypeConfig> Type;
 class TypeInfo;
 
 // Type of properties.
@@ -105,9 +107,7 @@ class Representation {
   static Representation Integer8() { return Representation(kInteger8); }
   static Representation UInteger8() { return Representation(kUInteger8); }
   static Representation Integer16() { return Representation(kInteger16); }
-  static Representation UInteger16() {
-    return Representation(kUInteger16);
-  }
+  static Representation UInteger16() { return Representation(kUInteger16); }
   static Representation Smi() { return Representation(kSmi); }
   static Representation Integer32() { return Representation(kInteger32); }
   static Representation Double() { return Representation(kDouble); }
index e92d119590260068681204b04dae135fb7f7c41e..fc0538ab5ba106cf5c88be95a8cca071b893db86 100644 (file)
@@ -651,7 +651,7 @@ Handle<Code> StubCache::ComputeLoadElementPolymorphic(
 
   TypeHandleList types(receiver_maps->length());
   for (int i = 0; i < receiver_maps->length(); i++) {
-    types.Add(handle(Type::Class(receiver_maps->at(i)), isolate()));
+    types.Add(Type::Class(receiver_maps->at(i), isolate()));
   }
   CodeHandleList handlers(receiver_maps->length());
   KeyedLoadStubCompiler compiler(isolate_);
index 7f1d3b5ea304a21c0b892b3056a9e4be623d8659..15e454b2188d63207614feebf1e63710d4ca47d7 100644 (file)
@@ -252,7 +252,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
   Handle<Object> info = GetInfo(id);
   if (!info->IsCode()) {
     // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
-    *left_type = *right_type = *combined_type = handle(Type::None(), isolate_);
+    *left_type = *right_type = *combined_type = Type::None(isolate_);
     return;
   }
   Handle<Code> code = Handle<Code>::cast(info);
@@ -291,7 +291,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
     // operations covered by the BinaryOpIC we should always have them.
     ASSERT(op < BinaryOpIC::State::FIRST_TOKEN ||
            op > BinaryOpIC::State::LAST_TOKEN);
-    *left = *right = *result = handle(Type::None(), isolate_);
+    *left = *right = *result = Type::None(isolate_);
     *fixed_right_arg = Maybe<int>();
     *allocation_site = Handle<AllocationSite>::null();
     return;
@@ -317,7 +317,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
 
 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) {
   Handle<Object> object = GetInfo(id);
-  if (!object->IsCode()) return handle(Type::None(), isolate_);
+  if (!object->IsCode()) return Type::None(isolate_);
   Handle<Code> code = Handle<Code>::cast(object);
   ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
   BinaryOpIC::State state(code->extended_extra_ic_state());
index 485ba885187364ed2b99098865eec3197b2c47dc..2aa60817e5f4f30e221085507ef3ae497a846e8e 100644 (file)
 namespace v8 {
 namespace internal {
 
-int Type::NumClasses() {
-  if (is_class()) {
+template<class Config>
+int TypeImpl<Config>::NumClasses() {
+  if (this->IsClass()) {
     return 1;
-  } else if (is_union()) {
-    Handle<Unioned> unioned = as_union();
+  } else if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     int result = 0;
     for (int i = 0; i < unioned->length(); ++i) {
-      if (union_get(unioned, i)->is_class()) ++result;
+      if (Config::union_get(unioned, i)->IsClass()) ++result;
     }
     return result;
   } else {
@@ -47,14 +48,15 @@ int Type::NumClasses() {
 }
 
 
-int Type::NumConstants() {
-  if (is_constant()) {
+template<class Config>
+int TypeImpl<Config>::NumConstants() {
+  if (this->IsConstant()) {
     return 1;
-  } else if (is_union()) {
-    Handle<Unioned> unioned = as_union();
+  } else if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     int result = 0;
     for (int i = 0; i < unioned->length(); ++i) {
-      if (union_get(unioned, i)->is_constant()) ++result;
+      if (Config::union_get(unioned, i)->IsConstant()) ++result;
     }
     return result;
   } else {
@@ -63,41 +65,61 @@ int Type::NumConstants() {
 }
 
 
-template<class T>
-Handle<Type> Type::Iterator<T>::get_type() {
+template<class Config> template<class T>
+typename TypeImpl<Config>::TypeHandle
+TypeImpl<Config>::Iterator<T>::get_type() {
   ASSERT(!Done());
-  return type_->is_union() ? union_get(type_->as_union(), index_) : type_;
+  return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_;
 }
 
-template<>
-Handle<i::Map> Type::Iterator<i::Map>::Current() {
-  return get_type()->as_class();
-}
 
-template<>
-Handle<i::Object> Type::Iterator<i::Object>::Current() {
-  return get_type()->as_constant();
-}
+// C++ cannot specialise nested templates, so we have to go through this
+// contortion with an auxiliary template to simulate it.
+template<class Config, class T>
+struct TypeImplIteratorAux {
+  static bool matches(typename TypeImpl<Config>::TypeHandle type);
+  static i::Handle<T> current(typename TypeImpl<Config>::TypeHandle type);
+};
+
+template<class Config>
+struct TypeImplIteratorAux<Config, i::Map> {
+  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
+    return type->IsClass();
+  }
+  static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
+    return type->AsClass();
+  }
+};
 
+template<class Config>
+struct TypeImplIteratorAux<Config, i::Object> {
+  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
+    return type->IsConstant();
+  }
+  static i::Handle<i::Object> current(
+      typename TypeImpl<Config>::TypeHandle type) {
+    return type->AsConstant();
+  }
+};
 
-template<>
-bool Type::Iterator<i::Map>::matches(Handle<Type> type) {
-  return type->is_class();
+template<class Config> template<class T>
+bool TypeImpl<Config>::Iterator<T>::matches(TypeHandle type) {
+  return TypeImplIteratorAux<Config, T>::matches(type);
 }
 
-template<>
-bool Type::Iterator<i::Object>::matches(Handle<Type> type) {
-  return type->is_constant();
+template<class Config> template<class T>
+i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
+  return TypeImplIteratorAux<Config, T>::current(get_type());
 }
 
 
-template<class T>
-void Type::Iterator<T>::Advance() {
+template<class Config> template<class T>
+void TypeImpl<Config>::Iterator<T>::Advance() {
   ++index_;
-  if (type_->is_union()) {
-    Handle<Unioned> unioned = type_->as_union();
+  if (type_->IsUnion()) {
+    UnionedHandle unioned = type_->AsUnion();
     for (; index_ < unioned->length(); ++index_) {
-      if (matches(union_get(unioned, index_))) return;
+      if (matches(Config::union_get(unioned, index_))) return;
     }
   } else if (index_ == 0 && matches(type_)) {
     return;
@@ -105,30 +127,29 @@ void Type::Iterator<T>::Advance() {
   index_ = -1;
 }
 
-template class Type::Iterator<i::Map>;
-template class Type::Iterator<i::Object>;
-
 
 // Get the smallest bitset subsuming this type.
-int Type::LubBitset() {
-  if (this->is_bitset()) {
-    return this->as_bitset();
-  } else if (this->is_union()) {
-    Handle<Unioned> unioned = this->as_union();
+template<class Config>
+int TypeImpl<Config>::LubBitset() {
+  if (this->IsBitset()) {
+    return this->AsBitset();
+  } else if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     int bitset = kNone;
     for (int i = 0; i < unioned->length(); ++i) {
-      bitset |= union_get(unioned, i)->LubBitset();
+      bitset |= Config::union_get(unioned, i)->LubBitset();
     }
     return bitset;
-  } else if (this->is_class()) {
-    return LubBitset(*this->as_class());
+  } else if (this->IsClass()) {
+    return LubBitset(*this->AsClass());
   } else {
-    return LubBitset(*this->as_constant());
+    return LubBitset(*this->AsConstant());
   }
 }
 
 
-int Type::LubBitset(i::Object* value) {
+template<class Config>
+int TypeImpl<Config>::LubBitset(i::Object* value) {
   if (value->IsSmi()) return kSmi;
   i::Map* map = i::HeapObject::cast(value)->map();
   if (map->instance_type() == HEAP_NUMBER_TYPE) {
@@ -145,11 +166,12 @@ int Type::LubBitset(i::Object* value) {
     if (value->IsTheHole()) return kAny;  // TODO(rossberg): kNone?
     UNREACHABLE();
   }
-  return Type::LubBitset(map);
+  return LubBitset(map);
 }
 
 
-int Type::LubBitset(i::Map* map) {
+template<class Config>
+int TypeImpl<Config>::LubBitset(i::Map* map) {
   switch (map->instance_type()) {
     case STRING_TYPE:
     case ASCII_STRING_TYPE:
@@ -231,12 +253,13 @@ int Type::LubBitset(i::Map* map) {
 
 
 // Get the largest bitset subsumed by this type.
-int Type::GlbBitset() {
-  if (this->is_bitset()) {
-    return this->as_bitset();
-  } else if (this->is_union()) {
+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 union_get(this->as_union(), 0)->GlbBitset();
+    return Config::union_get(this->AsUnion(), 0)->GlbBitset();
   } else {
     return kNone;
   }
@@ -244,37 +267,40 @@ int Type::GlbBitset() {
 
 
 // Most precise _current_ type of a value (usually its class).
-Type* Type::OfCurrently(Handle<i::Object> value) {
-  if (value->IsSmi()) return Smi();
+template<class Config>
+typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently(
+    i::Handle<i::Object> value, Region* region) {
+  if (value->IsSmi()) return Smi(region);
   i::Map* map = i::HeapObject::cast(*value)->map();
   if (map->instance_type() == HEAP_NUMBER_TYPE ||
       map->instance_type() == ODDBALL_TYPE) {
-    return Type::Of(value);
+    return Of(value, region);
   }
-  return Class(i::handle(map));
+  return Class(i::handle(map), region);
 }
 
 
 // Check this <= that.
-bool Type::SlowIs(Type* that) {
+template<class Config>
+bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
   // Fast path for bitsets.
-  if (this->is_none()) return true;
-  if (that->is_bitset()) {
-    return (this->LubBitset() | that->as_bitset()) == that->as_bitset();
+  if (this->IsNone()) return true;
+  if (that->IsBitset()) {
+    return (this->LubBitset() | that->AsBitset()) == that->AsBitset();
   }
 
-  if (that->is_class()) {
-    return this->is_class() && *this->as_class() == *that->as_class();
+  if (that->IsClass()) {
+    return this->IsClass() && *this->AsClass() == *that->AsClass();
   }
-  if (that->is_constant()) {
-    return this->is_constant() && *this->as_constant() == *that->as_constant();
+  if (that->IsConstant()) {
+    return this->IsConstant() && *this->AsConstant() == *that->AsConstant();
   }
 
   // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
-  if (this->is_union()) {
-    Handle<Unioned> unioned = this->as_union();
+  if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> this_i = union_get(unioned, i);
+      TypeHandle this_i = Config::union_get(unioned, i);
       if (!this_i->Is(that)) return false;
     }
     return true;
@@ -282,13 +308,13 @@ bool Type::SlowIs(Type* that) {
 
   // T <= (T1 \/ ... \/ Tn)  <=>  (T <= T1) \/ ... \/ (T <= Tn)
   // (iff T is not a union)
-  ASSERT(!this->is_union());
-  if (that->is_union()) {
-    Handle<Unioned> unioned = that->as_union();
+  ASSERT(!this->IsUnion());
+  if (that->IsUnion()) {
+    UnionedHandle unioned = that->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> that_i = union_get(unioned, i);
+      TypeHandle that_i = Config::union_get(unioned, i);
       if (this->Is(that_i)) return true;
-      if (this->is_bitset()) break;  // Fast fail, no other field is a bitset.
+      if (this->IsBitset()) break;  // Fast fail, only first field is a bitset.
     }
     return false;
   }
@@ -297,60 +323,63 @@ bool Type::SlowIs(Type* that) {
 }
 
 
-bool Type::IsCurrently(Type* that) {
+template<class Config>
+bool TypeImpl<Config>::IsCurrently(TypeImpl* that) {
   return this->Is(that) ||
-      (this->is_constant() && that->is_class() &&
-       this->as_constant()->IsHeapObject() &&
-       i::HeapObject::cast(*this->as_constant())->map() == *that->as_class());
+      (this->IsConstant() && that->IsClass() &&
+       this->AsConstant()->IsHeapObject() &&
+       i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass());
 }
 
 
 // Check this overlaps that.
-bool Type::Maybe(Type* that) {
+template<class Config>
+bool TypeImpl<Config>::Maybe(TypeImpl* that) {
   // Fast path for bitsets.
-  if (this->is_bitset()) {
-    return (this->as_bitset() & that->LubBitset()) != 0;
+  if (this->IsBitset()) {
+    return (this->AsBitset() & that->LubBitset()) != 0;
   }
-  if (that->is_bitset()) {
-    return (this->LubBitset() & that->as_bitset()) != 0;
+  if (that->IsBitset()) {
+    return (this->LubBitset() & that->AsBitset()) != 0;
   }
 
   // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
-  if (this->is_union()) {
-    Handle<Unioned> unioned = this->as_union();
+  if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> this_i = union_get(unioned, i);
+      TypeHandle this_i = Config::union_get(unioned, i);
       if (this_i->Maybe(that)) return true;
     }
     return false;
   }
 
   // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
-  if (that->is_union()) {
-    Handle<Unioned> unioned = that->as_union();
+  if (that->IsUnion()) {
+    UnionedHandle unioned = that->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> that_i = union_get(unioned, i);
+      TypeHandle that_i = Config::union_get(unioned, i);
       if (this->Maybe(that_i)) return true;
     }
     return false;
   }
 
-  ASSERT(!that->is_union());
-  if (this->is_class()) {
-    return that->is_class() && *this->as_class() == *that->as_class();
+  ASSERT(!this->IsUnion() && !that->IsUnion());
+  if (this->IsClass()) {
+    return that->IsClass() && *this->AsClass() == *that->AsClass();
   }
-  if (this->is_constant()) {
-    return that->is_constant() && *this->as_constant() == *that->as_constant();
+  if (this->IsConstant()) {
+    return that->IsConstant() && *this->AsConstant() == *that->AsConstant();
   }
 
   return false;
 }
 
 
-bool Type::InUnion(Handle<Unioned> unioned, int current_size) {
-  ASSERT(!this->is_union());
+template<class Config>
+bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
+  ASSERT(!this->IsUnion());
   for (int i = 0; i < current_size; ++i) {
-    Handle<Type> type = union_get(unioned, i);
+    TypeHandle type = Config::union_get(unioned, i);
     if (this->Is(type)) return true;
   }
   return false;
@@ -359,17 +388,20 @@ bool Type::InUnion(Handle<Unioned> unioned, int current_size) {
 
 // Get non-bitsets from this which are not subsumed by union, store at unioned,
 // starting at index. Returns updated index.
-int Type::ExtendUnion(Handle<Unioned> result, int current_size) {
+template<class Config>
+int TypeImpl<Config>::ExtendUnion(UnionedHandle result, int current_size) {
   int old_size = current_size;
-  if (this->is_class() || this->is_constant()) {
+  if (this->IsClass() || this->IsConstant()) {
     if (!this->InUnion(result, old_size)) result->set(current_size++, this);
-  } else if (this->is_union()) {
-    Handle<Unioned> unioned = this->as_union();
+  } else if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> type = union_get(unioned, i);
-      ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
-      if (type->is_bitset()) continue;
-      if (!type->InUnion(result, old_size)) result->set(current_size++, *type);
+      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);
+      }
     }
   }
   return current_size;
@@ -378,74 +410,75 @@ int Type::ExtendUnion(Handle<Unioned> result, int current_size) {
 
 // Union 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?
-Type* Type::Union(Handle<Type> type1, Handle<Type> type2) {
+template<class Config>
+typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
+    TypeHandle type1, TypeHandle type2, Region* region) {
   // Fast case: bit sets.
-  if (type1->is_bitset() && type2->is_bitset()) {
-    return from_bitset(type1->as_bitset() | type2->as_bitset());
+  if (type1->IsBitset() && type2->IsBitset()) {
+    return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region);
   }
 
   // Fast case: top or bottom types.
-  if (type1->SameValue(Type::Any())) return *type1;
-  if (type2->SameValue(Type::Any())) return *type2;
-  if (type1->SameValue(Type::None())) return *type2;
-  if (type2->SameValue(Type::None())) return *type1;
+  if (type1->IsAny()) return type1;
+  if (type2->IsAny()) return type2;
+  if (type1->IsNone()) return type2;
+  if (type2->IsNone()) return type1;
 
   // Semi-fast case: Unioned objects are neither involved nor produced.
-  if (!(type1->is_union() || type2->is_union())) {
-    if (type1->Is(type2)) return *type2;
-    if (type2->Is(type1)) return *type1;
+  if (!(type1->IsUnion() || type2->IsUnion())) {
+    if (type1->Is(type2)) return type2;
+    if (type2->Is(type1)) return type1;
   }
 
   // Slow case: may need to produce a Unioned object.
-  Isolate* isolate = NULL;
-  int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
-  if (!type1->is_bitset()) {
-    isolate = i::HeapObject::cast(*type1)->GetIsolate();
-    size += (type1->is_union() ? type1->as_union()->length() : 1);
+  int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
+  if (!type1->IsBitset()) {
+    size += (type1->IsUnion() ? type1->AsUnion()->length() : 1);
   }
-  if (!type2->is_bitset()) {
-    isolate = i::HeapObject::cast(*type2)->GetIsolate();
-    size += (type2->is_union() ? type2->as_union()->length() : 1);
+  if (!type2->IsBitset()) {
+    size += (type2->IsUnion() ? type2->AsUnion()->length() : 1);
   }
-  ASSERT(isolate != NULL);
   ASSERT(size >= 2);
-  Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
+  UnionedHandle unioned = Config::union_create(size, region);
   size = 0;
 
   int bitset = type1->GlbBitset() | type2->GlbBitset();
-  if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
+  if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
   size = type1->ExtendUnion(unioned, size);
   size = type2->ExtendUnion(unioned, size);
 
   if (size == 1) {
-    return *union_get(unioned, 0);
+    return Config::union_get(unioned, 0);
   } else if (size == unioned->length()) {
-    return from_handle(unioned);
+    return Config::from_union(unioned);
   }
 
   // There was an overlap. Copy to smaller union.
-  Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
+  UnionedHandle result = Config::union_create(size, region);
   for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
-  return from_handle(result);
+  return Config::from_union(result);
 }
 
 
 // Get non-bitsets from this which are also in that, store at unioned,
 // starting at index. Returns updated index.
-int Type::ExtendIntersection(
-    Handle<Unioned> result, Handle<Type> that, int current_size) {
+template<class Config>
+int TypeImpl<Config>::ExtendIntersection(
+    UnionedHandle result, TypeHandle that, int current_size) {
   int old_size = current_size;
-  if (this->is_class() || this->is_constant()) {
+  if (this->IsClass() || this->IsConstant()) {
     if (this->Is(that) && !this->InUnion(result, old_size))
       result->set(current_size++, this);
-  } else if (this->is_union()) {
-    Handle<Unioned> unioned = this->as_union();
+  } else if (this->IsUnion()) {
+    UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> type = union_get(unioned, i);
-      ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
-      if (type->is_bitset()) continue;
-      if (type->Is(that) && !type->InUnion(result, old_size))
+      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) &&
+          !type->InUnion(result, old_size)) {
         result->set(current_size++, *type);
+      }
     }
   }
   return current_size;
@@ -454,68 +487,60 @@ int Type::ExtendIntersection(
 
 // 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?
-Type* Type::Intersect(Handle<Type> type1, Handle<Type> type2) {
+template<class Config>
+typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
+    TypeHandle type1, TypeHandle type2, Region* region) {
   // Fast case: bit sets.
-  if (type1->is_bitset() && type2->is_bitset()) {
-    return from_bitset(type1->as_bitset() & type2->as_bitset());
+  if (type1->IsBitset() && type2->IsBitset()) {
+    return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region);
   }
 
   // Fast case: top or bottom types.
-  if (type1->SameValue(Type::None())) return *type1;
-  if (type2->SameValue(Type::None())) return *type2;
-  if (type1->SameValue(Type::Any())) return *type2;
-  if (type2->SameValue(Type::Any())) return *type1;
+  if (type1->IsNone()) return type1;
+  if (type2->IsNone()) return type2;
+  if (type1->IsAny()) return type2;
+  if (type2->IsAny()) return type1;
 
   // Semi-fast case: Unioned objects are neither involved nor produced.
-  if (!(type1->is_union() || type2->is_union())) {
-    if (type1->Is(type2)) return *type1;
-    if (type2->Is(type1)) return *type2;
+  if (!(type1->IsUnion() || type2->IsUnion())) {
+    if (type1->Is(type2)) return type1;
+    if (type2->Is(type1)) return type2;
   }
 
   // Slow case: may need to produce a Unioned object.
-  Isolate* isolate = NULL;
   int size = 0;
-  if (!type1->is_bitset()) {
-    isolate = i::HeapObject::cast(*type1)->GetIsolate();
-    size = (type1->is_union() ? type1->as_union()->length() : 2);
+  if (!type1->IsBitset()) {
+    size = (type1->IsUnion() ? type1->AsUnion()->length() : 2);
   }
-  if (!type2->is_bitset()) {
-    isolate = i::HeapObject::cast(*type2)->GetIsolate();
-    int size2 = (type2->is_union() ? type2->as_union()->length() : 2);
+  if (!type2->IsBitset()) {
+    int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2);
     size = (size == 0 ? size2 : Min(size, size2));
   }
-  ASSERT(isolate != NULL);
   ASSERT(size >= 2);
-  Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
+  UnionedHandle unioned = Config::union_create(size, region);
   size = 0;
 
   int bitset = type1->GlbBitset() & type2->GlbBitset();
-  if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
+  if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
   size = type1->ExtendIntersection(unioned, type2, size);
   size = type2->ExtendIntersection(unioned, type1, size);
 
   if (size == 0) {
-    return None();
+    return None(region);
   } else if (size == 1) {
-    return *union_get(unioned, 0);
+    return Config::union_get(unioned, 0);
   } else if (size == unioned->length()) {
-    return from_handle(unioned);
+    return Config::from_union(unioned);
   }
 
   // There were dropped cases. Copy to smaller union.
-  Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
+  UnionedHandle result = Config::union_create(size, region);
   for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
-  return from_handle(result);
-}
-
-
-Type* Type::Optional(Handle<Type> type) {
-  return type->is_bitset()
-      ? from_bitset(type->as_bitset() | kUndefined)
-      : Union(type, Undefined()->handle_via_isolate_of(*type));
+  return Config::from_union(result);
 }
 
 
+// TODO(rossberg): this does not belong here.
 Representation Representation::FromType(Handle<Type> type) {
   if (type->Is(Type::None())) return Representation::None();
   if (type->Is(Type::Smi())) return Representation::Smi();
@@ -526,14 +551,16 @@ Representation Representation::FromType(Handle<Type> type) {
 
 
 #ifdef OBJECT_PRINT
-void Type::TypePrint() {
+template<class Config>
+void TypeImpl<Config>::TypePrint() {
   TypePrint(stdout);
   PrintF(stdout, "\n");
   Flush(stdout);
 }
 
 
-const char* Type::bitset_name(int bitset) {
+template<class Config>
+const char* TypeImpl<Config>::bitset_name(int bitset) {
   switch (bitset) {
     #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type;
     BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
@@ -544,9 +571,10 @@ const char* Type::bitset_name(int bitset) {
 }
 
 
-void Type::TypePrint(FILE* out) {
-  if (is_bitset()) {
-    int bitset = as_bitset();
+template<class Config>
+void TypeImpl<Config>::TypePrint(FILE* out) {
+  if (this->IsBitset()) {
+    int bitset = this->AsBitset();
     const char* name = bitset_name(bitset);
     if (name != NULL) {
       PrintF(out, "%s", name);
@@ -562,19 +590,19 @@ void Type::TypePrint(FILE* out) {
       }
       PrintF(out, ")");
     }
-  } else if (is_constant()) {
-    PrintF(out, "Constant(%p : ", static_cast<void*>(*as_constant()));
-    from_bitset(LubBitset())->TypePrint(out);
+  } else if (this->IsConstant()) {
+    PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
+    Config::from_bitset(this->LubBitset())->TypePrint(out);
     PrintF(")");
-  } else if (is_class()) {
-    PrintF(out, "Class(%p < ", static_cast<void*>(*as_class()));
-    from_bitset(LubBitset())->TypePrint(out);
+  } else if (this->IsClass()) {
+    PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
+    Config::from_bitset(this->LubBitset())->TypePrint(out);
     PrintF(")");
-  } else if (is_union()) {
+  } else if (this->IsUnion()) {
     PrintF(out, "(");
-    Handle<Unioned> unioned = as_union();
+    UnionedHandle unioned = this->AsUnion();
     for (int i = 0; i < unioned->length(); ++i) {
-      Handle<Type> type_i = union_get(unioned, i);
+      TypeHandle type_i = Config::union_get(unioned, i);
       if (i > 0) PrintF(out, " | ");
       type_i->TypePrint(out);
     }
@@ -584,4 +612,9 @@ void Type::TypePrint(FILE* out) {
 #endif
 
 
+template class TypeImpl<HeapTypeConfig>;
+template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
+template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
+
+
 } }  // namespace v8::internal
index 1dc79dd6b33566759cd87f8df4d54d8da25a951f..f38fca83e9570f118c9d92e235e1d7b470f2661a 100644 (file)
@@ -131,44 +131,72 @@ namespace internal {
   V(Detectable,      kAllocated - kUndetectable)
 
 
-class Type : public Object {
+// struct Config {
+//   typedef Base;
+//   typedef Unioned;
+//   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 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);
+// }
+template<class Config>
+class TypeImpl : public Config::Base {
  public:
-  #define DEFINE_TYPE_CONSTRUCTOR(type, value)           \
-    static Type* type() { return from_bitset(k##type); }
+  typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
+  typedef typename Config::Region 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 Type* Class(Handle<i::Map> map) { return from_handle(map); }
-  static Type* Constant(Handle<i::HeapObject> value) {
-    return Constant(value, value->GetIsolate());
+  static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
+    return Config::from_class(map, region);
   }
-  static Type* Constant(Handle<i::Object> value, Isolate* isolate) {
-    return from_handle(isolate->factory()->NewBox(value));
+  static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
+    return Config::from_constant(value, region);
   }
 
-  static Type* Union(Handle<Type> type1, Handle<Type> type2);
-  static Type* Intersect(Handle<Type> type1, Handle<Type> type2);
-  static Type* Optional(Handle<Type> type);  // type \/ Undefined
+  static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
+  static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
 
-  static Type* Of(Handle<i::Object> value) {
-    return from_bitset(LubBitset(*value));
+  static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
+    return Config::from_bitset(LubBitset(*value), region);
   }
 
-  bool Is(Type* that) { return this == that || SlowIs(that); }
-  bool Is(Handle<Type> that) { return this->Is(*that); }
-  bool Maybe(Type* that);
-  bool Maybe(Handle<Type> that) { return this->Maybe(*that); }
+  bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
+  bool Is(TypeHandle that) { return this->Is(*that); }
+  bool Maybe(TypeImpl* that);
+  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 Type* OfCurrently(Handle<i::Object> value);
-  bool IsCurrently(Type* that);
-  bool IsCurrently(Handle<Type> that)  { return this->IsCurrently(*that); }
+  static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
+  bool IsCurrently(TypeImpl* that);
+  bool IsCurrently(TypeHandle that)  { return this->IsCurrently(*that); }
 
-  bool IsClass() { return is_class(); }
-  bool IsConstant() { return is_constant(); }
-  Handle<i::Map> AsClass() { return as_class(); }
-  Handle<i::Object> AsConstant() { return as_constant(); }
+  bool IsClass() { return Config::is_class(this); }
+  bool IsConstant() { return Config::is_constant(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();
@@ -177,37 +205,36 @@ class Type : public Object {
   class Iterator {
    public:
     bool Done() const { return index_ < 0; }
-    Handle<T> Current();
+    i::Handle<T> Current();
     void Advance();
 
    private:
-    friend class Type;
+    template<class> friend class TypeImpl;
 
     Iterator() : index_(-1) {}
-    explicit Iterator(Handle<Type> type) : type_(type), index_(-1) {
+    explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
       Advance();
     }
 
-    inline bool matches(Handle<Type> type);
-    inline Handle<Type> get_type();
+    inline bool matches(TypeHandle type);
+    inline TypeHandle get_type();
 
-    Handle<Type> type_;
+    TypeHandle type_;
     int index_;
   };
 
   Iterator<i::Map> Classes() {
-    if (this->is_bitset()) return Iterator<i::Map>();
-    return Iterator<i::Map>(this->handle());
+    if (this->IsBitset()) return Iterator<i::Map>();
+    return Iterator<i::Map>(Config::handle(this));
   }
   Iterator<i::Object> Constants() {
-    if (this->is_bitset()) return Iterator<i::Object>();
-    return Iterator<i::Object>(this->handle());
+    if (this->IsBitset()) return Iterator<i::Object>();
+    return Iterator<i::Object>(Config::handle(this));
   }
 
-  static Type* cast(i::Object* object) {
-    Type* t = static_cast<Type*>(object);
-    ASSERT(t->is_bitset() || t->is_class() ||
-           t->is_constant() || t->is_union());
+  static TypeImpl* cast(i::Object* object) {
+    TypeImpl* t = static_cast<TypeImpl*>(object);
+    ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
     return t;
   }
 
@@ -217,11 +244,14 @@ class Type : public Object {
 #endif
 
  private:
+  template<class> friend class Iterator;
+
   // A union is a fixed array containing types. 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 FixedArray Unioned;
+  typedef typename Config::Unioned Unioned;
+  typedef typename Config::template Handle<Unioned>::type UnionedHandle;
 
   enum {
     #define DECLARE_TYPE(type, value) k##type = (value),
@@ -230,40 +260,14 @@ class Type : public Object {
     kUnusedEOL = 0
   };
 
-  bool is_none() { return this == None(); }
-  bool is_bitset() { return this->IsSmi(); }
-  bool is_class() { return this->IsMap(); }
-  bool is_constant() { return this->IsBox(); }
-  bool is_union() { return this->IsFixedArray(); }
+  bool IsNone() { return this == None(); }
+  bool IsAny() { return this == Any(); }
+  bool IsBitset() { return Config::is_bitset(this); }
+  bool IsUnion() { return Config::is_union(this); }
+  int AsBitset() { return Config::as_bitset(this); }
+  UnionedHandle AsUnion() { return Config::as_union(this); }
 
-  bool SlowIs(Type* that);
-
-  int as_bitset() { return Smi::cast(this)->value(); }
-  Handle<i::Map> as_class() { return Handle<i::Map>::cast(handle()); }
-  Handle<i::Object> as_constant() {
-    Handle<i::Box> box = Handle<i::Box>::cast(handle());
-    return i::handle(box->value(), box->GetIsolate());
-  }
-  Handle<Unioned> as_union() { return Handle<Unioned>::cast(handle()); }
-
-  Handle<Type> handle() { return handle_via_isolate_of(this); }
-  Handle<Type> handle_via_isolate_of(Type* type) {
-    ASSERT(type->IsHeapObject());
-    return i::handle(this, i::HeapObject::cast(type)->GetIsolate());
-  }
-
-  static Type* from_bitset(int bitset) {
-    return static_cast<Type*>(i::Object::cast(i::Smi::FromInt(bitset)));
-  }
-  static Type* from_handle(Handle<i::HeapObject> handle) {
-    return static_cast<Type*>(i::Object::cast(*handle));
-  }
-
-  static Handle<Type> union_get(Handle<Unioned> unioned, int i) {
-    Type* type = static_cast<Type*>(unioned->get(i));
-    ASSERT(!type->is_union());
-    return type->handle_via_isolate_of(from_handle(unioned));
-  }
+  bool SlowIs(TypeImpl* that);
 
   int LubBitset();  // least upper bound that's a bitset
   int GlbBitset();  // greatest lower bound that's a bitset
@@ -271,67 +275,131 @@ class Type : public Object {
   static int LubBitset(i::Object* value);
   static int LubBitset(i::Map* map);
 
-  bool InUnion(Handle<Unioned> unioned, int current_size);
-  int ExtendUnion(Handle<Unioned> unioned, int current_size);
+  bool InUnion(UnionedHandle unioned, int current_size);
+  int ExtendUnion(UnionedHandle unioned, int current_size);
   int ExtendIntersection(
-      Handle<Unioned> unioned, Handle<Type> type, int current_size);
+      UnionedHandle unioned, TypeHandle type, int current_size);
 
   static const char* bitset_name(int bitset);
 };
 
 
-// A simple struct to represent a pair of lower/upper type bounds.
-struct Bounds {
-  Handle<Type> lower;
-  Handle<Type> upper;
+struct HeapTypeConfig {
+  typedef TypeImpl<HeapTypeConfig> Type;
+  typedef i::Object Base;
+  typedef i::FixedArray Unioned;
+  typedef i::Isolate Region;
+  template<class T> struct Handle { typedef i::Handle<T> type; };
 
-  Bounds() {}
-  Bounds(Handle<Type> l, Handle<Type> u) : lower(l), upper(u) {
-    ASSERT(lower->Is(upper));
+  static i::Handle<Type> handle(Type* type) {
+    return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
   }
-  Bounds(Type* l, Type* u, Isolate* isl) : lower(l, isl), upper(u, isl) {
-    ASSERT(lower->Is(upper));
+
+  static bool is_bitset(Type* type) { return type->IsSmi(); }
+  static bool is_class(Type* type) { return type->IsMap(); }
+  static bool is_constant(Type* type) { return type->IsBox(); }
+  static bool is_union(Type* type) { return type->IsFixedArray(); }
+
+  static int as_bitset(Type* type) {
+    return Smi::cast(type)->value();
   }
-  explicit Bounds(Handle<Type> t) : lower(t), upper(t) {
-    ASSERT(lower->Is(upper));
+  static i::Handle<i::Map> as_class(Type* type) {
+    return i::handle(i::Map::cast(type));
   }
-  Bounds(Type* t, Isolate* isl) : lower(t, isl), upper(t, isl) {
+  static i::Handle<i::Object> as_constant(Type* type) {
+    i::Box* box = i::Box::cast(type);
+    return i::handle(box->value(), box->GetIsolate());
+  }
+  static i::Handle<Unioned> as_union(Type* type) {
+    return i::handle(i::FixedArray::cast(type));
+  }
+
+  static Type* from_bitset(int bitset) {
+    return Type::cast(i::Smi::FromInt(bitset));
+  }
+  static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) {
+    return i::handle(from_bitset(bitset), isolate);
+  }
+  static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) {
+    return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
+  }
+  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));
+  }
+  static i::Handle<Type> from_union(i::Handle<Unioned> unioned) {
+    return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
+  }
+
+  static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
+    return isolate->factory()->NewFixedArray(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());
+  }
+};
+
+typedef TypeImpl<HeapTypeConfig> Type;
+
+
+// A simple struct to represent a pair of lower/upper type bounds.
+template<class Config>
+struct BoundsImpl {
+  typedef TypeImpl<Config> Type;
+  typedef typename Type::TypeHandle TypeHandle;
+  typedef typename Type::Region Region;
+
+  TypeHandle lower;
+  TypeHandle upper;
+
+  BoundsImpl() {}
+  explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {}
+  BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) {
     ASSERT(lower->Is(upper));
   }
 
   // Unrestricted bounds.
-  static Bounds Unbounded(Isolate* isl) {
-    return Bounds(Type::None(), Type::Any(), isl);
+  static BoundsImpl Unbounded(Region* region) {
+    return BoundsImpl(Type::None(region), Type::Any(region));
   }
 
   // Meet: both b1 and b2 are known to hold.
-  static Bounds Both(Bounds b1, Bounds b2, Isolate* isl) {
-    Handle<Type> lower(Type::Union(b1.lower, b2.lower), isl);
-    Handle<Type> upper(Type::Intersect(b1.upper, b2.upper), isl);
+  static BoundsImpl Both(BoundsImpl b1, BoundsImpl b2, Region* region) {
+    TypeHandle lower = Type::Union(b1.lower, b2.lower, region);
+    TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region);
     // Lower bounds are considered approximate, correct as necessary.
-    lower = handle(Type::Intersect(lower, upper), isl);
-    return Bounds(lower, upper);
+    lower = Type::Intersect(lower, upper, region);
+    return BoundsImpl(lower, upper);
   }
 
   // Join: either b1 or b2 is known to hold.
-  static Bounds Either(Bounds b1, Bounds b2, Isolate* isl) {
-    return Bounds(
-        handle(Type::Intersect(b1.lower, b2.lower), isl),
-        handle(Type::Union(b1.upper, b2.upper), isl));
+  static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region* region) {
+    TypeHandle lower = Type::Intersect(b1.lower, b2.lower, region);
+    TypeHandle upper = Type::Union(b1.upper, b2.upper, region);
+    return BoundsImpl(lower, upper);
   }
 
-  static Bounds NarrowLower(Bounds b, Handle<Type> t, Isolate* isl) {
+  static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) {
     // Lower bounds are considered approximate, correct as necessary.
-    t = handle(Type::Intersect(t, b.upper), isl);
-    return Bounds(handle(Type::Union(b.lower, t), isl), b.upper);
+    t = Type::Intersect(t, b.upper, region);
+    TypeHandle lower = Type::Union(b.lower, t, region);
+    return BoundsImpl(lower, b.upper);
   }
-  static Bounds NarrowUpper(Bounds b, Handle<Type> t, Isolate* isl) {
-    return Bounds(
-        handle(Type::Intersect(b.lower, t), isl),
-        handle(Type::Intersect(b.upper, t), isl));
+  static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) {
+    TypeHandle lower = Type::Intersect(b.lower, t, region);
+    TypeHandle upper = Type::Intersect(b.upper, t, region);
+    return BoundsImpl(lower, upper);
   }
 };
 
+typedef BoundsImpl<HeapTypeConfig> Bounds;
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TYPES_H_
index 152f3c7325d9b5ebf332b22fd5ad16627815c7ec..30e0b920529a5a9ed8890a3d627d3ff06b7bfacb 100644 (file)
@@ -71,12 +71,6 @@ void AstTyper::Run(CompilationInfo* info) {
 #undef RECURSE
 
 
-Effect AstTyper::ObservedOnStack(Object* value) {
-  Type* lower = Type::OfCurrently(Handle<Object>(value, isolate()));
-  return Effect(Bounds(lower, Type::Any(), isolate()));
-}
-
-
 #ifdef OBJECT_PRINT
   static void PrintObserved(Variable* var, Object* value, Handle<Type> type) {
     PrintF("  observed %s ", var->IsParameter() ? "param" : "local");
@@ -89,6 +83,12 @@ Effect AstTyper::ObservedOnStack(Object* value) {
 #endif  // OBJECT_PRINT
 
 
+Effect AstTyper::ObservedOnStack(Object* value) {
+  Handle<Type> lower = Type::OfCurrently(handle(value, isolate()), isolate());
+  return Effect(Bounds(lower, Type::Any(isolate())));
+}
+
+
 void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
   if (stmt->OsrEntryId() != info_->osr_ast_id()) return;
 
@@ -405,13 +405,13 @@ void AstTyper::VisitVariableProxy(VariableProxy* expr) {
 
 
 void AstTyper::VisitLiteral(Literal* expr) {
-  Type* type = Type::Constant(expr->value(), isolate_);
-  NarrowType(expr, Bounds(type, isolate_));
+  Handle<Type> type = Type::Constant(expr->value(), isolate_);
+  NarrowType(expr, Bounds(type));
 }
 
 
 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
-  NarrowType(expr, Bounds(Type::RegExp(), isolate_));
+  NarrowType(expr, Bounds(Type::RegExp(isolate_)));
 }
 
 
@@ -432,7 +432,7 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
     RECURSE(Visit(prop->value()));
   }
 
-  NarrowType(expr, Bounds(Type::Object(), isolate_));
+  NarrowType(expr, Bounds(Type::Object(isolate_)));
 }
 
 
@@ -443,7 +443,7 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
     RECURSE(Visit(value));
   }
 
-  NarrowType(expr, Bounds(Type::Array(), isolate_));
+  NarrowType(expr, Bounds(Type::Array(isolate_)));
 }
 
 
@@ -495,7 +495,7 @@ void AstTyper::VisitThrow(Throw* expr) {
   RECURSE(Visit(expr->exception()));
   // TODO(rossberg): is it worth having a non-termination effect?
 
-  NarrowType(expr, Bounds(Type::None(), isolate_));
+  NarrowType(expr, Bounds(Type::None(isolate_)));
 }
 
 
@@ -593,13 +593,13 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
   switch (expr->op()) {
     case Token::NOT:
     case Token::DELETE:
-      NarrowType(expr, Bounds(Type::Boolean(), isolate_));
+      NarrowType(expr, Bounds(Type::Boolean(isolate_)));
       break;
     case Token::VOID:
-      NarrowType(expr, Bounds(Type::Undefined(), isolate_));
+      NarrowType(expr, Bounds(Type::Undefined(isolate_)));
       break;
     case Token::TYPEOF:
-      NarrowType(expr, Bounds(Type::InternalizedString(), isolate_));
+      NarrowType(expr, Bounds(Type::InternalizedString(isolate_)));
       break;
     default:
       UNREACHABLE();
@@ -617,7 +617,7 @@ void AstTyper::VisitCountOperation(CountOperation* expr) {
 
   RECURSE(Visit(expr->expression()));
 
-  NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
+  NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_)));
 
   VariableProxy* proxy = expr->expression()->AsVariableProxy();
   if (proxy != NULL && proxy->var()->IsStackAllocated()) {
@@ -668,14 +668,13 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
     case Token::BIT_AND: {
       RECURSE(Visit(expr->left()));
       RECURSE(Visit(expr->right()));
-      Handle<Type> upper(
-          Type::Union(
-              expr->left()->bounds().upper, expr->right()->bounds().upper),
+      Handle<Type> upper = Type::Union(
+          expr->left()->bounds().upper, expr->right()->bounds().upper,
           isolate_);
       if (!upper->Is(Type::Signed32()))
-        upper = handle(Type::Signed32(), isolate_);
-      Handle<Type> lower(Type::Intersect(
-          handle(Type::Smi(), isolate_), upper), isolate_);
+        upper = Type::Signed32(isolate_);
+      Handle<Type> lower =
+          Type::Intersect(Type::Smi(isolate_), upper, isolate_);
       NarrowType(expr, Bounds(lower, upper));
       break;
     }
@@ -684,7 +683,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
     case Token::SAR:
       RECURSE(Visit(expr->left()));
       RECURSE(Visit(expr->right()));
-      NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_));
+      NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Signed32(isolate_)));
       break;
     case Token::SHR:
       RECURSE(Visit(expr->left()));
@@ -692,26 +691,26 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
       // TODO(rossberg): The upper bound would be Unsigned32, but since there
       // is no 'positive Smi' type for the lower bound, we use the smallest
       // union of Smi and Unsigned32 as upper bound instead.
-      NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
+      NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_)));
       break;
     case Token::ADD: {
       RECURSE(Visit(expr->left()));
       RECURSE(Visit(expr->right()));
       Bounds l = expr->left()->bounds();
       Bounds r = expr->right()->bounds();
-      Type* lower =
+      Handle<Type> lower =
           l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ?
-              Type::None() :
+              Type::None(isolate_) :
           l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ?
-              Type::String() :
+              Type::String(isolate_) :
           l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ?
-              Type::Smi() : Type::None();
-      Type* upper =
+              Type::Smi(isolate_) : Type::None(isolate_);
+      Handle<Type> upper =
           l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ?
-              Type::String() :
+              Type::String(isolate_) :
           l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ?
-              Type::Number() : Type::NumberOrString();
-      NarrowType(expr, Bounds(lower, upper, isolate_));
+              Type::Number(isolate_) : Type::NumberOrString(isolate_);
+      NarrowType(expr, Bounds(lower, upper));
       break;
     }
     case Token::SUB:
@@ -720,7 +719,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
     case Token::MOD:
       RECURSE(Visit(expr->left()));
       RECURSE(Visit(expr->right()));
-      NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
+      NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_)));
       break;
     default:
       UNREACHABLE();
@@ -740,7 +739,7 @@ void AstTyper::VisitCompareOperation(CompareOperation* expr) {
   RECURSE(Visit(expr->left()));
   RECURSE(Visit(expr->right()));
 
-  NarrowType(expr, Bounds(Type::Boolean(), isolate_));
+  NarrowType(expr, Bounds(Type::Boolean(isolate_)));
 }
 
 
index 264d2ed881b3781c0d31e809b2b25475248c4edd..adcc156940734cd3ece867c762d4dc0fe343aaa4 100644 (file)
 using namespace v8::internal;
 
 // Testing auxiliaries (breaking the Type abstraction).
-static bool IsBitset(Type* type) { return type->IsSmi(); }
-static bool IsClass(Type* type) { return type->IsMap(); }
-static bool IsConstant(Type* type) { return type->IsBox(); }
-static bool IsUnion(Type* type) { return type->IsFixedArray(); }
+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(Type* type) { return Smi::cast(type)->value(); }
-static Map* AsClass(Type* type) { return Map::cast(type); }
-static Object* AsConstant(Type* type) { return Box::cast(type)->value(); }
-static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); }
+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(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());
+  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());
   }
   CHECK(type1->Is(type2));
   CHECK(type2->Is(type1));
@@ -66,8 +66,8 @@ static void CheckEqual(Handle<Type> type1, Handle<Type> type2) {
 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));
+  if (IsBitset(type1) && IsBitset(type2)) {
+    CHECK_NE(AsBitset(type1), AsBitset(type2));
   }
 }
 
@@ -75,8 +75,8 @@ static void CheckSub(Handle<Type> type1, Handle<Type> type2) {
 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));
+  if (IsBitset(type1) && IsBitset(type2)) {
+    CHECK_NE(AsBitset(type1), AsBitset(type2));
   }
 }
 
@@ -84,8 +84,8 @@ static void CheckUnordered(Handle<Type> type1, Handle<Type> 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));
+  if (IsBitset(type1) && IsBitset(type2)) {
+    CHECK_NE(0, AsBitset(type1) & AsBitset(type2));
   }
 }
 
@@ -95,8 +95,8 @@ static void CheckDisjoint(Handle<Type> type1, Handle<Type> 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));
+  if (IsBitset(type1) && IsBitset(type2)) {
+    CHECK_EQ(0, AsBitset(type1) & AsBitset(type2));
   }
 }
 
@@ -104,26 +104,26 @@ static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) {
 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),
+      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) {
@@ -132,14 +132,14 @@ class HandlifiedTypes {
     object1 = isolate->factory()->NewJSObjectFromMap(object_map);
     object2 = isolate->factory()->NewJSObjectFromMap(object_map);
     array = isolate->factory()->NewJSArray(20);
-    ObjectClass = Class(object_map);
-    ArrayClass = Class(array_map);
-    SmiConstant = Constant(smi);
-    Signed32Constant = Constant(signed32);
-    ObjectConstant1 = Constant(object1);
-    ObjectConstant2 = Constant(object2);
-    ArrayConstant1 = Constant(array);
-    ArrayConstant2 = Constant(array);
+    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);
   }
 
   Handle<Type> None;
@@ -182,17 +182,11 @@ class HandlifiedTypes {
   Handle<JSObject> object2;
   Handle<JSArray> array;
 
-  Handle<Type> Class(Handle<Map> map) {
-    return handle(Type::Class(map), isolate_);
+  Handle<Type> Union(Handle<Type> t1, Handle<Type> t2) {
+    return Type::Union(t1, t2, isolate_);
   }
-  Handle<Type> Constant(Handle<i::Object> value) {
-    return handle(Type::Constant(value, isolate_), isolate_);
-  }
-  Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) {
-    return handle(Type::Union(type1, type2), isolate_);
-  }
-  Handle<Type> Intersect(Handle<Type> type1, Handle<Type> type2) {
-    return handle(Type::Intersect(type1, type2), isolate_);
+  Handle<Type> Intersect(Handle<Type> t1, Handle<Type> t2) {
+    return Type::Intersect(t1, t2, isolate_);
   }
 
  private:
@@ -206,22 +200,19 @@ TEST(Bitset) {
   HandleScope scope(isolate);
   HandlifiedTypes T(isolate);
 
-  CHECK(IsBitset(*T.None));
-  CHECK(IsBitset(*T.Any));
-  CHECK(IsBitset(*T.String));
-  CHECK(IsBitset(*T.Object));
-
-  CHECK(IsBitset(Type::Union(T.String, T.Number)));
-  CHECK(IsBitset(Type::Union(T.String, T.Receiver)));
-  CHECK(IsBitset(Type::Optional(T.Object)));
-
-  CHECK_EQ(0, AsBitset(*T.None));
-  CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String),
-           AsBitset(Type::Union(T.String, T.Number)));
-  CHECK_EQ(AsBitset(*T.Receiver),
-           AsBitset(Type::Union(T.Receiver, T.Object)));
-  CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined),
-           AsBitset(Type::Optional(T.String)));
+  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)));
 }
 
 
@@ -231,11 +222,11 @@ TEST(Class) {
   HandleScope scope(isolate);
   HandlifiedTypes T(isolate);
 
-  CHECK(IsClass(*T.ObjectClass));
-  CHECK(IsClass(*T.ArrayClass));
+  CHECK(IsClass(T.ObjectClass));
+  CHECK(IsClass(T.ArrayClass));
 
-  CHECK(*T.object_map == AsClass(*T.ObjectClass));
-  CHECK(*T.array_map == AsClass(*T.ArrayClass));
+  CHECK(*T.object_map == AsClass(T.ObjectClass));
+  CHECK(*T.array_map == AsClass(T.ArrayClass));
 }
 
 
@@ -245,18 +236,18 @@ TEST(Constant) {
   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));
+  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));
 }
 
 
@@ -426,9 +417,9 @@ TEST(Union) {
   HandlifiedTypes T(isolate);
 
   // Bitset-bitset
-  CHECK(IsBitset(Type::Union(T.Object, T.Number)));
-  CHECK(IsBitset(Type::Union(T.Object, T.Object)));
-  CHECK(IsBitset(Type::Union(T.Any, T.None)));
+  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);
@@ -436,8 +427,8 @@ TEST(Union) {
   CheckSub(T.Union(T.Number, T.String), T.Any);
 
   // Class-class
-  CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass)));
-  CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass)));
+  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));
@@ -450,9 +441,9 @@ TEST(Union) {
   CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
 
   // Constant-constant
-  CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1)));
-  CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1)));
-  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2)));
+  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);
@@ -471,8 +462,8 @@ TEST(Union) {
   CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
 
   // Bitset-class
-  CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object)));
-  CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number)));
+  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));
@@ -484,9 +475,9 @@ TEST(Union) {
   CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
 
   // Bitset-constant
-  CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number)));
-  CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object)));
-  CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number)));
+  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);
@@ -500,8 +491,8 @@ TEST(Union) {
   CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
 
   // Class-constant
-  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass)));
-  CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2)));
+  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);
@@ -516,10 +507,8 @@ TEST(Union) {
   CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
 
   // Bitset-union
-  CHECK(IsBitset(
-      Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
-  CHECK(IsUnion(
-      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
+  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)),
@@ -545,9 +534,9 @@ TEST(Union) {
 
   // Class-union
   CHECK(IsUnion(
-      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
   CHECK(IsUnion(
-      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
 
   CheckEqual(
       T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
@@ -566,11 +555,11 @@ TEST(Union) {
       T.Union(T.ArrayClass, T.ObjectConstant2));
 
   // Constant-union
-  CHECK(IsUnion(Type::Union(
+  CHECK(IsUnion(T.Union(
       T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
-  CHECK(IsUnion(Type::Union(
+  CHECK(IsUnion(T.Union(
       T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
-  CHECK(IsUnion(Type::Union(
+  CHECK(IsUnion(T.Union(
       T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
 
   CheckEqual(
@@ -581,9 +570,9 @@ TEST(Union) {
       T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
 
   // Union-union
-  CHECK(IsBitset(Type::Union(
+  CHECK(IsBitset(T.Union(
       T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
-  CHECK(IsUnion(Type::Union(
+  CHECK(IsUnion(T.Union(
       T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass))));
 
   CheckEqual(
@@ -609,9 +598,9 @@ TEST(Intersect) {
   HandlifiedTypes T(isolate);
 
   // Bitset-bitset
-  CHECK(IsBitset(Type::Intersect(T.Object, T.Number)));
-  CHECK(IsBitset(Type::Intersect(T.Object, T.Object)));
-  CHECK(IsBitset(Type::Intersect(T.Any, T.None)));
+  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);
@@ -619,16 +608,16 @@ TEST(Intersect) {
   CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
 
   // Class-class
-  CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass)));
-  CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass)));
+  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(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1)));
-  CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2)));
-  CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2)));
+  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);
@@ -637,34 +626,34 @@ TEST(Intersect) {
   CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
 
   // Bitset-class
-  CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object)));
-  CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number)));
+  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(Type::Intersect(T.Smi, T.Number)));
-  CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number)));
-  CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object)));
+  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(Type::Intersect(T.ObjectConstant1, T.ObjectClass)));
-  CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2)));
+  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(
-      Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
+      T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
   CHECK(IsBitset(
-      Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
+      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
 
   CheckEqual(
       T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
@@ -675,11 +664,11 @@ TEST(Intersect) {
 
   // Class-union
   CHECK(IsClass(
-      Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
+      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
   CHECK(IsClass(
-      Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
+      T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
   CHECK(IsBitset(
-      Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
+      T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
 
   CheckEqual(
       T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
@@ -692,11 +681,11 @@ TEST(Intersect) {
       T.None);
 
   // Constant-union
-  CHECK(IsConstant(Type::Intersect(
+  CHECK(IsConstant(T.Intersect(
       T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
-  CHECK(IsConstant(Type::Intersect(
+  CHECK(IsConstant(T.Intersect(
       T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
-  CHECK(IsBitset(Type::Intersect(
+  CHECK(IsBitset(T.Intersect(
       T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
 
   CheckEqual(
@@ -711,9 +700,9 @@ TEST(Intersect) {
       T.None);
 
   // Union-union
-  CHECK(IsUnion(Type::Intersect(
+  CHECK(IsUnion(T.Intersect(
       T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
-  CHECK(IsBitset(Type::Intersect(
+  CHECK(IsBitset(T.Intersect(
       T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
 
   CheckEqual(