Reland "Refactoring to allow adding new structured types"
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 8 Apr 2014 10:50:56 +0000 (10:50 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 8 Apr 2014 10:50:56 +0000 (10:50 +0000)
Same as before, except that it's now using a void array instead of a struct, to shut up Clang warnings.

R=bmeurer@chromium.org
BUG=

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

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

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

index 941fda7..d6c69c4 100644 (file)
@@ -14,92 +14,32 @@ namespace v8 {
 namespace internal {
 
 // static
-ZoneTypeConfig::Tagged* ZoneTypeConfig::tagged_create(
-    Tag tag, int size, Zone* zone) {
-  Tagged* tagged = new(zone) Tagged(size + 1, zone);
-  tagged->Add(reinterpret_cast<void*>(tag), zone);
-  tagged->AddBlock(NULL, size, zone);
-  return tagged;
-}
-
-
-// static
-void ZoneTypeConfig::tagged_shrink(Tagged* tagged, int size) {
-  tagged->Rewind(size + 1);
-}
-
-
-// static
-ZoneTypeConfig::Tag ZoneTypeConfig::tagged_tag(Tagged* tagged) {
-  return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
-}
-
-
-// static
-template<class T>
-T ZoneTypeConfig::tagged_get(Tagged* tagged, int i) {
-  return reinterpret_cast<T>(tagged->at(i + 1));
-}
-
-
-// static
-template<class T>
-void ZoneTypeConfig::tagged_set(Tagged* tagged, int i, T value) {
-  tagged->at(i + 1) = reinterpret_cast<void*>(value);
-}
-
-
-// static
-int ZoneTypeConfig::tagged_length(Tagged* tagged) {
-  return tagged->length() - 1;
-}
-
-
-// static
 Type* ZoneTypeConfig::handle(Type* type) {
   return type;
 }
 
 
 // static
-bool ZoneTypeConfig::is(Type* type, Tag tag) {
-  return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
-}
-
-
-// static
 bool ZoneTypeConfig::is_bitset(Type* type) {
   return reinterpret_cast<intptr_t>(type) & 1;
 }
 
 
 // static
-bool ZoneTypeConfig::is_tagged(Type* type) {
+bool ZoneTypeConfig::is_struct(Type* type) {
   return !is_bitset(type);
 }
 
 
 // static
 bool ZoneTypeConfig::is_class(Type* type) {
-  return is(type, kClassTag);
+  return is_struct(type) && struct_tag(as_struct(type)) == Type::kClassTag;
 }
 
 
 // static
 bool ZoneTypeConfig::is_constant(Type* type) {
-  return is(type, kConstantTag);
-}
-
-
-// static
-bool ZoneTypeConfig::is_union(Type* type) {
-  return is(type, kUnionTag);
-}
-
-
-// static
-bool ZoneTypeConfig::tagged_is_union(Tagged* tagged) {
-  return is(from_tagged(tagged), kUnionTag);
+  return is_struct(type) && struct_tag(as_struct(type)) == Type::kConstantTag;
 }
 
 
@@ -111,37 +51,24 @@ int ZoneTypeConfig::as_bitset(Type* type) {
 
 
 // static
-ZoneTypeConfig::Tagged* ZoneTypeConfig::as_tagged(Type* type) {
-  ASSERT(is_tagged(type));
-  return reinterpret_cast<Tagged*>(type);
+ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
+  ASSERT(is_struct(type));
+  return reinterpret_cast<Struct*>(type);
 }
 
 
 // static
 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
   ASSERT(is_class(type));
-  return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1));
+  return i::Handle<i::Map>(static_cast<i::Map**>(as_struct(type)[3]));
 }
 
 
 // static
 i::Handle<i::Object> ZoneTypeConfig::as_constant(Type* type) {
   ASSERT(is_constant(type));
-  return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
-}
-
-
-// static
-ZoneTypeConfig::Unioned* ZoneTypeConfig::as_union(Type* type) {
-  ASSERT(is_union(type));
-  return tagged_as_union(as_tagged(type));
-}
-
-
-// static
-ZoneTypeConfig::Unioned* ZoneTypeConfig::tagged_as_union(Tagged* tagged) {
-  ASSERT(tagged_is_union(tagged));
-  return reinterpret_cast<Unioned*>(tagged);
+  return i::Handle<i::Object>(
+      static_cast<i::Object**>(as_struct(type)[3]));
 }
 
 
@@ -158,80 +85,81 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) {
 
 
 // static
-ZoneTypeConfig::Type* ZoneTypeConfig::from_tagged(Tagged* tagged) {
-  return reinterpret_cast<Type*>(tagged);
+ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) {
+  return reinterpret_cast<Type*>(structured);
 }
 
 
 // static
 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
     i::Handle<i::Map> map, int lub, Zone* zone) {
-  Tagged* tagged = tagged_create(kClassTag, 2, zone);
-  tagged_set(tagged, 0, lub);
-  tagged_set(tagged, 1, map.location());
-  return from_tagged(tagged);
+  Struct* structured = struct_create(Type::kClassTag, 2, zone);
+  structured[2] = from_bitset(lub);
+  structured[3] = map.location();
+  return from_struct(structured);
 }
 
 
 // static
 ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
     i::Handle<i::Object> value, int lub, Zone* zone) {
-  Tagged* tagged = tagged_create(kConstantTag, 2, zone);
-  tagged_set(tagged, 0, lub);
-  tagged_set(tagged, 1, value.location());
-  return from_tagged(tagged);
+  Struct* structured = struct_create(Type::kConstantTag, 2, zone);
+  structured[2] = from_bitset(lub);
+  structured[3] = value.location();
+  return from_struct(structured);
 }
 
 
 // static
-ZoneTypeConfig::Type* ZoneTypeConfig::from_union(Unioned* unioned) {
-  return from_tagged(tagged_from_union(unioned));
+ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
+    int tag, int length, Zone* zone) {
+  Struct* structured = reinterpret_cast<Struct*>(
+      zone->New(sizeof(void*) * (length + 2)));  // NOLINT
+  structured[0] = reinterpret_cast<void*>(tag);
+  structured[1] = reinterpret_cast<void*>(length);
+  return structured;
 }
 
 
 // static
-ZoneTypeConfig::Tagged* ZoneTypeConfig::tagged_from_union(Unioned* unioned) {
-  return reinterpret_cast<Tagged*>(unioned);
+void ZoneTypeConfig::struct_shrink(Struct* structured, int length) {
+  ASSERT(0 <= length && length <= struct_length(structured));
+  structured[1] = reinterpret_cast<void*>(length);
 }
 
 
 // static
-ZoneTypeConfig::Unioned* ZoneTypeConfig::union_create(int size, Zone* zone) {
-  return tagged_as_union(tagged_create(kUnionTag, size, zone));
+int ZoneTypeConfig::struct_tag(Struct* structured) {
+  int tag = reinterpret_cast<intptr_t>(structured[0]);
+  return tag;
 }
 
 
 // static
-void ZoneTypeConfig::union_shrink(Unioned* unioned, int size) {
-  tagged_shrink(tagged_from_union(unioned), size);
+int ZoneTypeConfig::struct_length(Struct* structured) {
+  int length = reinterpret_cast<intptr_t>(structured[1]);
+  return length;
 }
 
 
 // static
-ZoneTypeConfig::Type* ZoneTypeConfig::union_get(Unioned* unioned, int i) {
-  Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
-  ASSERT(!is_union(type));
-  return type;
+Type* ZoneTypeConfig::struct_get(Struct* structured, int i) {
+  ASSERT(0 <= i && i <= struct_length(structured));
+  return static_cast<Type*>(structured[2 + i]);
 }
 
 
 // static
-void ZoneTypeConfig::union_set(Unioned* unioned, int i, Type* type) {
-  ASSERT(!is_union(type));
-  tagged_set(tagged_from_union(unioned), i, type);
-}
-
-
-// static
-int ZoneTypeConfig::union_length(Unioned* unioned) {
-  return tagged_length(tagged_from_union(unioned));
+void ZoneTypeConfig::struct_set(Struct* structured, int i, Type* type) {
+  ASSERT(0 <= i && i <= struct_length(structured));
+  structured[2 + i] = type;
 }
 
 
 // static
 int ZoneTypeConfig::lub_bitset(Type* type) {
   ASSERT(is_class(type) || is_constant(type));
-  return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0));
+  return as_bitset(struct_get(as_struct(type), 0));
 }
 
 // -------------------------------------------------------------------------- //
@@ -261,7 +189,7 @@ bool HeapTypeConfig::is_constant(Type* type) {
 
 
 // static
-bool HeapTypeConfig::is_union(Type* type) {
+bool HeapTypeConfig::is_struct(Type* type) {
   return type->IsFixedArray();
 }
 
@@ -286,8 +214,8 @@ i::Handle<i::Object> HeapTypeConfig::as_constant(Type* type) {
 
 
 // static
-i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::as_union(Type* type) {
-  return i::handle(i::FixedArray::cast(type));
+i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
+  return i::handle(Struct::cast(type));
 }
 
 
@@ -320,45 +248,51 @@ i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_constant(
 
 
 // static
-i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_union(
-    i::Handle<Unioned> unioned) {
-  return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
+    i::Handle<Struct> structured) {
+  return i::Handle<Type>::cast(i::Handle<Object>::cast(structured));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
+    int tag, int length, Isolate* isolate) {
+  i::Handle<Struct> structured = isolate->factory()->NewFixedArray(length + 1);
+  structured->set(0, i::Smi::FromInt(tag));
+  return structured;
 }
 
 
 // static
-i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::union_create(
-    int size, Isolate* isolate) {
-  return isolate->factory()->NewFixedArray(size);
+void HeapTypeConfig::struct_shrink(i::Handle<Struct> structured, int length) {
+  structured->Shrink(length + 1);
 }
 
 
 // static
-void HeapTypeConfig::union_shrink(i::Handle<Unioned> unioned, int size) {
-  unioned->Shrink(size);
+int HeapTypeConfig::struct_tag(i::Handle<Struct> structured) {
+  return static_cast<i::Smi*>(structured->get(0))->value();
 }
 
 
 // static
-i::Handle<HeapTypeConfig::Type> HeapTypeConfig::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());
+int HeapTypeConfig::struct_length(i::Handle<Struct> structured) {
+  return structured->length() - 1;
 }
 
 
 // static
-void HeapTypeConfig::union_set(
-    i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
-  ASSERT(!is_union(*type));
-  unioned->set(i, *type);
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
+    i::Handle<Struct> structured, int i) {
+  Type* type = static_cast<Type*>(structured->get(i + 1));
+  return i::handle(type, structured->GetIsolate());
 }
 
 
 // static
-int HeapTypeConfig::union_length(i::Handle<Unioned> unioned) {
-  return unioned->length();
+void HeapTypeConfig::struct_set(
+    i::Handle<Struct> structured, int i, i::Handle<Type> type) {
+  structured->set(i + 1, *type);
 }
 
 
index 29a2b99..2f91d87 100644 (file)
@@ -15,10 +15,10 @@ int TypeImpl<Config>::NumClasses() {
   if (this->IsClass()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
+    StructHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      if (Config::union_get(unioned, i)->IsClass()) ++result;
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      if (Config::struct_get(unioned, i)->IsClass()) ++result;
     }
     return result;
   } else {
@@ -32,10 +32,10 @@ int TypeImpl<Config>::NumConstants() {
   if (this->IsConstant()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
+    StructHandle unioned = this->AsUnion();
     int result = 0;
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      if (Config::union_get(unioned, i)->IsConstant()) ++result;
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      if (Config::struct_get(unioned, i)->IsConstant()) ++result;
     }
     return result;
   } else {
@@ -48,7 +48,8 @@ template<class Config> template<class T>
 typename TypeImpl<Config>::TypeHandle
 TypeImpl<Config>::Iterator<T>::get_type() {
   ASSERT(!Done());
-  return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_;
+  return type_->IsUnion()
+      ? Config::struct_get(type_->AsUnion(), index_) : type_;
 }
 
 
@@ -96,9 +97,9 @@ template<class Config> template<class T>
 void TypeImpl<Config>::Iterator<T>::Advance() {
   ++index_;
   if (type_->IsUnion()) {
-    UnionedHandle unioned = type_->AsUnion();
-    for (; index_ < Config::union_length(unioned); ++index_) {
-      if (matches(Config::union_get(unioned, 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;
@@ -113,10 +114,10 @@ int TypeImpl<Config>::LubBitset() {
   if (this->IsBitset()) {
     return this->AsBitset();
   } else if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
+    StructHandle unioned = this->AsUnion();
     int bitset = kNone;
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      bitset |= Config::union_get(unioned, i)->LubBitset();
+    for (int i = 0; i < Config::struct_length(unioned); ++i) {
+      bitset |= Config::struct_get(unioned, i)->LubBitset();
     }
     return bitset;
   } else if (this->IsClass()) {
@@ -241,7 +242,7 @@ int TypeImpl<Config>::GlbBitset() {
     return this->AsBitset();
   } else if (this->IsUnion()) {
     // All but the first are non-bitsets and thus would yield kNone anyway.
-    return Config::union_get(this->AsUnion(), 0)->GlbBitset();
+    return Config::struct_get(this->AsUnion(), 0)->GlbBitset();
   } else {
     return kNone;
   }
@@ -278,9 +279,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
 
   // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
   if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle this_i = Config::union_get(unioned, i);
+    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;
@@ -290,9 +291,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
   // (iff T is not a union)
   ASSERT(!this->IsUnion());
   if (that->IsUnion()) {
-    UnionedHandle unioned = that->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle that_i = Config::union_get(unioned, i);
+    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.
     }
@@ -325,9 +326,9 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
 
   // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
   if (this->IsUnion()) {
-    UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle this_i = Config::union_get(unioned, i);
+    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;
@@ -335,9 +336,9 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
 
   // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
   if (that->IsUnion()) {
-    UnionedHandle unioned = that->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle that_i = Config::union_get(unioned, i);
+    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;
@@ -373,34 +374,34 @@ bool TypeImpl<Config>::NowContains(i::Object* value) {
 
 
 template<class Config>
-bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
+bool TypeImpl<Config>::InUnion(StructHandle unioned, int current_size) {
   ASSERT(!this->IsUnion());
   for (int i = 0; i < current_size; ++i) {
-    TypeHandle type = Config::union_get(unioned, i);
+    TypeHandle type = Config::struct_get(unioned, i);
     if (this->Is(type)) return true;
   }
   return false;
 }
 
 
-// Get non-bitsets from this which are not subsumed by union, store at unioned,
+// Get non-bitsets from this which are not subsumed by union, store at result,
 // starting at index. Returns updated index.
 template<class Config>
 int TypeImpl<Config>::ExtendUnion(
-    UnionedHandle result, TypeHandle type, int current_size) {
+    StructHandle result, TypeHandle type, int current_size) {
   int old_size = current_size;
   if (type->IsClass() || type->IsConstant()) {
     if (!type->InUnion(result, old_size)) {
-      Config::union_set(result, current_size++, type);
+      Config::struct_set(result, current_size++, type);
     }
   } else if (type->IsUnion()) {
-    UnionedHandle unioned = type->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle type = Config::union_get(unioned, i);
+    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::union_get(unioned, 0))));
+             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
       if (!type->IsBitset() && !type->InUnion(result, old_size)) {
-        Config::union_set(result, current_size++, type);
+        Config::struct_set(result, current_size++, type);
       }
     }
   }
@@ -409,7 +410,6 @@ int TypeImpl<Config>::ExtendUnion(
 
 
 // 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?
 template<class Config>
 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
     TypeHandle type1, TypeHandle type2, Region* region) {
@@ -431,51 +431,51 @@ 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() ? Config::union_length(type1->AsUnion()) : 1);
+    size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
-    size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
+    size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
   }
   int bitset = type1->GlbBitset() | type2->GlbBitset();
   if (IsInhabited(bitset)) ++size;
   ASSERT(size >= 1);
-  UnionedHandle unioned = Config::union_create(size, region);
+  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 
   size = 0;
   if (IsInhabited(bitset)) {
-    Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendUnion(unioned, type1, size);
   size = ExtendUnion(unioned, type2, size);
 
   if (size == 1) {
-    return Config::union_get(unioned, 0);
+    return Config::struct_get(unioned, 0);
   } else {
-    Config::union_shrink(unioned, size);
-    return Config::from_union(unioned);
+    Config::struct_shrink(unioned, size);
+    return Config::from_struct(unioned);
   }
 }
 
 
-// Get non-bitsets from type which are also in other, store at unioned,
+// Get non-bitsets from type which are also in other, store at result,
 // starting at index. Returns updated index.
 template<class Config>
 int TypeImpl<Config>::ExtendIntersection(
-    UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
+    StructHandle result, TypeHandle type, TypeHandle other, int current_size) {
   int old_size = current_size;
   if (type->IsClass() || type->IsConstant()) {
     if (type->Is(other) && !type->InUnion(result, old_size)) {
-      Config::union_set(result, current_size++, type);
+      Config::struct_set(result, current_size++, type);
     }
   } else if (type->IsUnion()) {
-    UnionedHandle unioned = type->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle type = Config::union_get(unioned, i);
+    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::union_get(unioned, 0))));
+             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
       if (!type->IsBitset() && type->Is(other) &&
           !type->InUnion(result, old_size)) {
-        Config::union_set(result, current_size++, type);
+        Config::struct_set(result, current_size++, type);
       }
     }
   }
@@ -506,20 +506,20 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
   // Slow case: may need to produce a Unioned object.
   int size = INT_MAX;
   if (!type1->IsBitset()) {
-    size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
+    size = (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
   }
   if (!type2->IsBitset()) {
     size = Min(size,
-               type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
+               type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
   }
   int bitset = type1->GlbBitset() & type2->GlbBitset();
   if (IsInhabited(bitset)) ++size;
   ASSERT(size >= 1);
-  UnionedHandle unioned = Config::union_create(size, region);
+  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 
   size = 0;
   if (IsInhabited(bitset)) {
-    Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
   }
   size = ExtendIntersection(unioned, type1, type2, size);
   size = ExtendIntersection(unioned, type2, type1, size);
@@ -527,10 +527,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
   if (size == 0) {
     return None(region);
   } else if (size == 1) {
-    return Config::union_get(unioned, 0);
+    return Config::struct_get(unioned, 0);
   } else {
-    Config::union_shrink(unioned, size);
-    return Config::from_union(unioned);
+    Config::struct_shrink(unioned, size);
+    return Config::from_struct(unioned);
   }
 }
 
@@ -547,14 +547,14 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
     return Config::from_constant(type->AsConstant(), type->LubBitset(), region);
   } else {
     ASSERT(type->IsUnion());
-    typename OtherType::UnionedHandle unioned = type->AsUnion();
-    int length = OtherType::UnionLength(unioned);
-    UnionedHandle new_unioned = Config::union_create(length, region);
+    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) {
-      Config::union_set(new_unioned, i,
-          Convert<OtherType>(OtherType::UnionGet(unioned, i), region));
+      Config::struct_set(new_unioned, i,
+          Convert<OtherType>(OtherType::StructGet(unioned, i), region));
     }
-    return Config::from_union(new_unioned);
+    return Config::from_struct(new_unioned);
   }
 }
 
@@ -657,9 +657,9 @@ void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
     PrintF(out, ")");
   } else if (this->IsUnion()) {
     PrintF(out, "(");
-    UnionedHandle unioned = this->AsUnion();
-    for (int i = 0; i < Config::union_length(unioned); ++i) {
-      TypeHandle type_i = Config::union_get(unioned, 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);
     }
index 7f4d706..0161582 100644 (file)
@@ -164,28 +164,29 @@ namespace internal {
 
 // struct Config {
 //   typedef Base;
-//   typedef Unioned;
+//   typedef Struct;
 //   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*);
 //   static bool is_class(Type*);
 //   static bool is_constant(Type*);
-//   static bool is_union(Type*);
+//   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*);
-//   static Handle<Unioned>::type as_union(Type*);
+//   static Handle<Struct>::type as_struct(Type*);
 //   static Type* from_bitset(int bitset);
 //   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_union(Handle<Unioned>::type);
-//   static Handle<Unioned>::type union_create(int size, Region*);
-//   static void union_shrink(Handle<Unioned>::type, int size);
-//   static Handle<Type>::type union_get(Handle<Unioned>::type, int);
-//   static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
-//   static int union_length(Handle<Unioned>::type);
+//   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);
+//   static int struct_length(Handle<Struct>::type);
+//   static Handle<Type>::type struct_get(Handle<Struct>::type, int);
+//   static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
 //   static int lub_bitset(Type*);
 // }
 template<class Config>
@@ -299,13 +300,22 @@ class TypeImpl : public Config::Base {
  private:
   template<class> friend class Iterator;
   template<class> friend class TypeImpl;
+  friend struct ZoneTypeConfig;
+  friend struct HeapTypeConfig;
 
-  // A union is a fixed array containing types. Invariants:
+  enum Tag {
+    kClassTag,
+    kConstantTag,
+    kUnionTag
+  };
+
+  // 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::Unioned Unioned;
-  typedef typename Config::template Handle<Unioned>::type UnionedHandle;
+  typedef typename Config::Struct Struct;
+  typedef typename Config::template Handle<Struct>::type StructHandle;
 
   enum {
     #define DECLARE_TYPE(type, value) k##type = (value),
@@ -317,15 +327,24 @@ class TypeImpl : public Config::Base {
   bool IsNone() { return this == None(); }
   bool IsAny() { return this == Any(); }
   bool IsBitset() { return Config::is_bitset(this); }
-  bool IsUnion() { return Config::is_union(this); }
+  bool IsStruct(Tag tag) {
+    return Config::is_struct(this)
+        && Config::struct_tag(Config::as_struct(this)) == tag;
+  }
+  bool IsUnion() { return IsStruct(kUnionTag); }
+
   int AsBitset() { return Config::as_bitset(this); }
-  UnionedHandle AsUnion() { return Config::as_union(this); }
+  StructHandle AsStruct(Tag tag) {
+    ASSERT(IsStruct(tag));
+    return Config::as_struct(this);
+  }
+  StructHandle AsUnion() { return AsStruct(kUnionTag); }
 
-  static int UnionLength(UnionedHandle unioned) {
-    return Config::union_length(unioned);
+  static int StructLength(StructHandle structured) {
+    return Config::struct_length(structured);
   }
-  static TypeHandle UnionGet(UnionedHandle unioned, int i) {
-    return Config::union_get(unioned, i);
+  static TypeHandle StructGet(StructHandle structured, int i) {
+    return Config::struct_get(structured, i);
   }
 
   bool SlowIs(TypeImpl* that);
@@ -340,11 +359,11 @@ class TypeImpl : public Config::Base {
   static int LubBitset(i::Object* value);
   static int LubBitset(i::Map* map);
 
-  bool InUnion(UnionedHandle unioned, int current_size);
+  bool InUnion(StructHandle unioned, int current_size);
   static int ExtendUnion(
-      UnionedHandle unioned, TypeHandle t, int current_size);
+      StructHandle unioned, TypeHandle t, int current_size);
   static int ExtendIntersection(
-      UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
+      StructHandle unioned, TypeHandle t, TypeHandle other, int current_size);
 
   static const char* bitset_name(int bitset);
   static void BitsetTypePrint(FILE* out, int bitset);
@@ -352,59 +371,35 @@ class TypeImpl : public Config::Base {
 
 
 // Zone-allocated types are either (odd) integers to represent bitsets, or
-// (even) pointers to zone lists for everything else. The first slot of every
-// list is an explicit tag value to distinguish representation.
+// (even) pointers to structures for everything else.
 struct ZoneTypeConfig {
- private:
-  typedef i::ZoneList<void*> Tagged;
-
-  enum Tag {
-    kClassTag,
-    kConstantTag,
-    kUnionTag
-  };
-
-  static inline Tagged* tagged_create(Tag tag, int size, Zone* zone);
-  static inline void tagged_shrink(Tagged* tagged, int size);
-  static inline Tag tagged_tag(Tagged* tagged);
-  template<class T> static inline T tagged_get(Tagged* tagged, int i);
-  template<class T> static inline void tagged_set(Tagged* tagged, int i, T val);
-  static inline int tagged_length(Tagged* tagged);
-
- public:
   typedef TypeImpl<ZoneTypeConfig> Type;
   class Base {};
-  typedef i::ZoneList<Type*> Unioned;
+  typedef void* Struct;
   typedef i::Zone Region;
   template<class T> struct Handle { typedef T* type; };
 
   static inline Type* handle(Type* type);
-  static inline bool is(Type* type, Tag tag);
   static inline bool is_bitset(Type* type);
-  static inline bool is_tagged(Type* type);
   static inline bool is_class(Type* type);
   static inline bool is_constant(Type* type);
-  static inline bool is_union(Type* type);
-  static inline bool tagged_is_union(Tagged* tagged);
+  static inline bool is_struct(Type* type);
   static inline int as_bitset(Type* type);
-  static inline Tagged* as_tagged(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 Unioned* as_union(Type* type);
-  static inline Unioned* tagged_as_union(Tagged* tagged);
   static inline Type* from_bitset(int bitset);
   static inline Type* from_bitset(int bitset, Zone* zone);
-  static inline Type* from_tagged(Tagged* tagged);
+  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 Type* from_union(Unioned* unioned);
-  static inline Tagged* tagged_from_union(Unioned* unioned);
-  static inline Unioned* union_create(int size, Zone* zone);
-  static inline void union_shrink(Unioned* unioned, int size);
-  static inline Type* union_get(Unioned* unioned, int i);
-  static inline void union_set(Unioned* unioned, int i, Type* type);
-  static inline int union_length(Unioned* unioned);
+  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);
 };
 
@@ -416,7 +411,7 @@ typedef TypeImpl<ZoneTypeConfig> Type;
 struct HeapTypeConfig {
   typedef TypeImpl<HeapTypeConfig> Type;
   typedef i::Object Base;
-  typedef i::FixedArray Unioned;
+  typedef i::FixedArray Struct;
   typedef i::Isolate Region;
   template<class T> struct Handle { typedef i::Handle<T> type; };
 
@@ -424,24 +419,26 @@ struct HeapTypeConfig {
   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_union(Type* type);
+  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<Unioned> as_union(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(
       i::Handle<i::Map> map, int lub, Isolate* isolate);
   static inline i::Handle<Type> from_constant(
       i::Handle<i::Object> value, int lub, Isolate* isolate);
-  static inline i::Handle<Type> from_union(i::Handle<Unioned> unioned);
-  static inline i::Handle<Unioned> union_create(int size, Isolate* isolate);
-  static inline void union_shrink(i::Handle<Unioned> unioned, int size);
-  static inline i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i);
-  static inline void union_set(
-      i::Handle<Unioned> unioned, int i, i::Handle<Type> type);
-  static inline int union_length(i::Handle<Unioned> unioned);
+  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);
+  static inline int struct_tag(i::Handle<Struct> structured);
+  static inline int struct_length(i::Handle<Struct> structured);
+  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 cdaa95b..e45a1c7 100644 (file)
@@ -176,49 +176,56 @@ class Types {
 
 // Testing auxiliaries (breaking the Type abstraction).
 struct ZoneRep {
-  static bool IsTagged(Type* t, int tag) {
-    return !IsBitset(t)
-        && reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag;
+  struct Struct { int tag; int length; void* args[1]; };
+
+  static bool IsStruct(Type* t, int tag) {
+    return !IsBitset(t) && AsStruct(t)->tag == tag;
   }
   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
-  static bool IsClass(Type* t) { return IsTagged(t, 0); }
-  static bool IsConstant(Type* t) { return IsTagged(t, 1); }
-  static bool IsUnion(Type* t) { return IsTagged(t, 2); }
+  static bool IsClass(Type* t) { return IsStruct(t, 0); }
+  static bool IsConstant(Type* t) { return IsStruct(t, 1); }
+  static bool IsUnion(Type* t) { return IsStruct(t, 2); }
 
-  static ZoneList<void*>* AsTagged(Type* t) {
-    return reinterpret_cast<ZoneList<void*>*>(t);
+  static Struct* AsStruct(Type* t) {
+    return reinterpret_cast<Struct*>(t);
   }
   static int AsBitset(Type* t) {
     return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
   }
   static Map* AsClass(Type* t) {
-    return *reinterpret_cast<Map**>(AsTagged(t)->at(2));
+    return *static_cast<Map**>(AsStruct(t)->args[1]);
   }
   static Object* AsConstant(Type* t) {
-    return *reinterpret_cast<Object**>(AsTagged(t)->at(2));
+    return *static_cast<Object**>(AsStruct(t)->args[1]);
   }
-  static ZoneList<Type*>* AsUnion(Type* t) {
-    return reinterpret_cast<ZoneList<Type*>*>(AsTagged(t));
+  static Struct* AsUnion(Type* t) {
+    return AsStruct(t);
   }
+  static int Length(Struct* structured) { return structured->length; }
 
   static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
 };
 
 
 struct HeapRep {
+  typedef FixedArray Struct;
+
+  static bool IsStruct(Handle<HeapType> t, int tag) {
+    return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
+  }
   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 IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); }
+  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(); }
   static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
   static Object* AsConstant(Handle<HeapType> t) {
     return Box::cast(*t)->value();
   }
-  static FixedArray* AsUnion(Handle<HeapType> t) {
-    return FixedArray::cast(*t);
-  }
+  static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
+  static int Length(Struct* structured) { return structured->length() - 1; }
 
   static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
 };
@@ -252,7 +259,8 @@ struct Tests : Rep {
     } else if (Rep::IsConstant(type1)) {
       CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2));
     } else if (Rep::IsUnion(type1)) {
-      CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length());
+      CHECK_EQ(
+          Rep::Length(Rep::AsUnion(type1)), Rep::Length(Rep::AsUnion(type2)));
     }
     CHECK(type1->Is(type2));
     CHECK(type2->Is(type1));