| Index: src/types.cc
 | 
| diff --git a/src/types.cc b/src/types.cc
 | 
| index 2f91d876c619865527b91b091d348655ca2cb5a1..29a2b99d765da58e46dcf0a5d10c5fcf2e1b9272 100644
 | 
| --- a/src/types.cc
 | 
| +++ b/src/types.cc
 | 
| @@ -15,10 +15,10 @@ int TypeImpl<Config>::NumClasses() {
 | 
|    if (this->IsClass()) {
 | 
|      return 1;
 | 
|    } else if (this->IsUnion()) {
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
|      int result = 0;
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      if (Config::struct_get(unioned, i)->IsClass()) ++result;
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      if (Config::union_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()) {
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
|      int result = 0;
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      if (Config::struct_get(unioned, i)->IsConstant()) ++result;
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      if (Config::union_get(unioned, i)->IsConstant()) ++result;
 | 
|      }
 | 
|      return result;
 | 
|    } else {
 | 
| @@ -48,8 +48,7 @@ template<class Config> template<class T>
 | 
|  typename TypeImpl<Config>::TypeHandle
 | 
|  TypeImpl<Config>::Iterator<T>::get_type() {
 | 
|    ASSERT(!Done());
 | 
| -  return type_->IsUnion()
 | 
| -      ? Config::struct_get(type_->AsUnion(), index_) : type_;
 | 
| +  return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_;
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -97,9 +96,9 @@ template<class Config> template<class T>
 | 
|  void TypeImpl<Config>::Iterator<T>::Advance() {
 | 
|    ++index_;
 | 
|    if (type_->IsUnion()) {
 | 
| -    StructHandle unioned = type_->AsUnion();
 | 
| -    for (; index_ < Config::struct_length(unioned); ++index_) {
 | 
| -      if (matches(Config::struct_get(unioned, index_))) return;
 | 
| +    UnionedHandle unioned = type_->AsUnion();
 | 
| +    for (; index_ < Config::union_length(unioned); ++index_) {
 | 
| +      if (matches(Config::union_get(unioned, index_))) return;
 | 
|      }
 | 
|    } else if (index_ == 0 && matches(type_)) {
 | 
|      return;
 | 
| @@ -114,10 +113,10 @@ int TypeImpl<Config>::LubBitset() {
 | 
|    if (this->IsBitset()) {
 | 
|      return this->AsBitset();
 | 
|    } else if (this->IsUnion()) {
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
|      int bitset = kNone;
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      bitset |= Config::struct_get(unioned, i)->LubBitset();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      bitset |= Config::union_get(unioned, i)->LubBitset();
 | 
|      }
 | 
|      return bitset;
 | 
|    } else if (this->IsClass()) {
 | 
| @@ -242,7 +241,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::struct_get(this->AsUnion(), 0)->GlbBitset();
 | 
| +    return Config::union_get(this->AsUnion(), 0)->GlbBitset();
 | 
|    } else {
 | 
|      return kNone;
 | 
|    }
 | 
| @@ -279,9 +278,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
 | 
|  
 | 
|    // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
 | 
|    if (this->IsUnion()) {
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle this_i = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle this_i = Config::union_get(unioned, i);
 | 
|        if (!this_i->Is(that)) return false;
 | 
|      }
 | 
|      return true;
 | 
| @@ -291,9 +290,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
 | 
|    // (iff T is not a union)
 | 
|    ASSERT(!this->IsUnion());
 | 
|    if (that->IsUnion()) {
 | 
| -    StructHandle unioned = that->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle that_i = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = that->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle that_i = Config::union_get(unioned, i);
 | 
|        if (this->Is(that_i)) return true;
 | 
|        if (this->IsBitset()) break;  // Fast fail, only first field is a bitset.
 | 
|      }
 | 
| @@ -326,9 +325,9 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
 | 
|  
 | 
|    // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
 | 
|    if (this->IsUnion()) {
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle this_i = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle this_i = Config::union_get(unioned, i);
 | 
|        if (this_i->Maybe(that)) return true;
 | 
|      }
 | 
|      return false;
 | 
| @@ -336,9 +335,9 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
 | 
|  
 | 
|    // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
 | 
|    if (that->IsUnion()) {
 | 
| -    StructHandle unioned = that->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle that_i = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = that->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle that_i = Config::union_get(unioned, i);
 | 
|        if (this->Maybe(that_i)) return true;
 | 
|      }
 | 
|      return false;
 | 
| @@ -374,34 +373,34 @@ bool TypeImpl<Config>::NowContains(i::Object* value) {
 | 
|  
 | 
|  
 | 
|  template<class Config>
 | 
| -bool TypeImpl<Config>::InUnion(StructHandle unioned, int current_size) {
 | 
| +bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
 | 
|    ASSERT(!this->IsUnion());
 | 
|    for (int i = 0; i < current_size; ++i) {
 | 
| -    TypeHandle type = Config::struct_get(unioned, i);
 | 
| +    TypeHandle type = Config::union_get(unioned, i);
 | 
|      if (this->Is(type)) return true;
 | 
|    }
 | 
|    return false;
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Get non-bitsets from this which are not subsumed by union, store at result,
 | 
| +// Get non-bitsets from this which are not subsumed by union, store at unioned,
 | 
|  // starting at index. Returns updated index.
 | 
|  template<class Config>
 | 
|  int TypeImpl<Config>::ExtendUnion(
 | 
| -    StructHandle result, TypeHandle type, int current_size) {
 | 
| +    UnionedHandle result, TypeHandle type, int current_size) {
 | 
|    int old_size = current_size;
 | 
|    if (type->IsClass() || type->IsConstant()) {
 | 
|      if (!type->InUnion(result, old_size)) {
 | 
| -      Config::struct_set(result, current_size++, type);
 | 
| +      Config::union_set(result, current_size++, type);
 | 
|      }
 | 
|    } else if (type->IsUnion()) {
 | 
| -    StructHandle unioned = type->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle type = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = type->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle type = Config::union_get(unioned, i);
 | 
|        ASSERT(i == 0 ||
 | 
| -             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
 | 
| +             !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
 | 
|        if (!type->IsBitset() && !type->InUnion(result, old_size)) {
 | 
| -        Config::struct_set(result, current_size++, type);
 | 
| +        Config::union_set(result, current_size++, type);
 | 
|        }
 | 
|      }
 | 
|    }
 | 
| @@ -410,6 +409,7 @@ 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::struct_length(type1->AsUnion()) : 1);
 | 
| +    size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
 | 
|    }
 | 
|    if (!type2->IsBitset()) {
 | 
| -    size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
 | 
| +    size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
 | 
|    }
 | 
|    int bitset = type1->GlbBitset() | type2->GlbBitset();
 | 
|    if (IsInhabited(bitset)) ++size;
 | 
|    ASSERT(size >= 1);
 | 
| -  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 | 
| +  UnionedHandle unioned = Config::union_create(size, region);
 | 
|  
 | 
|    size = 0;
 | 
|    if (IsInhabited(bitset)) {
 | 
| -    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
 | 
| +    Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
 | 
|    }
 | 
|    size = ExtendUnion(unioned, type1, size);
 | 
|    size = ExtendUnion(unioned, type2, size);
 | 
|  
 | 
|    if (size == 1) {
 | 
| -    return Config::struct_get(unioned, 0);
 | 
| +    return Config::union_get(unioned, 0);
 | 
|    } else {
 | 
| -    Config::struct_shrink(unioned, size);
 | 
| -    return Config::from_struct(unioned);
 | 
| +    Config::union_shrink(unioned, size);
 | 
| +    return Config::from_union(unioned);
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Get non-bitsets from type which are also in other, store at result,
 | 
| +// Get non-bitsets from type which are also in other, store at unioned,
 | 
|  // starting at index. Returns updated index.
 | 
|  template<class Config>
 | 
|  int TypeImpl<Config>::ExtendIntersection(
 | 
| -    StructHandle result, TypeHandle type, TypeHandle other, int current_size) {
 | 
| +    UnionedHandle 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::struct_set(result, current_size++, type);
 | 
| +      Config::union_set(result, current_size++, type);
 | 
|      }
 | 
|    } else if (type->IsUnion()) {
 | 
| -    StructHandle unioned = type->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle type = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = type->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle type = Config::union_get(unioned, i);
 | 
|        ASSERT(i == 0 ||
 | 
| -             !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
 | 
| +             !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
 | 
|        if (!type->IsBitset() && type->Is(other) &&
 | 
|            !type->InUnion(result, old_size)) {
 | 
| -        Config::struct_set(result, current_size++, type);
 | 
| +        Config::union_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::struct_length(type1->AsUnion()) : 1);
 | 
| +    size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
 | 
|    }
 | 
|    if (!type2->IsBitset()) {
 | 
|      size = Min(size,
 | 
| -               type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
 | 
| +               type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
 | 
|    }
 | 
|    int bitset = type1->GlbBitset() & type2->GlbBitset();
 | 
|    if (IsInhabited(bitset)) ++size;
 | 
|    ASSERT(size >= 1);
 | 
| -  StructHandle unioned = Config::struct_create(kUnionTag, size, region);
 | 
| +  UnionedHandle unioned = Config::union_create(size, region);
 | 
|  
 | 
|    size = 0;
 | 
|    if (IsInhabited(bitset)) {
 | 
| -    Config::struct_set(unioned, size++, Config::from_bitset(bitset, region));
 | 
| +    Config::union_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::struct_get(unioned, 0);
 | 
| +    return Config::union_get(unioned, 0);
 | 
|    } else {
 | 
| -    Config::struct_shrink(unioned, size);
 | 
| -    return Config::from_struct(unioned);
 | 
| +    Config::union_shrink(unioned, size);
 | 
| +    return Config::from_union(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::StructHandle unioned = type->AsUnion();
 | 
| -    int length = OtherType::StructLength(unioned);
 | 
| -    StructHandle new_unioned = Config::struct_create(kUnionTag, length, region);
 | 
| +    typename OtherType::UnionedHandle unioned = type->AsUnion();
 | 
| +    int length = OtherType::UnionLength(unioned);
 | 
| +    UnionedHandle new_unioned = Config::union_create(length, region);
 | 
|      for (int i = 0; i < length; ++i) {
 | 
| -      Config::struct_set(new_unioned, i,
 | 
| -          Convert<OtherType>(OtherType::StructGet(unioned, i), region));
 | 
| +      Config::union_set(new_unioned, i,
 | 
| +          Convert<OtherType>(OtherType::UnionGet(unioned, i), region));
 | 
|      }
 | 
| -    return Config::from_struct(new_unioned);
 | 
| +    return Config::from_union(new_unioned);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -657,9 +657,9 @@ void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
 | 
|      PrintF(out, ")");
 | 
|    } else if (this->IsUnion()) {
 | 
|      PrintF(out, "(");
 | 
| -    StructHandle unioned = this->AsUnion();
 | 
| -    for (int i = 0; i < Config::struct_length(unioned); ++i) {
 | 
| -      TypeHandle type_i = Config::struct_get(unioned, i);
 | 
| +    UnionedHandle unioned = this->AsUnion();
 | 
| +    for (int i = 0; i < Config::union_length(unioned); ++i) {
 | 
| +      TypeHandle type_i = Config::union_get(unioned, i);
 | 
|        if (i > 0) PrintF(out, " | ");
 | 
|        type_i->TypePrint(out, dim);
 | 
|      }
 | 
| 
 |