Commit 99359d38 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Revert "Implement zone-allocated types"

This reverts commit 4308974b16d1ee67d9f64d797c5ea64ffaab51df.

TBR=machenbach@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18545 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fe69172e
......@@ -166,7 +166,6 @@ void List<T, P>::Clear() {
template<typename T, class P>
void List<T, P>::Rewind(int pos) {
ASSERT(pos <= length_);
length_ = pos;
}
......
......@@ -7857,14 +7857,6 @@ MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
}
void FixedArray::Shrink(int new_length) {
ASSERT(new_length <= length());
if (new_length < length()) {
RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), this, length() - new_length);
}
}
MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_result =
......
......@@ -2941,9 +2941,6 @@ class FixedArray: public FixedArrayBase {
// Gives access to raw memory which stores the array's data.
inline Object** data_start();
// Shrink length and insert filler objects.
void Shrink(int length);
// Copy operations.
MUST_USE_RESULT inline MaybeObject* Copy();
MUST_USE_RESULT MaybeObject* CopySize(int new_length,
......
......@@ -38,7 +38,7 @@ int TypeImpl<Config>::NumClasses() {
} else if (this->IsUnion()) {
UnionedHandle unioned = this->AsUnion();
int result = 0;
for (int i = 0; i < Config::union_length(unioned); ++i) {
for (int i = 0; i < unioned->length(); ++i) {
if (Config::union_get(unioned, i)->IsClass()) ++result;
}
return result;
......@@ -55,7 +55,7 @@ int TypeImpl<Config>::NumConstants() {
} else if (this->IsUnion()) {
UnionedHandle unioned = this->AsUnion();
int result = 0;
for (int i = 0; i < Config::union_length(unioned); ++i) {
for (int i = 0; i < unioned->length(); ++i) {
if (Config::union_get(unioned, i)->IsConstant()) ++result;
}
return result;
......@@ -118,7 +118,7 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
++index_;
if (type_->IsUnion()) {
UnionedHandle unioned = type_->AsUnion();
for (; index_ < Config::union_length(unioned); ++index_) {
for (; index_ < unioned->length(); ++index_) {
if (matches(Config::union_get(unioned, index_))) return;
}
} else if (index_ == 0 && matches(type_)) {
......@@ -136,7 +136,7 @@ int TypeImpl<Config>::LubBitset() {
} else if (this->IsUnion()) {
UnionedHandle unioned = this->AsUnion();
int bitset = kNone;
for (int i = 0; i < Config::union_length(unioned); ++i) {
for (int i = 0; i < unioned->length(); ++i) {
bitset |= Config::union_get(unioned, i)->LubBitset();
}
return bitset;
......@@ -299,7 +299,7 @@ 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) {
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle this_i = Config::union_get(unioned, i);
if (!this_i->Is(that)) return false;
}
......@@ -311,7 +311,7 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
ASSERT(!this->IsUnion());
if (that->IsUnion()) {
UnionedHandle unioned = that->AsUnion();
for (int i = 0; i < Config::union_length(unioned); ++i) {
for (int i = 0; i < unioned->length(); ++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.
......@@ -346,7 +346,7 @@ 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) {
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle this_i = Config::union_get(unioned, i);
if (this_i->Maybe(that)) return true;
}
......@@ -356,7 +356,7 @@ 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) {
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle that_i = Config::union_get(unioned, i);
if (this->Maybe(that_i)) return true;
}
......@@ -389,21 +389,18 @@ bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
// 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(
UnionedHandle result, TypeHandle type, int current_size) {
int TypeImpl<Config>::ExtendUnion(UnionedHandle result, 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);
}
} else if (type->IsUnion()) {
UnionedHandle unioned = type->AsUnion();
for (int i = 0; i < Config::union_length(unioned); ++i) {
if (this->IsClass() || this->IsConstant()) {
if (!this->InUnion(result, old_size)) result->set(current_size++, this);
} else if (this->IsUnion()) {
UnionedHandle unioned = this->AsUnion();
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle type = Config::union_get(unioned, i);
ASSERT(i == 0 ||
!(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
if (!type->IsBitset() && !type->InUnion(result, old_size)) {
Config::union_set(result, current_size++, type);
result->set(current_size++, *type);
}
}
}
......@@ -436,50 +433,51 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
// Slow case: may need to produce a Unioned object.
int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
if (!type1->IsBitset()) {
size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
size += (type1->IsUnion() ? type1->AsUnion()->length() : 1);
}
if (!type2->IsBitset()) {
size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
size += (type2->IsUnion() ? type2->AsUnion()->length() : 1);
}
ASSERT(size >= 2);
UnionedHandle unioned = Config::union_create(size, region);
size = 0;
int bitset = type1->GlbBitset() | type2->GlbBitset();
if (bitset != kNone) {
Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
}
size = ExtendUnion(unioned, type1, size);
size = ExtendUnion(unioned, type2, size);
if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
size = type1->ExtendUnion(unioned, size);
size = type2->ExtendUnion(unioned, size);
if (size == 1) {
return Config::union_get(unioned, 0);
} else {
Config::union_shrink(unioned, size);
} else if (size == unioned->length()) {
return Config::from_union(unioned);
}
// There was an overlap. Copy to smaller union.
UnionedHandle result = Config::union_create(size, region);
for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
return Config::from_union(result);
}
// Get non-bitsets from type which are also in other, store at unioned,
// Get non-bitsets from this which are also in that, store at unioned,
// starting at index. Returns updated index.
template<class Config>
int TypeImpl<Config>::ExtendIntersection(
UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
UnionedHandle result, TypeHandle that, 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);
}
} else if (type->IsUnion()) {
UnionedHandle unioned = type->AsUnion();
for (int i = 0; i < Config::union_length(unioned); ++i) {
if (this->IsClass() || this->IsConstant()) {
if (this->Is(that) && !this->InUnion(result, old_size))
result->set(current_size++, this);
} else if (this->IsUnion()) {
UnionedHandle unioned = this->AsUnion();
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle type = Config::union_get(unioned, i);
ASSERT(i == 0 ||
!(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
if (!type->IsBitset() && type->Is(other) &&
if (!type->IsBitset() && type->Is(that) &&
!type->InUnion(result, old_size)) {
Config::union_set(result, current_size++, type);
result->set(current_size++, *type);
}
}
}
......@@ -512,10 +510,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
// Slow case: may need to produce a Unioned object.
int size = 0;
if (!type1->IsBitset()) {
size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
size = (type1->IsUnion() ? type1->AsUnion()->length() : 2);
}
if (!type2->IsBitset()) {
int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2);
size = (size == 0 ? size2 : Min(size, size2));
}
ASSERT(size >= 2);
......@@ -523,20 +521,22 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
size = 0;
int bitset = type1->GlbBitset() & type2->GlbBitset();
if (bitset != kNone) {
Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
}
size = ExtendIntersection(unioned, type1, type2, size);
size = ExtendIntersection(unioned, type2, type1, size);
if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
size = type1->ExtendIntersection(unioned, type2, size);
size = type2->ExtendIntersection(unioned, type1, size);
if (size == 0) {
return None(region);
} else if (size == 1) {
return Config::union_get(unioned, 0);
} else {
Config::union_shrink(unioned, size);
} else if (size == unioned->length()) {
return Config::from_union(unioned);
}
// There were dropped cases. Copy to smaller union.
UnionedHandle result = Config::union_create(size, region);
for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
return Config::from_union(result);
}
......@@ -601,7 +601,7 @@ void TypeImpl<Config>::TypePrint(FILE* out) {
} else if (this->IsUnion()) {
PrintF(out, "(");
UnionedHandle unioned = this->AsUnion();
for (int i = 0; i < Config::union_length(unioned); ++i) {
for (int i = 0; i < unioned->length(); ++i) {
TypeHandle type_i = Config::union_get(unioned, i);
if (i > 0) PrintF(out, " | ");
type_i->TypePrint(out);
......@@ -612,10 +612,6 @@ void TypeImpl<Config>::TypePrint(FILE* out) {
#endif
template class TypeImpl<ZoneTypeConfig>;
template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
template class TypeImpl<HeapTypeConfig>;
template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
......
......@@ -137,24 +137,22 @@ namespace internal {
// 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 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 bool is_bitset(Type* type);
// static bool is_class(Type* type);
// static bool is_constant(Type* type);
// static bool is_union(Type* type);
// static int as_bitset(Type* type);
// static i::Handle<i::Map> as_class(Type* type);
// static i::Handle<i::Object> as_constant(Type* type);
// static Handle<Unioned>::type as_union(Type* type);
// static Type* from_bitset(int bitset);
// static Handle<Type>::type from_bitset(int bitset, Region*);
// static Handle<Type>::type from_class(i::Handle<i::Map>, Region*)
// static Handle<Type>::type from_constant(i::Handle<i::Object>, 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_bitset(int bitset, Region* region);
// static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region)
// static Handle<Type>::type from_constant(
// i::Handle<i::Object> value, Region* region);
// static Handle<Type>::type from_union(Handle<Unioned>::T unioned);
// static Handle<Unioned>::type union_create(int size, Region* region);
// static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i);
// }
template<class Config>
class TypeImpl : public Config::Base {
......@@ -185,17 +183,14 @@ class TypeImpl : public Config::Base {
}
bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
template<class TypeHandle>
bool Is(TypeHandle that) { return this->Is(*that); }
bool Maybe(TypeImpl* that);
template<class TypeHandle>
bool Maybe(TypeHandle that) { return this->Maybe(*that); }
// State-dependent versions of Of and Is that consider subtyping between
// a constant and its map class.
static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
bool IsCurrently(TypeImpl* that);
template<class TypeHandle>
bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); }
bool IsClass() { return Config::is_class(this); }
......@@ -237,7 +232,7 @@ class TypeImpl : public Config::Base {
return Iterator<i::Object>(Config::handle(this));
}
static TypeImpl* cast(typename Config::Base* object) {
static TypeImpl* cast(i::Object* object) {
TypeImpl* t = static_cast<TypeImpl*>(object);
ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
return t;
......@@ -281,10 +276,9 @@ class TypeImpl : public Config::Base {
static int LubBitset(i::Map* map);
bool InUnion(UnionedHandle unioned, int current_size);
static int ExtendUnion(
UnionedHandle unioned, TypeHandle t, int current_size);
static int ExtendIntersection(
UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
int ExtendUnion(UnionedHandle unioned, int current_size);
int ExtendIntersection(
UnionedHandle unioned, TypeHandle type, int current_size);
#ifdef OBJECT_PRINT
static const char* bitset_name(int bitset);
......@@ -292,141 +286,6 @@ 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.
struct ZoneTypeConfig {
private:
typedef i::ZoneList<void*> Tagged;
enum Tag {
kClassTag,
kConstantTag,
kUnionTag
};
static Tagged* 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 tagged_shrink(Tagged* tagged, int size) {
tagged->Rewind(size + 1);
}
static Tag tagged_tag(Tagged* tagged) {
return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
}
template<class T>
static T tagged_get(Tagged* tagged, int i) {
return reinterpret_cast<T>(tagged->at(i + 1));
}
template<class T>
static void tagged_set(Tagged* tagged, int i, T value) {
tagged->at(i + 1) = reinterpret_cast<T>(value);
}
static int tagged_length(Tagged* tagged) {
return tagged->length() - 1;
}
public:
typedef TypeImpl<ZoneTypeConfig> Type;
class Base {};
typedef i::ZoneList<Type*> Unioned;
typedef i::Zone Region;
template<class T> struct Handle { typedef T* type; };
static Type* handle(Type* type) { return type; }
static bool is(Type* type, Tag tag) {
return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
}
static bool is_bitset(Type* type) {
return reinterpret_cast<intptr_t>(type) & 1;
}
static bool is_tagged(Type* type) { return !is_bitset(type); }
static bool is_class(Type* type) { return is(type, kClassTag); }
static bool is_constant(Type* type) { return is(type, kConstantTag); }
static bool is_union(Type* type) { return is(type, kUnionTag); }
static bool tagged_is_union(Tagged* tagged) {
return is(from_tagged(tagged), kUnionTag);
}
static int as_bitset(Type* type) {
ASSERT(is_bitset(type));
return reinterpret_cast<intptr_t>(type) >> 1;
}
static Tagged* as_tagged(Type* type) {
ASSERT(is_tagged(type));
return reinterpret_cast<Tagged*>(type);
}
static i::Handle<i::Map> as_class(Type* type) {
ASSERT(is_class(type));
return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 0));
}
static i::Handle<i::Object> as_constant(Type* type) {
ASSERT(is_constant(type));
return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 0));
}
static Unioned* as_union(Type* type) {
ASSERT(is_union(type));
return tagged_as_union(as_tagged(type));
}
static Unioned* tagged_as_union(Tagged* tagged) {
ASSERT(tagged_is_union(tagged));
return reinterpret_cast<Unioned*>(tagged);
}
static Type* from_bitset(int bitset) {
return reinterpret_cast<Type*>((bitset << 1) | 1);
}
static Type* from_bitset(int bitset, Zone* Zone) {
return from_bitset(bitset);
}
static Type* from_tagged(Tagged* tagged) {
return reinterpret_cast<Type*>(tagged);
}
static Type* from_class(i::Handle<i::Map> map, Zone* zone) {
Tagged* tagged = tagged_create(kClassTag, 1, zone);
tagged_set(tagged, 0, map.location());
return from_tagged(tagged);
}
static Type* from_constant(i::Handle<i::Object> value, Zone* zone) {
Tagged* tagged = tagged_create(kConstantTag, 1, zone);
tagged_set(tagged, 0, value.location());
return from_tagged(tagged);
}
static Type* from_union(Unioned* unioned) {
return from_tagged(tagged_from_union(unioned));
}
static Tagged* tagged_from_union(Unioned* unioned) {
return reinterpret_cast<Tagged*>(unioned);
}
static Unioned* union_create(int size, Zone* zone) {
return tagged_as_union(tagged_create(kUnionTag, size, zone));
}
static void union_shrink(Unioned* unioned, int size) {
tagged_shrink(tagged_from_union(unioned), size);
}
static Type* union_get(Unioned* unioned, int i) {
Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
ASSERT(!is_union(type));
return type;
}
static void union_set(Unioned* unioned, int i, Type* type) {
ASSERT(!is_union(type));
tagged_set(tagged_from_union(unioned), i, type);
}
static int union_length(Unioned* unioned) {
return tagged_length(tagged_from_union(unioned));
}
};
// Heap-allocated types are either smis for bitsets, maps for classes, boxes for
// constants, or fixed arrays for unions.
struct HeapTypeConfig {
typedef TypeImpl<HeapTypeConfig> Type;
typedef i::Object Base;
......@@ -468,6 +327,8 @@ struct HeapTypeConfig {
}
static i::Handle<Type> from_constant(
i::Handle<i::Object> value, Isolate* isolate) {
ASSERT(isolate || value->IsHeapObject());
if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate();
i::Handle<Box> box = isolate->factory()->NewBox(value);
return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
}
......@@ -478,25 +339,13 @@ struct HeapTypeConfig {
static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
return isolate->factory()->NewFixedArray(size);
}
static void union_shrink(i::Handle<Unioned> unioned, int size) {
unioned->Shrink(size);
}
static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
Type* type = static_cast<Type*>(unioned->get(i));
ASSERT(!is_union(type));
return i::handle(type, unioned->GetIsolate());
}
static void union_set(
i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
ASSERT(!is_union(*type));
unioned->set(i, *type);
}
static int union_length(i::Handle<Unioned> unioned) {
return unioned->length();
}
};
typedef TypeImpl<ZoneTypeConfig> ZoneType;
typedef TypeImpl<HeapTypeConfig> Type;
......@@ -550,7 +399,6 @@ struct BoundsImpl {
}
};
typedef BoundsImpl<ZoneTypeConfig> ZoneBounds;
typedef BoundsImpl<HeapTypeConfig> Bounds;
......
......@@ -30,779 +30,705 @@
using namespace v8::internal;
template<class Type, class TypeHandle, class Region>
class Types {
public:
Types(Region* region, Isolate* isolate) :
None(Type::None(region)),
Any(Type::Any(region)),
Oddball(Type::Oddball(region)),
Boolean(Type::Boolean(region)),
Null(Type::Null(region)),
Undefined(Type::Undefined(region)),
Number(Type::Number(region)),
Smi(Type::Smi(region)),
Signed32(Type::Signed32(region)),
Double(Type::Double(region)),
Name(Type::Name(region)),
UniqueName(Type::UniqueName(region)),
String(Type::String(region)),
InternalizedString(Type::InternalizedString(region)),
Symbol(Type::Symbol(region)),
Receiver(Type::Receiver(region)),
Object(Type::Object(region)),
Array(Type::Array(region)),
Function(Type::Function(region)),
Proxy(Type::Proxy(region)),
object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
region_(region) {
smi = handle(Smi::FromInt(666), isolate);
signed32 = isolate->factory()->NewHeapNumber(0x40000000);
object1 = isolate->factory()->NewJSObjectFromMap(object_map);
object2 = isolate->factory()->NewJSObjectFromMap(object_map);
array = isolate->factory()->NewJSArray(20);
ObjectClass = Type::Class(object_map, region);
ArrayClass = Type::Class(array_map, region);
SmiConstant = Type::Constant(smi, region);
Signed32Constant = Type::Constant(signed32, region);
ObjectConstant1 = Type::Constant(object1, region);
ObjectConstant2 = Type::Constant(object2, region);
ArrayConstant1 = Type::Constant(array, region);
ArrayConstant2 = Type::Constant(array, region);
}
TypeHandle None;
TypeHandle Any;
TypeHandle Oddball;
TypeHandle Boolean;
TypeHandle Null;
TypeHandle Undefined;
TypeHandle Number;
TypeHandle Smi;
TypeHandle Signed32;
TypeHandle Double;
TypeHandle Name;
TypeHandle UniqueName;
TypeHandle String;
TypeHandle InternalizedString;
TypeHandle Symbol;
TypeHandle Receiver;
TypeHandle Object;
TypeHandle Array;
TypeHandle Function;
TypeHandle Proxy;
TypeHandle ObjectClass;
TypeHandle ArrayClass;
TypeHandle SmiConstant;
TypeHandle Signed32Constant;
TypeHandle ObjectConstant1;
TypeHandle ObjectConstant2;
TypeHandle ArrayConstant1;
TypeHandle ArrayConstant2;
Handle<i::Map> object_map;
Handle<i::Map> array_map;
Handle<i::Smi> smi;
Handle<i::HeapNumber> signed32;
Handle<i::JSObject> object1;
Handle<i::JSObject> object2;
Handle<i::JSArray> array;
TypeHandle Union(TypeHandle t1, TypeHandle t2) {
return Type::Union(t1, t2, region_);
}
TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
return Type::Intersect(t1, t2, region_);
}
private:
Region* region_;
};
// Testing auxiliaries (breaking the Type abstraction).
struct ZoneRep {
static bool IsTagged(ZoneType* t, int tag) {
return !IsBitset(t)
&& reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag;
}
static bool IsBitset(ZoneType* t) {
return reinterpret_cast<intptr_t>(t) & 1;
}
static bool IsClass(ZoneType* t) { return IsTagged(t, 0); }
static bool IsConstant(ZoneType* t) { return IsTagged(t, 1); }
static bool IsUnion(ZoneType* t) { return IsTagged(t, 2); }
static ZoneList<void*>* AsTagged(ZoneType* t) {
return reinterpret_cast<ZoneList<void*>*>(t);
}
static int AsBitset(ZoneType* t) {
return reinterpret_cast<intptr_t>(t) >> 1;
static bool IsBitset(Handle<Type> t) { return t->IsSmi(); }
static bool IsClass(Handle<Type> t) { return t->IsMap(); }
static bool IsConstant(Handle<Type> t) { return t->IsBox(); }
static bool IsUnion(Handle<Type> t) { return t->IsFixedArray(); }
static int AsBitset(Handle<Type> t) { return Smi::cast(*t)->value(); }
static Map* AsClass(Handle<Type> t) { return Map::cast(*t); }
static Object* AsConstant(Handle<Type> t) { return Box::cast(*t)->value(); }
static FixedArray* AsUnion(Handle<Type> t) { return FixedArray::cast(*t); }
static void CheckEqual(Handle<Type> type1, Handle<Type> type2) {
CHECK_EQ(IsBitset(type1), IsBitset(type2));
CHECK_EQ(IsClass(type1), IsClass(type2));
CHECK_EQ(IsConstant(type1), IsConstant(type2));
CHECK_EQ(IsUnion(type1), IsUnion(type2));
CHECK_EQ(type1->NumClasses(), type2->NumClasses());
CHECK_EQ(type1->NumConstants(), type2->NumConstants());
if (IsBitset(type1)) {
CHECK_EQ(AsBitset(type1), AsBitset(type2));
} else if (IsClass(type1)) {
CHECK_EQ(AsClass(type1), AsClass(type2));
} else if (IsConstant(type1)) {
CHECK_EQ(AsConstant(type1), AsConstant(type2));
} else if (IsUnion(type1)) {
CHECK_EQ(AsUnion(type1)->length(), AsUnion(type2)->length());
}
static Map* AsClass(ZoneType* t) {
return *reinterpret_cast<Map**>(AsTagged(t)->at(1));
}
static Object* AsConstant(ZoneType* t) {
return *reinterpret_cast<Object**>(AsTagged(t)->at(1));
}
static ZoneList<ZoneType*>* AsUnion(ZoneType* t) {
return reinterpret_cast<ZoneList<ZoneType*>*>(AsTagged(t));
}
static Zone* Region(Zone* zone, Isolate* isolate) { return zone; }
};
struct HeapRep {
static bool IsBitset(Handle<Type> t) { return t->IsSmi(); }
static bool IsClass(Handle<Type> t) { return t->IsMap(); }
static bool IsConstant(Handle<Type> t) { return t->IsBox(); }
static bool IsUnion(Handle<Type> t) { return t->IsFixedArray(); }
static int AsBitset(Handle<Type> t) { return Smi::cast(*t)->value(); }
static Map* AsClass(Handle<Type> t) { return Map::cast(*t); }
static Object* AsConstant(Handle<Type> t) { return Box::cast(*t)->value(); }
static FixedArray* AsUnion(Handle<Type> t) { return FixedArray::cast(*t); }
static Isolate* Region(Zone* zone, Isolate* isolate) { return isolate; }
};
template<class Type, class TypeHandle, class Region, class Rep>
struct Tests : Rep {
Isolate* isolate;
HandleScope scope;
Zone zone;
Types<Type, TypeHandle, Region> T;
CHECK(type1->Is(type2));
CHECK(type2->Is(type1));
}
Tests() :
isolate(CcTest::i_isolate()),
scope(isolate),
zone(isolate),
T(Rep::Region(&zone, isolate), isolate) {
}
static void CheckEqual(TypeHandle type1, TypeHandle type2) {
CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2));
CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2));
CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2));
CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2));
CHECK_EQ(type1->NumClasses(), type2->NumClasses());
CHECK_EQ(type1->NumConstants(), type2->NumConstants());
if (Rep::IsBitset(type1)) {
CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2));
} else if (Rep::IsClass(type1)) {
CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2));
} 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(type1->Is(type2));
CHECK(type2->Is(type1));
static void CheckSub(Handle<Type> type1, Handle<Type> type2) {
CHECK(type1->Is(type2));
CHECK(!type2->Is(type1));
if (IsBitset(type1) && IsBitset(type2)) {
CHECK_NE(AsBitset(type1), AsBitset(type2));
}
}
static void CheckSub(TypeHandle type1, TypeHandle type2) {
CHECK(type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
}
}
static void CheckUnordered(TypeHandle type1, TypeHandle type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
}
static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
if (IsBitset(type1) && IsBitset(type2)) {
CHECK_NE(AsBitset(type1), AsBitset(type2));
}
}
static void CheckOverlap(TypeHandle type1, TypeHandle type2) {
CHECK(type1->Maybe(type2));
CHECK(type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
}
}
static void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
CHECK(!type1->Maybe(type2));
CHECK(!type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_EQ(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
}
static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) {
CHECK(type1->Maybe(type2));
CHECK(type2->Maybe(type1));
if (IsBitset(type1) && IsBitset(type2)) {
CHECK_NE(0, AsBitset(type1) & AsBitset(type2));
}
}
void Bitset() {
CHECK(IsBitset(T.None));
CHECK(IsBitset(T.Any));
CHECK(IsBitset(T.String));
CHECK(IsBitset(T.Object));
CHECK(IsBitset(T.Union(T.String, T.Number)));
CHECK(IsBitset(T.Union(T.String, T.Receiver)));
CHECK_EQ(0, AsBitset(T.None));
CHECK_EQ(AsBitset(T.Number) | AsBitset(T.String),
AsBitset(T.Union(T.String, T.Number)));
CHECK_EQ(AsBitset(T.Receiver),
AsBitset(T.Union(T.Receiver, T.Object)));
static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
CHECK(!type1->Maybe(type2));
CHECK(!type2->Maybe(type1));
if (IsBitset(type1) && IsBitset(type2)) {
CHECK_EQ(0, AsBitset(type1) & AsBitset(type2));
}
}
void Class() {
CHECK(IsClass(T.ObjectClass));
CHECK(IsClass(T.ArrayClass));
CHECK(*T.object_map == AsClass(T.ObjectClass));
CHECK(*T.array_map == AsClass(T.ArrayClass));
class HandlifiedTypes {
public:
explicit HandlifiedTypes(Isolate* isolate) :
None(Type::None(isolate)),
Any(Type::Any(isolate)),
Oddball(Type::Oddball(isolate)),
Boolean(Type::Boolean(isolate)),
Null(Type::Null(isolate)),
Undefined(Type::Undefined(isolate)),
Number(Type::Number(isolate)),
Smi(Type::Smi(isolate)),
Signed32(Type::Signed32(isolate)),
Double(Type::Double(isolate)),
Name(Type::Name(isolate)),
UniqueName(Type::UniqueName(isolate)),
String(Type::String(isolate)),
InternalizedString(Type::InternalizedString(isolate)),
Symbol(Type::Symbol(isolate)),
Receiver(Type::Receiver(isolate)),
Object(Type::Object(isolate)),
Array(Type::Array(isolate)),
Function(Type::Function(isolate)),
Proxy(Type::Proxy(isolate)),
object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
isolate_(isolate) {
smi = handle(Smi::FromInt(666), isolate);
signed32 = isolate->factory()->NewHeapNumber(0x40000000);
object1 = isolate->factory()->NewJSObjectFromMap(object_map);
object2 = isolate->factory()->NewJSObjectFromMap(object_map);
array = isolate->factory()->NewJSArray(20);
ObjectClass = Type::Class(object_map, isolate);
ArrayClass = Type::Class(array_map, isolate);
SmiConstant = Type::Constant(smi, isolate);
Signed32Constant = Type::Constant(signed32, isolate);
ObjectConstant1 = Type::Constant(object1, isolate);
ObjectConstant2 = Type::Constant(object2, isolate);
ArrayConstant1 = Type::Constant(array, isolate);
ArrayConstant2 = Type::Constant(array, isolate);
}
void Constant() {
CHECK(IsConstant(T.SmiConstant));
CHECK(IsConstant(T.ObjectConstant1));
CHECK(IsConstant(T.ObjectConstant2));
CHECK(IsConstant(T.ArrayConstant1));
CHECK(IsConstant(T.ArrayConstant2));
CHECK(*T.smi == AsConstant(T.SmiConstant));
CHECK(*T.object1 == AsConstant(T.ObjectConstant1));
CHECK(*T.object2 == AsConstant(T.ObjectConstant2));
CHECK(*T.object1 != AsConstant(T.ObjectConstant2));
CHECK(*T.array == AsConstant(T.ArrayConstant1));
CHECK(*T.array == AsConstant(T.ArrayConstant2));
}
Handle<Type> None;
Handle<Type> Any;
Handle<Type> Oddball;
Handle<Type> Boolean;
Handle<Type> Null;
Handle<Type> Undefined;
Handle<Type> Number;
Handle<Type> Smi;
Handle<Type> Signed32;
Handle<Type> Double;
Handle<Type> Name;
Handle<Type> UniqueName;
Handle<Type> String;
Handle<Type> InternalizedString;
Handle<Type> Symbol;
Handle<Type> Receiver;
Handle<Type> Object;
Handle<Type> Array;
Handle<Type> Function;
Handle<Type> Proxy;
Handle<Type> ObjectClass;
Handle<Type> ArrayClass;
Handle<Type> SmiConstant;
Handle<Type> Signed32Constant;
Handle<Type> ObjectConstant1;
Handle<Type> ObjectConstant2;
Handle<Type> ArrayConstant1;
Handle<Type> ArrayConstant2;
Handle<Map> object_map;
Handle<Map> array_map;
void Is() {
// Reflexivity
CHECK(T.None->Is(T.None));
CHECK(T.Any->Is(T.Any));
CHECK(T.Object->Is(T.Object));
CHECK(T.ObjectClass->Is(T.ObjectClass));
CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
// Symmetry and Transitivity
CheckSub(T.None, T.Number);
CheckSub(T.None, T.Any);
CheckSub(T.Oddball, T.Any);
CheckSub(T.Boolean, T.Oddball);
CheckSub(T.Null, T.Oddball);
CheckSub(T.Undefined, T.Oddball);
CheckUnordered(T.Boolean, T.Null);
CheckUnordered(T.Undefined, T.Null);
CheckUnordered(T.Boolean, T.Undefined);
CheckSub(T.Number, T.Any);
CheckSub(T.Smi, T.Number);
CheckSub(T.Signed32, T.Number);
CheckSub(T.Double, T.Number);
CheckSub(T.Smi, T.Signed32);
CheckUnordered(T.Smi, T.Double);
CheckUnordered(T.Signed32, T.Double);
CheckSub(T.Name, T.Any);
CheckSub(T.UniqueName, T.Any);
CheckSub(T.UniqueName, T.Name);
CheckSub(T.String, T.Name);
CheckSub(T.InternalizedString, T.String);
CheckSub(T.InternalizedString, T.UniqueName);
CheckSub(T.InternalizedString, T.Name);
CheckSub(T.Symbol, T.UniqueName);
CheckSub(T.Symbol, T.Name);
CheckUnordered(T.String, T.UniqueName);
CheckUnordered(T.String, T.Symbol);
CheckUnordered(T.InternalizedString, T.Symbol);
CheckSub(T.Receiver, T.Any);
CheckSub(T.Object, T.Any);
CheckSub(T.Object, T.Receiver);
CheckSub(T.Array, T.Object);
CheckSub(T.Function, T.Object);
CheckSub(T.Proxy, T.Receiver);
CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.Array, T.Function);
// Structured subtyping
CheckSub(T.None, T.ObjectClass);
CheckSub(T.None, T.ObjectConstant1);
CheckSub(T.ObjectClass, T.Any);
CheckSub(T.ObjectConstant1, T.Any);
CheckSub(T.ObjectClass, T.Object);
CheckSub(T.ArrayClass, T.Object);
CheckUnordered(T.ObjectClass, T.ArrayClass);
CheckSub(T.SmiConstant, T.Smi);
CheckSub(T.SmiConstant, T.Signed32);
CheckSub(T.SmiConstant, T.Number);
CheckSub(T.ObjectConstant1, T.Object);
CheckSub(T.ObjectConstant2, T.Object);
CheckSub(T.ArrayConstant1, T.Object);
CheckSub(T.ArrayConstant1, T.Array);
CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
CheckUnordered(T.ObjectConstant1, T.ObjectClass);
CheckUnordered(T.ObjectConstant2, T.ObjectClass);
CheckUnordered(T.ObjectConstant1, T.ArrayClass);
CheckUnordered(T.ObjectConstant2, T.ArrayClass);
CheckUnordered(T.ArrayConstant1, T.ObjectClass);
}
Handle<i::Smi> smi;
Handle<HeapNumber> signed32;
Handle<JSObject> object1;
Handle<JSObject> object2;
Handle<JSArray> array;
void Maybe() {
CheckOverlap(T.Any, T.Any);
CheckOverlap(T.Object, T.Object);
CheckOverlap(T.Oddball, T.Any);
CheckOverlap(T.Boolean, T.Oddball);
CheckOverlap(T.Null, T.Oddball);
CheckOverlap(T.Undefined, T.Oddball);
CheckDisjoint(T.Boolean, T.Null);
CheckDisjoint(T.Undefined, T.Null);
CheckDisjoint(T.Boolean, T.Undefined);
CheckOverlap(T.Number, T.Any);
CheckOverlap(T.Smi, T.Number);
CheckOverlap(T.Double, T.Number);
CheckDisjoint(T.Signed32, T.Double);
CheckOverlap(T.Name, T.Any);
CheckOverlap(T.UniqueName, T.Any);
CheckOverlap(T.UniqueName, T.Name);
CheckOverlap(T.String, T.Name);
CheckOverlap(T.InternalizedString, T.String);
CheckOverlap(T.InternalizedString, T.UniqueName);
CheckOverlap(T.InternalizedString, T.Name);
CheckOverlap(T.Symbol, T.UniqueName);
CheckOverlap(T.Symbol, T.Name);
CheckOverlap(T.String, T.UniqueName);
CheckDisjoint(T.String, T.Symbol);
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Receiver, T.Any);
CheckOverlap(T.Object, T.Any);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.Array, T.Object);
CheckOverlap(T.Function, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
CheckDisjoint(T.Array, T.Function);
CheckOverlap(T.ObjectClass, T.Any);
CheckOverlap(T.ObjectConstant1, T.Any);
CheckOverlap(T.ObjectClass, T.Object);
CheckOverlap(T.ArrayClass, T.Object);
CheckOverlap(T.ObjectClass, T.ObjectClass);
CheckOverlap(T.ArrayClass, T.ArrayClass);
CheckDisjoint(T.ObjectClass, T.ArrayClass);
CheckOverlap(T.SmiConstant, T.Smi);
CheckOverlap(T.SmiConstant, T.Signed32);
CheckOverlap(T.SmiConstant, T.Number);
CheckDisjoint(T.SmiConstant, T.Double);
CheckOverlap(T.ObjectConstant1, T.Object);
CheckOverlap(T.ObjectConstant2, T.Object);
CheckOverlap(T.ArrayConstant1, T.Object);
CheckOverlap(T.ArrayConstant1, T.Array);
CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
Handle<Type> Union(Handle<Type> t1, Handle<Type> t2) {
return Type::Union(t1, t2, isolate_);
}
void Union() {
// Bitset-bitset
CHECK(IsBitset(T.Union(T.Object, T.Number)));
CHECK(IsBitset(T.Union(T.Object, T.Object)));
CHECK(IsBitset(T.Union(T.Any, T.None)));
CheckEqual(T.Union(T.None, T.Number), T.Number);
CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
CheckSub(T.Union(T.Number, T.String), T.Any);
// Class-class
CHECK(IsClass(T.Union(T.ObjectClass, T.ObjectClass)));
CHECK(IsUnion(T.Union(T.ObjectClass, T.ArrayClass)));
CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
// Constant-constant
CHECK(IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
CHECK(IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1)));
CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2)));
CheckEqual(
T.Union(T.ObjectConstant1, T.ObjectConstant1),
T.ObjectConstant1);
CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
CheckUnordered(
T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
CheckOverlap(
T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
// Bitset-class
CHECK(IsBitset(T.Union(T.ObjectClass, T.Object)));
CHECK(IsUnion(T.Union(T.ObjectClass, T.Number)));
CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
// Bitset-constant
CHECK(IsBitset(T.Union(T.SmiConstant, T.Number)));
CHECK(IsBitset(T.Union(T.ObjectConstant1, T.Object)));
CHECK(IsUnion(T.Union(T.ObjectConstant2, T.Number)));
CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
CheckSub(
T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
// Class-constant
CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass)));
CHECK(IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2)));
CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(
T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
// Bitset-union
CHECK(IsBitset(
T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
CHECK(IsUnion(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
CheckEqual(
T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Object);
CheckEqual(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
CheckSub(
T.Double,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
CheckSub(
T.ObjectConstant1,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
CheckSub(
T.None,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
CheckSub(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
T.Any);
CheckSub(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
// Class-union
CHECK(IsUnion(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
CHECK(IsUnion(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
CheckEqual(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Union(T.ObjectClass, T.ObjectConstant1));
CheckSub(
T.None,
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
CheckSub(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Any);
CheckSub(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Object);
CheckEqual(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
T.Union(T.ArrayClass, T.ObjectConstant2));
// Constant-union
CHECK(IsUnion(T.Union(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
CHECK(IsUnion(T.Union(
T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
CHECK(IsUnion(T.Union(
T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
CheckEqual(
T.Union(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Union(
T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
T.Union(
T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
// Union-union
CHECK(IsBitset(T.Union(
T.Union(T.Number, T.ArrayClass),
T.Union(T.Signed32, T.Array))));
CHECK(IsUnion(T.Union(
T.Union(T.Number, T.ArrayClass),
T.Union(T.ObjectClass, T.ArrayClass))));
CheckEqual(
T.Union(
T.Union(T.ObjectConstant2, T.ObjectConstant1),
T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Union(
T.Union(T.ObjectConstant2, T.ArrayConstant1),
T.Union(T.ObjectConstant1, T.ArrayConstant2)),
T.Union(
T.Union(T.ObjectConstant1, T.ObjectConstant2),
T.ArrayConstant1));
CheckEqual(
T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
T.Union(T.Number, T.Array));
Handle<Type> Intersect(Handle<Type> t1, Handle<Type> t2) {
return Type::Intersect(t1, t2, isolate_);
}
void Intersect() {
// Bitset-bitset
CHECK(IsBitset(T.Intersect(T.Object, T.Number)));
CHECK(IsBitset(T.Intersect(T.Object, T.Object)));
CHECK(IsBitset(T.Intersect(T.Any, T.None)));
CheckEqual(T.Intersect(T.None, T.Number), T.None);
CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
// Class-class
CHECK(IsClass(T.Intersect(T.ObjectClass, T.ObjectClass)));
CHECK(IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass)));
CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
// Constant-constant
CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1)));
CHECK(IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2)));
CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2)));
CheckEqual(
T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
CheckEqual(
T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
// Bitset-class
CHECK(IsClass(T.Intersect(T.ObjectClass, T.Object)));
CHECK(IsBitset(T.Intersect(T.ObjectClass, T.Number)));
CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
// Bitset-constant
CHECK(IsBitset(T.Intersect(T.Smi, T.Number)));
CHECK(IsConstant(T.Intersect(T.SmiConstant, T.Number)));
CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
// Class-constant
CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass)));
CHECK(IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2)));
CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
// Bitset-union
CHECK(IsUnion(
T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
CHECK(IsBitset(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
CheckEqual(
T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Union(T.ObjectConstant1, T.ObjectClass));
CheckEqual(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.None);
// Class-union
CHECK(IsClass(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
CHECK(IsClass(
T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
CHECK(IsBitset(
T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
CheckEqual(
T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
T.ArrayClass);
CheckEqual(
T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
T.ArrayClass);
CheckEqual(
T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
T.None);
// Constant-union
CHECK(IsConstant(T.Intersect(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
CHECK(IsConstant(T.Intersect(
T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
CHECK(IsBitset(T.Intersect(
T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
CheckEqual(
T.Intersect(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.ObjectConstant1);
CheckEqual(
T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
T.SmiConstant);
CheckEqual(
T.Intersect(
T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
T.None);
// Union-union
CHECK(IsUnion(T.Intersect(
T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
CHECK(IsBitset(T.Intersect(
T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ArrayClass),
T.Union(T.Smi, T.Array)),
T.Union(T.Smi, T.ArrayClass));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ObjectClass),
T.Union(T.Signed32, T.Array)),
T.Signed32);
CheckEqual(
T.Intersect(
T.Union(T.ObjectConstant2, T.ObjectConstant1),
T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Intersect(
T.Union(
T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
T.Union(
T.ObjectConstant1,
T.Union(T.ArrayConstant1, T.ObjectConstant2))),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Intersect(
T.Union(T.ObjectConstant2, T.ArrayConstant1),
T.Union(T.ObjectConstant1, T.ArrayConstant2)),
T.ArrayConstant1);
}
private:
Isolate* isolate_;
};
typedef Tests<ZoneType, ZoneType*, Zone, ZoneRep> ZoneTests;
typedef Tests<Type, Handle<Type>, Isolate, HeapRep> HeapTests;
TEST(Bitset) {
CcTest::InitializeVM();
ZoneTests().Bitset();
HeapTests().Bitset();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
CHECK(IsBitset(T.None));
CHECK(IsBitset(T.Any));
CHECK(IsBitset(T.String));
CHECK(IsBitset(T.Object));
CHECK(IsBitset(T.Union(T.String, T.Number)));
CHECK(IsBitset(T.Union(T.String, T.Receiver)));
CHECK_EQ(0, AsBitset(T.None));
CHECK_EQ(AsBitset(T.Number) | AsBitset(T.String),
AsBitset(T.Union(T.String, T.Number)));
CHECK_EQ(AsBitset(T.Receiver),
AsBitset(T.Union(T.Receiver, T.Object)));
}
TEST(Class) {
CcTest::InitializeVM();
ZoneTests().Class();
HeapTests().Class();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
CHECK(IsClass(T.ObjectClass));
CHECK(IsClass(T.ArrayClass));
CHECK(*T.object_map == AsClass(T.ObjectClass));
CHECK(*T.array_map == AsClass(T.ArrayClass));
}
TEST(Constant) {
CcTest::InitializeVM();
ZoneTests().Constant();
HeapTests().Constant();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
CHECK(IsConstant(T.SmiConstant));
CHECK(IsConstant(T.ObjectConstant1));
CHECK(IsConstant(T.ObjectConstant2));
CHECK(IsConstant(T.ArrayConstant1));
CHECK(IsConstant(T.ArrayConstant2));
CHECK(*T.smi == AsConstant(T.SmiConstant));
CHECK(*T.object1 == AsConstant(T.ObjectConstant1));
CHECK(*T.object2 == AsConstant(T.ObjectConstant2));
CHECK(*T.object1 != AsConstant(T.ObjectConstant2));
CHECK(*T.array == AsConstant(T.ArrayConstant1));
CHECK(*T.array == AsConstant(T.ArrayConstant2));
}
TEST(Is) {
CcTest::InitializeVM();
ZoneTests().Is();
HeapTests().Is();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
// Reflexivity
CHECK(T.None->Is(T.None));
CHECK(T.Any->Is(T.Any));
CHECK(T.Object->Is(T.Object));
CHECK(T.ObjectClass->Is(T.ObjectClass));
CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
// Symmetry and Transitivity
CheckSub(T.None, T.Number);
CheckSub(T.None, T.Any);
CheckSub(T.Oddball, T.Any);
CheckSub(T.Boolean, T.Oddball);
CheckSub(T.Null, T.Oddball);
CheckSub(T.Undefined, T.Oddball);
CheckUnordered(T.Boolean, T.Null);
CheckUnordered(T.Undefined, T.Null);
CheckUnordered(T.Boolean, T.Undefined);
CheckSub(T.Number, T.Any);
CheckSub(T.Smi, T.Number);
CheckSub(T.Signed32, T.Number);
CheckSub(T.Double, T.Number);
CheckSub(T.Smi, T.Signed32);
CheckUnordered(T.Smi, T.Double);
CheckUnordered(T.Signed32, T.Double);
CheckSub(T.Name, T.Any);
CheckSub(T.UniqueName, T.Any);
CheckSub(T.UniqueName, T.Name);
CheckSub(T.String, T.Name);
CheckSub(T.InternalizedString, T.String);
CheckSub(T.InternalizedString, T.UniqueName);
CheckSub(T.InternalizedString, T.Name);
CheckSub(T.Symbol, T.UniqueName);
CheckSub(T.Symbol, T.Name);
CheckUnordered(T.String, T.UniqueName);
CheckUnordered(T.String, T.Symbol);
CheckUnordered(T.InternalizedString, T.Symbol);
CheckSub(T.Receiver, T.Any);
CheckSub(T.Object, T.Any);
CheckSub(T.Object, T.Receiver);
CheckSub(T.Array, T.Object);
CheckSub(T.Function, T.Object);
CheckSub(T.Proxy, T.Receiver);
CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.Array, T.Function);
// Structured subtyping
CheckSub(T.None, T.ObjectClass);
CheckSub(T.None, T.ObjectConstant1);
CheckSub(T.ObjectClass, T.Any);
CheckSub(T.ObjectConstant1, T.Any);
CheckSub(T.ObjectClass, T.Object);
CheckSub(T.ArrayClass, T.Object);
CheckUnordered(T.ObjectClass, T.ArrayClass);
CheckSub(T.SmiConstant, T.Smi);
CheckSub(T.SmiConstant, T.Signed32);
CheckSub(T.SmiConstant, T.Number);
CheckSub(T.ObjectConstant1, T.Object);
CheckSub(T.ObjectConstant2, T.Object);
CheckSub(T.ArrayConstant1, T.Object);
CheckSub(T.ArrayConstant1, T.Array);
CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
CheckUnordered(T.ObjectConstant1, T.ObjectClass);
CheckUnordered(T.ObjectConstant2, T.ObjectClass);
CheckUnordered(T.ObjectConstant1, T.ArrayClass);
CheckUnordered(T.ObjectConstant2, T.ArrayClass);
CheckUnordered(T.ArrayConstant1, T.ObjectClass);
}
TEST(Maybe) {
CcTest::InitializeVM();
ZoneTests().Maybe();
HeapTests().Maybe();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
CheckOverlap(T.Any, T.Any);
CheckOverlap(T.Object, T.Object);
CheckOverlap(T.Oddball, T.Any);
CheckOverlap(T.Boolean, T.Oddball);
CheckOverlap(T.Null, T.Oddball);
CheckOverlap(T.Undefined, T.Oddball);
CheckDisjoint(T.Boolean, T.Null);
CheckDisjoint(T.Undefined, T.Null);
CheckDisjoint(T.Boolean, T.Undefined);
CheckOverlap(T.Number, T.Any);
CheckOverlap(T.Smi, T.Number);
CheckOverlap(T.Double, T.Number);
CheckDisjoint(T.Signed32, T.Double);
CheckOverlap(T.Name, T.Any);
CheckOverlap(T.UniqueName, T.Any);
CheckOverlap(T.UniqueName, T.Name);
CheckOverlap(T.String, T.Name);
CheckOverlap(T.InternalizedString, T.String);
CheckOverlap(T.InternalizedString, T.UniqueName);
CheckOverlap(T.InternalizedString, T.Name);
CheckOverlap(T.Symbol, T.UniqueName);
CheckOverlap(T.Symbol, T.Name);
CheckOverlap(T.String, T.UniqueName);
CheckDisjoint(T.String, T.Symbol);
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Receiver, T.Any);
CheckOverlap(T.Object, T.Any);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.Array, T.Object);
CheckOverlap(T.Function, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
CheckDisjoint(T.Array, T.Function);
CheckOverlap(T.ObjectClass, T.Any);
CheckOverlap(T.ObjectConstant1, T.Any);
CheckOverlap(T.ObjectClass, T.Object);
CheckOverlap(T.ArrayClass, T.Object);
CheckOverlap(T.ObjectClass, T.ObjectClass);
CheckOverlap(T.ArrayClass, T.ArrayClass);
CheckDisjoint(T.ObjectClass, T.ArrayClass);
CheckOverlap(T.SmiConstant, T.Smi);
CheckOverlap(T.SmiConstant, T.Signed32);
CheckOverlap(T.SmiConstant, T.Number);
CheckDisjoint(T.SmiConstant, T.Double);
CheckOverlap(T.ObjectConstant1, T.Object);
CheckOverlap(T.ObjectConstant2, T.Object);
CheckOverlap(T.ArrayConstant1, T.Object);
CheckOverlap(T.ArrayConstant1, T.Array);
CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
}
TEST(Union) {
CcTest::InitializeVM();
ZoneTests().Union();
HeapTests().Union();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
// Bitset-bitset
CHECK(IsBitset(T.Union(T.Object, T.Number)));
CHECK(IsBitset(T.Union(T.Object, T.Object)));
CHECK(IsBitset(T.Union(T.Any, T.None)));
CheckEqual(T.Union(T.None, T.Number), T.Number);
CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
CheckSub(T.Union(T.Number, T.String), T.Any);
// Class-class
CHECK(IsClass(T.Union(T.ObjectClass, T.ObjectClass)));
CHECK(IsUnion(T.Union(T.ObjectClass, T.ArrayClass)));
CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
// Constant-constant
CHECK(IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
CHECK(IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1)));
CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2)));
CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
// Bitset-class
CHECK(IsBitset(T.Union(T.ObjectClass, T.Object)));
CHECK(IsUnion(T.Union(T.ObjectClass, T.Number)));
CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
// Bitset-constant
CHECK(IsBitset(T.Union(T.SmiConstant, T.Number)));
CHECK(IsBitset(T.Union(T.ObjectConstant1, T.Object)));
CHECK(IsUnion(T.Union(T.ObjectConstant2, T.Number)));
CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
// Class-constant
CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass)));
CHECK(IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2)));
CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
CheckSub(
T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
// Bitset-union
CHECK(IsBitset(T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
CHECK(IsUnion(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
CheckEqual(
T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Object);
CheckEqual(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
CheckSub(
T.Double,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
CheckSub(
T.ObjectConstant1,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
CheckSub(
T.None,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
CheckSub(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
T.Any);
CheckSub(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
// Class-union
CHECK(IsUnion(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
CHECK(IsUnion(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
CheckEqual(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Union(T.ObjectClass, T.ObjectConstant1));
CheckSub(
T.None,
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
CheckSub(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Any);
CheckSub(
T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Object);
CheckEqual(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
T.Union(T.ArrayClass, T.ObjectConstant2));
// Constant-union
CHECK(IsUnion(T.Union(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
CHECK(IsUnion(T.Union(
T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
CHECK(IsUnion(T.Union(
T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
CheckEqual(
T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
// Union-union
CHECK(IsBitset(T.Union(
T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
CHECK(IsUnion(T.Union(
T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass))));
CheckEqual(
T.Union(
T.Union(T.ObjectConstant2, T.ObjectConstant1),
T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Union(
T.Union(T.ObjectConstant2, T.ArrayConstant1),
T.Union(T.ObjectConstant1, T.ArrayConstant2)),
T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1));
CheckEqual(
T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
T.Union(T.Number, T.Array));
}
TEST(Intersect) {
CcTest::InitializeVM();
ZoneTests().Intersect();
HeapTests().Intersect();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
HandlifiedTypes T(isolate);
// Bitset-bitset
CHECK(IsBitset(T.Intersect(T.Object, T.Number)));
CHECK(IsBitset(T.Intersect(T.Object, T.Object)));
CHECK(IsBitset(T.Intersect(T.Any, T.None)));
CheckEqual(T.Intersect(T.None, T.Number), T.None);
CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
// Class-class
CHECK(IsClass(T.Intersect(T.ObjectClass, T.ObjectClass)));
CHECK(IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass)));
CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
// Constant-constant
CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1)));
CHECK(IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2)));
CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2)));
CheckEqual(
T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
CheckEqual(
T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
// Bitset-class
CHECK(IsClass(T.Intersect(T.ObjectClass, T.Object)));
CHECK(IsBitset(T.Intersect(T.ObjectClass, T.Number)));
CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
// Bitset-constant
CHECK(IsBitset(T.Intersect(T.Smi, T.Number)));
CHECK(IsConstant(T.Intersect(T.SmiConstant, T.Number)));
CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
// Class-constant
CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass)));
CHECK(IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2)));
CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
// Bitset-union
CHECK(IsUnion(
T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
CHECK(IsBitset(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
CheckEqual(
T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
T.Union(T.ObjectConstant1, T.ObjectClass));
CheckEqual(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.None);
// Class-union
CHECK(IsClass(
T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
CHECK(IsClass(
T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
CHECK(IsBitset(
T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
CheckEqual(
T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
T.ArrayClass);
CheckEqual(
T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
T.ArrayClass);
CheckEqual(
T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
T.None);
// Constant-union
CHECK(IsConstant(T.Intersect(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
CHECK(IsConstant(T.Intersect(
T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
CHECK(IsBitset(T.Intersect(
T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
CheckEqual(
T.Intersect(
T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.ObjectConstant1);
CheckEqual(
T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
T.SmiConstant);
CheckEqual(
T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
T.None);
// Union-union
CHECK(IsUnion(T.Intersect(
T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
CHECK(IsBitset(T.Intersect(
T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ArrayClass),
T.Union(T.Smi, T.Array)),
T.Union(T.Smi, T.ArrayClass));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ObjectClass),
T.Union(T.Signed32, T.Array)),
T.Signed32);
CheckEqual(
T.Intersect(
T.Union(T.ObjectConstant2, T.ObjectConstant1),
T.Union(T.ObjectConstant1, T.ObjectConstant2)),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Intersect(
T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
T.Union(
T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))),
T.Union(T.ObjectConstant2, T.ObjectConstant1));
CheckEqual(
T.Intersect(
T.Union(T.ObjectConstant2, T.ArrayConstant1),
T.Union(T.ObjectConstant1, T.ArrayConstant2)),
T.ArrayConstant1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment