Revert "Refactoring to allow adding new structured types"
This reverts commit r20538 for breaking gcmole. TBR=rossberg@chromium.org BUG= Review URL: https://codereview.chromium.org/228223002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20562 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f7bb456035
commit
1d138ecdd5
204
src/types-inl.h
204
src/types-inl.h
@ -13,12 +13,60 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
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
|
// static
|
||||||
Type* ZoneTypeConfig::handle(Type* type) {
|
Type* ZoneTypeConfig::handle(Type* type) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool ZoneTypeConfig::is(Type* type, Tag tag) {
|
||||||
|
return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool ZoneTypeConfig::is_bitset(Type* type) {
|
bool ZoneTypeConfig::is_bitset(Type* type) {
|
||||||
return reinterpret_cast<intptr_t>(type) & 1;
|
return reinterpret_cast<intptr_t>(type) & 1;
|
||||||
@ -26,20 +74,32 @@ bool ZoneTypeConfig::is_bitset(Type* type) {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool ZoneTypeConfig::is_struct(Type* type) {
|
bool ZoneTypeConfig::is_tagged(Type* type) {
|
||||||
return !is_bitset(type);
|
return !is_bitset(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool ZoneTypeConfig::is_class(Type* type) {
|
bool ZoneTypeConfig::is_class(Type* type) {
|
||||||
return is_struct(type) && struct_tag(as_struct(type)) == Type::kClassTag;
|
return is(type, kClassTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool ZoneTypeConfig::is_constant(Type* type) {
|
bool ZoneTypeConfig::is_constant(Type* type) {
|
||||||
return is_struct(type) && struct_tag(as_struct(type)) == Type::kConstantTag;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -51,24 +111,37 @@ int ZoneTypeConfig::as_bitset(Type* type) {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
|
ZoneTypeConfig::Tagged* ZoneTypeConfig::as_tagged(Type* type) {
|
||||||
ASSERT(is_struct(type));
|
ASSERT(is_tagged(type));
|
||||||
return reinterpret_cast<Struct*>(type);
|
return reinterpret_cast<Tagged*>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
|
i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
|
||||||
ASSERT(is_class(type));
|
ASSERT(is_class(type));
|
||||||
return i::Handle<i::Map>(static_cast<i::Map**>(as_struct(type)->args[1]));
|
return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<i::Object> ZoneTypeConfig::as_constant(Type* type) {
|
i::Handle<i::Object> ZoneTypeConfig::as_constant(Type* type) {
|
||||||
ASSERT(is_constant(type));
|
ASSERT(is_constant(type));
|
||||||
return i::Handle<i::Object>(
|
return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
|
||||||
static_cast<i::Object**>(as_struct(type)->args[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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,79 +158,80 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) {
|
ZoneTypeConfig::Type* ZoneTypeConfig::from_tagged(Tagged* tagged) {
|
||||||
return reinterpret_cast<Type*>(structured);
|
return reinterpret_cast<Type*>(tagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
|
ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
|
||||||
i::Handle<i::Map> map, int lub, Zone* zone) {
|
i::Handle<i::Map> map, int lub, Zone* zone) {
|
||||||
Struct* structured = struct_create(Type::kClassTag, 2, zone);
|
Tagged* tagged = tagged_create(kClassTag, 2, zone);
|
||||||
structured->args[0] = from_bitset(lub);
|
tagged_set(tagged, 0, lub);
|
||||||
structured->args[1] = map.location();
|
tagged_set(tagged, 1, map.location());
|
||||||
return from_struct(structured);
|
return from_tagged(tagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
|
ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
|
||||||
i::Handle<i::Object> value, int lub, Zone* zone) {
|
i::Handle<i::Object> value, int lub, Zone* zone) {
|
||||||
Struct* structured = struct_create(Type::kConstantTag, 2, zone);
|
Tagged* tagged = tagged_create(kConstantTag, 2, zone);
|
||||||
structured->args[0] = from_bitset(lub);
|
tagged_set(tagged, 0, lub);
|
||||||
structured->args[1] = value.location();
|
tagged_set(tagged, 1, value.location());
|
||||||
return from_struct(structured);
|
return from_tagged(tagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
|
ZoneTypeConfig::Type* ZoneTypeConfig::from_union(Unioned* unioned) {
|
||||||
int tag, int length, Zone* zone) {
|
return from_tagged(tagged_from_union(unioned));
|
||||||
Struct* structured = reinterpret_cast<Struct*>(
|
|
||||||
zone->New(sizeof(Struct) + sizeof(void*) * (length - 1))); // NOLINT
|
|
||||||
structured->tag = tag;
|
|
||||||
structured->length = length;
|
|
||||||
return structured;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void ZoneTypeConfig::struct_shrink(Struct* structured, int length) {
|
ZoneTypeConfig::Tagged* ZoneTypeConfig::tagged_from_union(Unioned* unioned) {
|
||||||
ASSERT(0 <= length && length <= structured->length);
|
return reinterpret_cast<Tagged*>(unioned);
|
||||||
structured->length = length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int ZoneTypeConfig::struct_tag(Struct* structured) {
|
ZoneTypeConfig::Unioned* ZoneTypeConfig::union_create(int size, Zone* zone) {
|
||||||
return structured->tag;
|
return tagged_as_union(tagged_create(kUnionTag, size, zone));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Type* ZoneTypeConfig::struct_get(Struct* structured, int i) {
|
void ZoneTypeConfig::union_shrink(Unioned* unioned, int size) {
|
||||||
ASSERT(0 <= i && i < structured->length);
|
tagged_shrink(tagged_from_union(unioned), size);
|
||||||
return static_cast<Type*>(structured->args[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void ZoneTypeConfig::struct_set(Struct* structured, int i, Type* type) {
|
ZoneTypeConfig::Type* ZoneTypeConfig::union_get(Unioned* unioned, int i) {
|
||||||
ASSERT(0 <= i && i < structured->length);
|
Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
|
||||||
structured->args[i] = type;
|
ASSERT(!is_union(type));
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int ZoneTypeConfig::struct_length(Struct* structured) {
|
void ZoneTypeConfig::union_set(Unioned* unioned, int i, Type* type) {
|
||||||
return structured->length;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int ZoneTypeConfig::lub_bitset(Type* type) {
|
int ZoneTypeConfig::lub_bitset(Type* type) {
|
||||||
ASSERT(is_class(type) || is_constant(type));
|
ASSERT(is_class(type) || is_constant(type));
|
||||||
return as_bitset(struct_get(as_struct(type), 0));
|
return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
@ -187,7 +261,7 @@ bool HeapTypeConfig::is_constant(Type* type) {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool HeapTypeConfig::is_struct(Type* type) {
|
bool HeapTypeConfig::is_union(Type* type) {
|
||||||
return type->IsFixedArray();
|
return type->IsFixedArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +286,8 @@ i::Handle<i::Object> HeapTypeConfig::as_constant(Type* type) {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
|
i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::as_union(Type* type) {
|
||||||
return i::handle(Struct::cast(type));
|
return i::handle(i::FixedArray::cast(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -246,51 +320,45 @@ i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_constant(
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
|
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_union(
|
||||||
i::Handle<Struct> structured) {
|
i::Handle<Unioned> unioned) {
|
||||||
return i::Handle<Type>::cast(i::Handle<Object>::cast(structured));
|
return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
|
i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::union_create(
|
||||||
int tag, int length, Isolate* isolate) {
|
int size, Isolate* isolate) {
|
||||||
i::Handle<Struct> structured = isolate->factory()->NewFixedArray(length + 1);
|
return isolate->factory()->NewFixedArray(size);
|
||||||
structured->set(0, i::Smi::FromInt(tag));
|
|
||||||
return structured;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void HeapTypeConfig::struct_shrink(i::Handle<Struct> structured, int length) {
|
void HeapTypeConfig::union_shrink(i::Handle<Unioned> unioned, int size) {
|
||||||
structured->Shrink(length + 1);
|
unioned->Shrink(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int HeapTypeConfig::struct_tag(i::Handle<Struct> structured) {
|
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::union_get(
|
||||||
return static_cast<i::Smi*>(structured->get(0))->value();
|
i::Handle<Unioned> unioned, int i) {
|
||||||
|
Type* type = static_cast<Type*>(unioned->get(i));
|
||||||
|
ASSERT(!is_union(type));
|
||||||
|
return i::handle(type, unioned->GetIsolate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
|
void HeapTypeConfig::union_set(
|
||||||
i::Handle<Struct> structured, int i) {
|
i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
|
||||||
Type* type = static_cast<Type*>(structured->get(i + 1));
|
ASSERT(!is_union(*type));
|
||||||
return i::handle(type, structured->GetIsolate());
|
unioned->set(i, *type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void HeapTypeConfig::struct_set(
|
int HeapTypeConfig::union_length(i::Handle<Unioned> unioned) {
|
||||||
i::Handle<Struct> structured, int i, i::Handle<Type> type) {
|
return unioned->length();
|
||||||
structured->set(i + 1, *type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
|
||||||
int HeapTypeConfig::struct_length(i::Handle<Struct> structured) {
|
|
||||||
return structured->length() - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
136
src/types.cc
136
src/types.cc
@ -15,10 +15,10 @@ int TypeImpl<Config>::NumClasses() {
|
|||||||
if (this->IsClass()) {
|
if (this->IsClass()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (this->IsUnion()) {
|
} else if (this->IsUnion()) {
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
if (Config::struct_get(unioned, i)->IsClass()) ++result;
|
if (Config::union_get(unioned, i)->IsClass()) ++result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@ -32,10 +32,10 @@ int TypeImpl<Config>::NumConstants() {
|
|||||||
if (this->IsConstant()) {
|
if (this->IsConstant()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (this->IsUnion()) {
|
} else if (this->IsUnion()) {
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
if (Config::struct_get(unioned, i)->IsConstant()) ++result;
|
if (Config::union_get(unioned, i)->IsConstant()) ++result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@ -48,8 +48,7 @@ template<class Config> template<class T>
|
|||||||
typename TypeImpl<Config>::TypeHandle
|
typename TypeImpl<Config>::TypeHandle
|
||||||
TypeImpl<Config>::Iterator<T>::get_type() {
|
TypeImpl<Config>::Iterator<T>::get_type() {
|
||||||
ASSERT(!Done());
|
ASSERT(!Done());
|
||||||
return type_->IsUnion()
|
return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_;
|
||||||
? Config::struct_get(type_->AsUnion(), index_) : type_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,9 +96,9 @@ template<class Config> template<class T>
|
|||||||
void TypeImpl<Config>::Iterator<T>::Advance() {
|
void TypeImpl<Config>::Iterator<T>::Advance() {
|
||||||
++index_;
|
++index_;
|
||||||
if (type_->IsUnion()) {
|
if (type_->IsUnion()) {
|
||||||
StructHandle unioned = type_->AsUnion();
|
UnionedHandle unioned = type_->AsUnion();
|
||||||
for (; index_ < Config::struct_length(unioned); ++index_) {
|
for (; index_ < Config::union_length(unioned); ++index_) {
|
||||||
if (matches(Config::struct_get(unioned, index_))) return;
|
if (matches(Config::union_get(unioned, index_))) return;
|
||||||
}
|
}
|
||||||
} else if (index_ == 0 && matches(type_)) {
|
} else if (index_ == 0 && matches(type_)) {
|
||||||
return;
|
return;
|
||||||
@ -114,10 +113,10 @@ int TypeImpl<Config>::LubBitset() {
|
|||||||
if (this->IsBitset()) {
|
if (this->IsBitset()) {
|
||||||
return this->AsBitset();
|
return this->AsBitset();
|
||||||
} else if (this->IsUnion()) {
|
} else if (this->IsUnion()) {
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
int bitset = kNone;
|
int bitset = kNone;
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
bitset |= Config::struct_get(unioned, i)->LubBitset();
|
bitset |= Config::union_get(unioned, i)->LubBitset();
|
||||||
}
|
}
|
||||||
return bitset;
|
return bitset;
|
||||||
} else if (this->IsClass()) {
|
} else if (this->IsClass()) {
|
||||||
@ -242,7 +241,7 @@ int TypeImpl<Config>::GlbBitset() {
|
|||||||
return this->AsBitset();
|
return this->AsBitset();
|
||||||
} else if (this->IsUnion()) {
|
} else if (this->IsUnion()) {
|
||||||
// All but the first are non-bitsets and thus would yield kNone anyway.
|
// 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 {
|
} else {
|
||||||
return kNone;
|
return kNone;
|
||||||
}
|
}
|
||||||
@ -279,9 +278,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
|
|||||||
|
|
||||||
// (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T)
|
// (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T)
|
||||||
if (this->IsUnion()) {
|
if (this->IsUnion()) {
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle this_i = Config::struct_get(unioned, i);
|
TypeHandle this_i = Config::union_get(unioned, i);
|
||||||
if (!this_i->Is(that)) return false;
|
if (!this_i->Is(that)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -291,9 +290,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
|
|||||||
// (iff T is not a union)
|
// (iff T is not a union)
|
||||||
ASSERT(!this->IsUnion());
|
ASSERT(!this->IsUnion());
|
||||||
if (that->IsUnion()) {
|
if (that->IsUnion()) {
|
||||||
StructHandle unioned = that->AsUnion();
|
UnionedHandle unioned = that->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle that_i = Config::struct_get(unioned, i);
|
TypeHandle that_i = Config::union_get(unioned, i);
|
||||||
if (this->Is(that_i)) return true;
|
if (this->Is(that_i)) return true;
|
||||||
if (this->IsBitset()) break; // Fast fail, only first field is a bitset.
|
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)
|
// (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
|
||||||
if (this->IsUnion()) {
|
if (this->IsUnion()) {
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle this_i = Config::struct_get(unioned, i);
|
TypeHandle this_i = Config::union_get(unioned, i);
|
||||||
if (this_i->Maybe(that)) return true;
|
if (this_i->Maybe(that)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -336,9 +335,9 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
|
|||||||
|
|
||||||
// T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
|
// T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
|
||||||
if (that->IsUnion()) {
|
if (that->IsUnion()) {
|
||||||
StructHandle unioned = that->AsUnion();
|
UnionedHandle unioned = that->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle that_i = Config::struct_get(unioned, i);
|
TypeHandle that_i = Config::union_get(unioned, i);
|
||||||
if (this->Maybe(that_i)) return true;
|
if (this->Maybe(that_i)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -374,34 +373,34 @@ bool TypeImpl<Config>::NowContains(i::Object* value) {
|
|||||||
|
|
||||||
|
|
||||||
template<class Config>
|
template<class Config>
|
||||||
bool TypeImpl<Config>::InUnion(StructHandle unioned, int current_size) {
|
bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
|
||||||
ASSERT(!this->IsUnion());
|
ASSERT(!this->IsUnion());
|
||||||
for (int i = 0; i < current_size; ++i) {
|
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;
|
if (this->Is(type)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
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.
|
// starting at index. Returns updated index.
|
||||||
template<class Config>
|
template<class Config>
|
||||||
int TypeImpl<Config>::ExtendUnion(
|
int TypeImpl<Config>::ExtendUnion(
|
||||||
StructHandle result, TypeHandle type, int current_size) {
|
UnionedHandle result, TypeHandle type, int current_size) {
|
||||||
int old_size = current_size;
|
int old_size = current_size;
|
||||||
if (type->IsClass() || type->IsConstant()) {
|
if (type->IsClass() || type->IsConstant()) {
|
||||||
if (!type->InUnion(result, old_size)) {
|
if (!type->InUnion(result, old_size)) {
|
||||||
Config::struct_set(result, current_size++, type);
|
Config::union_set(result, current_size++, type);
|
||||||
}
|
}
|
||||||
} else if (type->IsUnion()) {
|
} else if (type->IsUnion()) {
|
||||||
StructHandle unioned = type->AsUnion();
|
UnionedHandle unioned = type->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle type = Config::struct_get(unioned, i);
|
TypeHandle type = Config::union_get(unioned, i);
|
||||||
ASSERT(i == 0 ||
|
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)) {
|
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.
|
// 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>
|
template<class Config>
|
||||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
|
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
|
||||||
TypeHandle type1, TypeHandle type2, Region* region) {
|
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.
|
// Slow case: may need to produce a Unioned object.
|
||||||
int size = 0;
|
int size = 0;
|
||||||
if (!type1->IsBitset()) {
|
if (!type1->IsBitset()) {
|
||||||
size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
|
size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
|
||||||
}
|
}
|
||||||
if (!type2->IsBitset()) {
|
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();
|
int bitset = type1->GlbBitset() | type2->GlbBitset();
|
||||||
if (IsInhabited(bitset)) ++size;
|
if (IsInhabited(bitset)) ++size;
|
||||||
ASSERT(size >= 1);
|
ASSERT(size >= 1);
|
||||||
StructHandle unioned = Config::struct_create(kUnionTag, size, region);
|
UnionedHandle unioned = Config::union_create(size, region);
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (IsInhabited(bitset)) {
|
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, type1, size);
|
||||||
size = ExtendUnion(unioned, type2, size);
|
size = ExtendUnion(unioned, type2, size);
|
||||||
|
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return Config::struct_get(unioned, 0);
|
return Config::union_get(unioned, 0);
|
||||||
} else {
|
} else {
|
||||||
Config::struct_shrink(unioned, size);
|
Config::union_shrink(unioned, size);
|
||||||
return Config::from_struct(unioned);
|
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.
|
// starting at index. Returns updated index.
|
||||||
template<class Config>
|
template<class Config>
|
||||||
int TypeImpl<Config>::ExtendIntersection(
|
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;
|
int old_size = current_size;
|
||||||
if (type->IsClass() || type->IsConstant()) {
|
if (type->IsClass() || type->IsConstant()) {
|
||||||
if (type->Is(other) && !type->InUnion(result, old_size)) {
|
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()) {
|
} else if (type->IsUnion()) {
|
||||||
StructHandle unioned = type->AsUnion();
|
UnionedHandle unioned = type->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle type = Config::struct_get(unioned, i);
|
TypeHandle type = Config::union_get(unioned, i);
|
||||||
ASSERT(i == 0 ||
|
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) &&
|
if (!type->IsBitset() && type->Is(other) &&
|
||||||
!type->InUnion(result, old_size)) {
|
!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.
|
// Slow case: may need to produce a Unioned object.
|
||||||
int size = INT_MAX;
|
int size = INT_MAX;
|
||||||
if (!type1->IsBitset()) {
|
if (!type1->IsBitset()) {
|
||||||
size = (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1);
|
size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
|
||||||
}
|
}
|
||||||
if (!type2->IsBitset()) {
|
if (!type2->IsBitset()) {
|
||||||
size = Min(size,
|
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();
|
int bitset = type1->GlbBitset() & type2->GlbBitset();
|
||||||
if (IsInhabited(bitset)) ++size;
|
if (IsInhabited(bitset)) ++size;
|
||||||
ASSERT(size >= 1);
|
ASSERT(size >= 1);
|
||||||
StructHandle unioned = Config::struct_create(kUnionTag, size, region);
|
UnionedHandle unioned = Config::union_create(size, region);
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (IsInhabited(bitset)) {
|
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, type1, type2, size);
|
||||||
size = ExtendIntersection(unioned, type2, type1, size);
|
size = ExtendIntersection(unioned, type2, type1, size);
|
||||||
@ -527,10 +527,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
|
|||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return None(region);
|
return None(region);
|
||||||
} else if (size == 1) {
|
} else if (size == 1) {
|
||||||
return Config::struct_get(unioned, 0);
|
return Config::union_get(unioned, 0);
|
||||||
} else {
|
} else {
|
||||||
Config::struct_shrink(unioned, size);
|
Config::union_shrink(unioned, size);
|
||||||
return Config::from_struct(unioned);
|
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);
|
return Config::from_constant(type->AsConstant(), type->LubBitset(), region);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(type->IsUnion());
|
ASSERT(type->IsUnion());
|
||||||
typename OtherType::StructHandle unioned = type->AsUnion();
|
typename OtherType::UnionedHandle unioned = type->AsUnion();
|
||||||
int length = OtherType::StructLength(unioned);
|
int length = OtherType::UnionLength(unioned);
|
||||||
StructHandle new_unioned = Config::struct_create(kUnionTag, length, region);
|
UnionedHandle new_unioned = Config::union_create(length, region);
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
Config::struct_set(new_unioned, i,
|
Config::union_set(new_unioned, i,
|
||||||
Convert<OtherType>(OtherType::StructGet(unioned, i), region));
|
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, ")");
|
PrintF(out, ")");
|
||||||
} else if (this->IsUnion()) {
|
} else if (this->IsUnion()) {
|
||||||
PrintF(out, "(");
|
PrintF(out, "(");
|
||||||
StructHandle unioned = this->AsUnion();
|
UnionedHandle unioned = this->AsUnion();
|
||||||
for (int i = 0; i < Config::struct_length(unioned); ++i) {
|
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||||
TypeHandle type_i = Config::struct_get(unioned, i);
|
TypeHandle type_i = Config::union_get(unioned, i);
|
||||||
if (i > 0) PrintF(out, " | ");
|
if (i > 0) PrintF(out, " | ");
|
||||||
type_i->TypePrint(out, dim);
|
type_i->TypePrint(out, dim);
|
||||||
}
|
}
|
||||||
|
129
src/types.h
129
src/types.h
@ -164,29 +164,28 @@ namespace internal {
|
|||||||
|
|
||||||
// struct Config {
|
// struct Config {
|
||||||
// typedef Base;
|
// typedef Base;
|
||||||
// typedef Struct;
|
// typedef Unioned;
|
||||||
// typedef Region;
|
// typedef Region;
|
||||||
// template<class> struct Handle { typedef type; } // No template typedefs...
|
// template<class> struct Handle { typedef type; } // No template typedefs...
|
||||||
// static Handle<Type>::type handle(Type* type); // !is_bitset(type)
|
// static Handle<Type>::type handle(Type* type); // !is_bitset(type)
|
||||||
// static bool is_bitset(Type*);
|
// static bool is_bitset(Type*);
|
||||||
// static bool is_class(Type*);
|
// static bool is_class(Type*);
|
||||||
// static bool is_constant(Type*);
|
// static bool is_constant(Type*);
|
||||||
// static bool is_struct(Type*);
|
// static bool is_union(Type*);
|
||||||
// static int as_bitset(Type*);
|
// static int as_bitset(Type*);
|
||||||
// static i::Handle<i::Map> as_class(Type*);
|
// static i::Handle<i::Map> as_class(Type*);
|
||||||
// static i::Handle<i::Object> as_constant(Type*);
|
// static i::Handle<i::Object> as_constant(Type*);
|
||||||
// static Handle<Struct>::type as_struct(Type*);
|
// static Handle<Unioned>::type as_union(Type*);
|
||||||
// static Type* from_bitset(int bitset);
|
// static Type* from_bitset(int bitset);
|
||||||
// static Handle<Type>::type from_bitset(int bitset, Region*);
|
// 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_class(i::Handle<Map>, int lub, Region*);
|
||||||
// static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
|
// static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
|
||||||
// static Handle<Type>::type from_struct(Handle<Struct>::type);
|
// static Handle<Type>::type from_union(Handle<Unioned>::type);
|
||||||
// static Handle<Struct>::type struct_create(int tag, int length, Region*);
|
// static Handle<Unioned>::type union_create(int size, Region*);
|
||||||
// static void struct_shrink(Handle<Struct>::type, int length);
|
// static void union_shrink(Handle<Unioned>::type, int size);
|
||||||
// static int struct_tag(Handle<Struct>::type);
|
// static Handle<Type>::type union_get(Handle<Unioned>::type, int);
|
||||||
// static Handle<Type>::type struct_get(Handle<Struct>::type, int);
|
// static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
|
||||||
// static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
|
// static int union_length(Handle<Unioned>::type);
|
||||||
// static int struct_length(Handle<Struct>::type);
|
|
||||||
// static int lub_bitset(Type*);
|
// static int lub_bitset(Type*);
|
||||||
// }
|
// }
|
||||||
template<class Config>
|
template<class Config>
|
||||||
@ -300,22 +299,13 @@ class TypeImpl : public Config::Base {
|
|||||||
private:
|
private:
|
||||||
template<class> friend class Iterator;
|
template<class> friend class Iterator;
|
||||||
template<class> friend class TypeImpl;
|
template<class> friend class TypeImpl;
|
||||||
friend struct ZoneTypeConfig;
|
|
||||||
friend struct HeapTypeConfig;
|
|
||||||
|
|
||||||
enum Tag {
|
// A union is a fixed array containing types. Invariants:
|
||||||
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
|
// - its length is at least 2
|
||||||
// - at most one field is a bitset, and it must go into index 0
|
// - at most one field is a bitset, and it must go into index 0
|
||||||
// - no field is a union
|
// - no field is a union
|
||||||
typedef typename Config::Struct Struct;
|
typedef typename Config::Unioned Unioned;
|
||||||
typedef typename Config::template Handle<Struct>::type StructHandle;
|
typedef typename Config::template Handle<Unioned>::type UnionedHandle;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
#define DECLARE_TYPE(type, value) k##type = (value),
|
#define DECLARE_TYPE(type, value) k##type = (value),
|
||||||
@ -327,24 +317,15 @@ class TypeImpl : public Config::Base {
|
|||||||
bool IsNone() { return this == None(); }
|
bool IsNone() { return this == None(); }
|
||||||
bool IsAny() { return this == Any(); }
|
bool IsAny() { return this == Any(); }
|
||||||
bool IsBitset() { return Config::is_bitset(this); }
|
bool IsBitset() { return Config::is_bitset(this); }
|
||||||
bool IsStruct(Tag tag) {
|
bool IsUnion() { return Config::is_union(this); }
|
||||||
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); }
|
int AsBitset() { return Config::as_bitset(this); }
|
||||||
StructHandle AsStruct(Tag tag) {
|
UnionedHandle AsUnion() { return Config::as_union(this); }
|
||||||
ASSERT(IsStruct(tag));
|
|
||||||
return Config::as_struct(this);
|
|
||||||
}
|
|
||||||
StructHandle AsUnion() { return AsStruct(kUnionTag); }
|
|
||||||
|
|
||||||
static int StructLength(StructHandle structured) {
|
static int UnionLength(UnionedHandle unioned) {
|
||||||
return Config::struct_length(structured);
|
return Config::union_length(unioned);
|
||||||
}
|
}
|
||||||
static TypeHandle StructGet(StructHandle structured, int i) {
|
static TypeHandle UnionGet(UnionedHandle unioned, int i) {
|
||||||
return Config::struct_get(structured, i);
|
return Config::union_get(unioned, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SlowIs(TypeImpl* that);
|
bool SlowIs(TypeImpl* that);
|
||||||
@ -359,11 +340,11 @@ class TypeImpl : public Config::Base {
|
|||||||
static int LubBitset(i::Object* value);
|
static int LubBitset(i::Object* value);
|
||||||
static int LubBitset(i::Map* map);
|
static int LubBitset(i::Map* map);
|
||||||
|
|
||||||
bool InUnion(StructHandle unioned, int current_size);
|
bool InUnion(UnionedHandle unioned, int current_size);
|
||||||
static int ExtendUnion(
|
static int ExtendUnion(
|
||||||
StructHandle unioned, TypeHandle t, int current_size);
|
UnionedHandle unioned, TypeHandle t, int current_size);
|
||||||
static int ExtendIntersection(
|
static int ExtendIntersection(
|
||||||
StructHandle unioned, TypeHandle t, TypeHandle other, int current_size);
|
UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
|
||||||
|
|
||||||
static const char* bitset_name(int bitset);
|
static const char* bitset_name(int bitset);
|
||||||
static void BitsetTypePrint(FILE* out, int bitset);
|
static void BitsetTypePrint(FILE* out, int bitset);
|
||||||
@ -371,35 +352,59 @@ class TypeImpl : public Config::Base {
|
|||||||
|
|
||||||
|
|
||||||
// Zone-allocated types are either (odd) integers to represent bitsets, or
|
// Zone-allocated types are either (odd) integers to represent bitsets, or
|
||||||
// (even) pointers to structures for everything else.
|
// (even) pointers to zone lists for everything else. The first slot of every
|
||||||
|
// list is an explicit tag value to distinguish representation.
|
||||||
struct ZoneTypeConfig {
|
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;
|
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||||
class Base {};
|
class Base {};
|
||||||
struct Struct { int tag; int length; void* args[1]; };
|
typedef i::ZoneList<Type*> Unioned;
|
||||||
typedef i::Zone Region;
|
typedef i::Zone Region;
|
||||||
template<class T> struct Handle { typedef T* type; };
|
template<class T> struct Handle { typedef T* type; };
|
||||||
|
|
||||||
static inline Type* handle(Type* 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_bitset(Type* type);
|
||||||
|
static inline bool is_tagged(Type* type);
|
||||||
static inline bool is_class(Type* type);
|
static inline bool is_class(Type* type);
|
||||||
static inline bool is_constant(Type* type);
|
static inline bool is_constant(Type* type);
|
||||||
static inline bool is_struct(Type* type);
|
static inline bool is_union(Type* type);
|
||||||
|
static inline bool tagged_is_union(Tagged* tagged);
|
||||||
static inline int as_bitset(Type* type);
|
static inline int as_bitset(Type* type);
|
||||||
static inline Struct* as_struct(Type* type);
|
static inline Tagged* as_tagged(Type* type);
|
||||||
static inline i::Handle<i::Map> as_class(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<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);
|
||||||
static inline Type* from_bitset(int bitset, Zone* zone);
|
static inline Type* from_bitset(int bitset, Zone* zone);
|
||||||
static inline Type* from_struct(Struct* structured);
|
static inline Type* from_tagged(Tagged* tagged);
|
||||||
static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
|
static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
|
||||||
static inline Type* from_constant(
|
static inline Type* from_constant(
|
||||||
i::Handle<i::Object> value, int lub, Zone* zone);
|
i::Handle<i::Object> value, int lub, Zone* zone);
|
||||||
static inline Struct* struct_create(int tag, int length, Zone* zone);
|
static inline Type* from_union(Unioned* unioned);
|
||||||
static inline void struct_shrink(Struct* structured, int length);
|
static inline Tagged* tagged_from_union(Unioned* unioned);
|
||||||
static inline int struct_tag(Struct* structured);
|
static inline Unioned* union_create(int size, Zone* zone);
|
||||||
static inline Type* struct_get(Struct* structured, int i);
|
static inline void union_shrink(Unioned* unioned, int size);
|
||||||
static inline void struct_set(Struct* structured, int i, Type* type);
|
static inline Type* union_get(Unioned* unioned, int i);
|
||||||
static inline int struct_length(Struct* structured);
|
static inline void union_set(Unioned* unioned, int i, Type* type);
|
||||||
|
static inline int union_length(Unioned* unioned);
|
||||||
static inline int lub_bitset(Type* type);
|
static inline int lub_bitset(Type* type);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -411,7 +416,7 @@ typedef TypeImpl<ZoneTypeConfig> Type;
|
|||||||
struct HeapTypeConfig {
|
struct HeapTypeConfig {
|
||||||
typedef TypeImpl<HeapTypeConfig> Type;
|
typedef TypeImpl<HeapTypeConfig> Type;
|
||||||
typedef i::Object Base;
|
typedef i::Object Base;
|
||||||
typedef i::FixedArray Struct;
|
typedef i::FixedArray Unioned;
|
||||||
typedef i::Isolate Region;
|
typedef i::Isolate Region;
|
||||||
template<class T> struct Handle { typedef i::Handle<T> type; };
|
template<class T> struct Handle { typedef i::Handle<T> type; };
|
||||||
|
|
||||||
@ -419,26 +424,24 @@ struct HeapTypeConfig {
|
|||||||
static inline bool is_bitset(Type* type);
|
static inline bool is_bitset(Type* type);
|
||||||
static inline bool is_class(Type* type);
|
static inline bool is_class(Type* type);
|
||||||
static inline bool is_constant(Type* type);
|
static inline bool is_constant(Type* type);
|
||||||
static inline bool is_struct(Type* type);
|
static inline bool is_union(Type* type);
|
||||||
static inline int as_bitset(Type* type);
|
static inline int as_bitset(Type* type);
|
||||||
static inline i::Handle<i::Map> as_class(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<i::Object> as_constant(Type* type);
|
||||||
static inline i::Handle<Struct> as_struct(Type* type);
|
static inline i::Handle<Unioned> as_union(Type* type);
|
||||||
static inline Type* from_bitset(int bitset);
|
static inline Type* from_bitset(int bitset);
|
||||||
static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
|
static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
|
||||||
static inline i::Handle<Type> from_class(
|
static inline i::Handle<Type> from_class(
|
||||||
i::Handle<i::Map> map, int lub, Isolate* isolate);
|
i::Handle<i::Map> map, int lub, Isolate* isolate);
|
||||||
static inline i::Handle<Type> from_constant(
|
static inline i::Handle<Type> from_constant(
|
||||||
i::Handle<i::Object> value, int lub, Isolate* isolate);
|
i::Handle<i::Object> value, int lub, Isolate* isolate);
|
||||||
static inline i::Handle<Type> from_struct(i::Handle<Struct> structured);
|
static inline i::Handle<Type> from_union(i::Handle<Unioned> unioned);
|
||||||
static inline i::Handle<Struct> struct_create(
|
static inline i::Handle<Unioned> union_create(int size, Isolate* isolate);
|
||||||
int tag, int length, Isolate* isolate);
|
static inline void union_shrink(i::Handle<Unioned> unioned, int size);
|
||||||
static inline void struct_shrink(i::Handle<Struct> structured, int length);
|
static inline i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i);
|
||||||
static inline int struct_tag(i::Handle<Struct> structured);
|
static inline void union_set(
|
||||||
static inline i::Handle<Type> struct_get(i::Handle<Struct> structured, int i);
|
i::Handle<Unioned> unioned, int i, i::Handle<Type> type);
|
||||||
static inline void struct_set(
|
static inline int union_length(i::Handle<Unioned> unioned);
|
||||||
i::Handle<Struct> structured, int i, i::Handle<Type> type);
|
|
||||||
static inline int struct_length(i::Handle<Struct> structured);
|
|
||||||
static inline int lub_bitset(Type* type);
|
static inline int lub_bitset(Type* type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,56 +176,49 @@ class Types {
|
|||||||
|
|
||||||
// Testing auxiliaries (breaking the Type abstraction).
|
// Testing auxiliaries (breaking the Type abstraction).
|
||||||
struct ZoneRep {
|
struct ZoneRep {
|
||||||
struct Struct { int tag; int length; void* args[1]; };
|
static bool IsTagged(Type* t, int tag) {
|
||||||
|
return !IsBitset(t)
|
||||||
static bool IsStruct(Type* t, int tag) {
|
&& reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag;
|
||||||
return !IsBitset(t) && AsStruct(t)->tag == tag;
|
|
||||||
}
|
}
|
||||||
static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
|
static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
|
||||||
static bool IsClass(Type* t) { return IsStruct(t, 0); }
|
static bool IsClass(Type* t) { return IsTagged(t, 0); }
|
||||||
static bool IsConstant(Type* t) { return IsStruct(t, 1); }
|
static bool IsConstant(Type* t) { return IsTagged(t, 1); }
|
||||||
static bool IsUnion(Type* t) { return IsStruct(t, 2); }
|
static bool IsUnion(Type* t) { return IsTagged(t, 2); }
|
||||||
|
|
||||||
static Struct* AsStruct(Type* t) {
|
static ZoneList<void*>* AsTagged(Type* t) {
|
||||||
return reinterpret_cast<Struct*>(t);
|
return reinterpret_cast<ZoneList<void*>*>(t);
|
||||||
}
|
}
|
||||||
static int AsBitset(Type* t) {
|
static int AsBitset(Type* t) {
|
||||||
return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
|
return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
|
||||||
}
|
}
|
||||||
static Map* AsClass(Type* t) {
|
static Map* AsClass(Type* t) {
|
||||||
return *static_cast<Map**>(AsStruct(t)->args[1]);
|
return *reinterpret_cast<Map**>(AsTagged(t)->at(2));
|
||||||
}
|
}
|
||||||
static Object* AsConstant(Type* t) {
|
static Object* AsConstant(Type* t) {
|
||||||
return *static_cast<Object**>(AsStruct(t)->args[1]);
|
return *reinterpret_cast<Object**>(AsTagged(t)->at(2));
|
||||||
}
|
}
|
||||||
static Struct* AsUnion(Type* t) {
|
static ZoneList<Type*>* AsUnion(Type* t) {
|
||||||
return AsStruct(t);
|
return reinterpret_cast<ZoneList<Type*>*>(AsTagged(t));
|
||||||
}
|
}
|
||||||
static int Length(Struct* structured) { return structured->length; }
|
|
||||||
|
|
||||||
static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
|
static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct HeapRep {
|
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 IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
|
||||||
static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
|
static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
|
||||||
static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
|
static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
|
||||||
static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 2); }
|
static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); }
|
||||||
|
|
||||||
static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
|
|
||||||
static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
|
static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
|
||||||
static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
|
static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
|
||||||
static Object* AsConstant(Handle<HeapType> t) {
|
static Object* AsConstant(Handle<HeapType> t) {
|
||||||
return Box::cast(*t)->value();
|
return Box::cast(*t)->value();
|
||||||
}
|
}
|
||||||
static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
|
static FixedArray* AsUnion(Handle<HeapType> t) {
|
||||||
static int Length(Struct* structured) { return structured->length() - 1; }
|
return FixedArray::cast(*t);
|
||||||
|
}
|
||||||
|
|
||||||
static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
|
static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
|
||||||
};
|
};
|
||||||
@ -259,8 +252,7 @@ struct Tests : Rep {
|
|||||||
} else if (Rep::IsConstant(type1)) {
|
} else if (Rep::IsConstant(type1)) {
|
||||||
CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2));
|
CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2));
|
||||||
} else if (Rep::IsUnion(type1)) {
|
} else if (Rep::IsUnion(type1)) {
|
||||||
CHECK_EQ(
|
CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length());
|
||||||
Rep::Length(Rep::AsUnion(type1)), Rep::Length(Rep::AsUnion(type2)));
|
|
||||||
}
|
}
|
||||||
CHECK(type1->Is(type2));
|
CHECK(type1->Is(type2));
|
||||||
CHECK(type2->Is(type1));
|
CHECK(type2->Is(type1));
|
||||||
|
Loading…
Reference in New Issue
Block a user