Retry landing "Implement zone-allocated types"
Works around apparent scoping bug in VS, the only change to before being a method rename in the test suite: --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -153,7 +153,7 @@ struct ZoneRep { return reinterpret_cast<ZoneList<ZoneType*>*>(AsTagged(t)); } - static Zone* Region(Zone* zone, Isolate* isolate) { return zone; } + static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } }; @@ -168,7 +168,7 @@ struct HeapRep { 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; } + static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } }; @@ -183,7 +183,7 @@ struct Tests : Rep { isolate(CcTest::i_isolate()), scope(isolate), zone(isolate), - T(Rep::Region(&zone, isolate), isolate) { + T(Rep::ToRegion(&zone, isolate), isolate) { } static void CheckEqual(TypeHandle type1, TypeHandle type2) { R=titzer@chromium.org BUG= Review URL: https://codereview.chromium.org/143693003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18711 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c3383698ee
commit
928d71f83b
@ -166,6 +166,7 @@ void List<T, P>::Clear() {
|
||||
|
||||
template<typename T, class P>
|
||||
void List<T, P>::Rewind(int pos) {
|
||||
ASSERT(0 <= pos && pos <= length_);
|
||||
length_ = pos;
|
||||
}
|
||||
|
||||
|
@ -7905,6 +7905,14 @@ MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
|
||||
}
|
||||
|
||||
|
||||
void FixedArray::Shrink(int new_length) {
|
||||
ASSERT(0 <= new_length && 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 =
|
||||
|
@ -2980,6 +2980,9 @@ 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,
|
||||
|
100
src/types.cc
100
src/types.cc
@ -38,7 +38,7 @@ int TypeImpl<Config>::NumClasses() {
|
||||
} else if (this->IsUnion()) {
|
||||
UnionedHandle unioned = this->AsUnion();
|
||||
int result = 0;
|
||||
for (int i = 0; i < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++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_ < unioned->length(); ++index_) {
|
||||
for (; index_ < Config::union_length(unioned); ++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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||
TypeHandle this_i = Config::union_get(unioned, i);
|
||||
if (!this_i->Is(that)) return false;
|
||||
}
|
||||
@ -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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||
TypeHandle that_i = Config::union_get(unioned, i);
|
||||
if (this->Is(that_i)) return true;
|
||||
if (this->IsBitset()) break; // Fast fail, only first field is a bitset.
|
||||
@ -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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||
TypeHandle this_i = Config::union_get(unioned, i);
|
||||
if (this_i->Maybe(that)) return true;
|
||||
}
|
||||
@ -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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||
TypeHandle that_i = Config::union_get(unioned, i);
|
||||
if (this->Maybe(that_i)) return true;
|
||||
}
|
||||
@ -389,18 +389,21 @@ 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, int current_size) {
|
||||
int TypeImpl<Config>::ExtendUnion(
|
||||
UnionedHandle result, TypeHandle type, int current_size) {
|
||||
int old_size = current_size;
|
||||
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) {
|
||||
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) {
|
||||
TypeHandle type = Config::union_get(unioned, i);
|
||||
ASSERT(i == 0 ||
|
||||
!(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
|
||||
if (!type->IsBitset() && !type->InUnion(result, old_size)) {
|
||||
result->set(current_size++, *type);
|
||||
Config::union_set(result, current_size++, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,51 +436,50 @@ 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() ? type1->AsUnion()->length() : 1);
|
||||
size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
|
||||
}
|
||||
if (!type2->IsBitset()) {
|
||||
size += (type2->IsUnion() ? type2->AsUnion()->length() : 1);
|
||||
size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
|
||||
}
|
||||
ASSERT(size >= 2);
|
||||
UnionedHandle unioned = Config::union_create(size, region);
|
||||
size = 0;
|
||||
|
||||
int bitset = type1->GlbBitset() | type2->GlbBitset();
|
||||
if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
|
||||
size = type1->ExtendUnion(unioned, size);
|
||||
size = type2->ExtendUnion(unioned, size);
|
||||
if (bitset != kNone) {
|
||||
Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
|
||||
}
|
||||
size = ExtendUnion(unioned, type1, size);
|
||||
size = ExtendUnion(unioned, type2, size);
|
||||
|
||||
if (size == 1) {
|
||||
return Config::union_get(unioned, 0);
|
||||
} else if (size == unioned->length()) {
|
||||
} else {
|
||||
Config::union_shrink(unioned, size);
|
||||
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 this which are also in that, store at unioned,
|
||||
// Get non-bitsets from type which are also in other, store at unioned,
|
||||
// starting at index. Returns updated index.
|
||||
template<class Config>
|
||||
int TypeImpl<Config>::ExtendIntersection(
|
||||
UnionedHandle result, TypeHandle that, int current_size) {
|
||||
UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
|
||||
int old_size = current_size;
|
||||
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) {
|
||||
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) {
|
||||
TypeHandle type = Config::union_get(unioned, i);
|
||||
ASSERT(i == 0 ||
|
||||
!(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
|
||||
if (!type->IsBitset() && type->Is(that) &&
|
||||
if (!type->IsBitset() && type->Is(other) &&
|
||||
!type->InUnion(result, old_size)) {
|
||||
result->set(current_size++, *type);
|
||||
Config::union_set(result, current_size++, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -510,10 +512,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() ? type1->AsUnion()->length() : 2);
|
||||
size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
|
||||
}
|
||||
if (!type2->IsBitset()) {
|
||||
int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2);
|
||||
int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
|
||||
size = (size == 0 ? size2 : Min(size, size2));
|
||||
}
|
||||
ASSERT(size >= 2);
|
||||
@ -521,22 +523,20 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
|
||||
size = 0;
|
||||
|
||||
int bitset = type1->GlbBitset() & type2->GlbBitset();
|
||||
if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset));
|
||||
size = type1->ExtendIntersection(unioned, type2, size);
|
||||
size = type2->ExtendIntersection(unioned, type1, size);
|
||||
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 (size == 0) {
|
||||
return None(region);
|
||||
} else if (size == 1) {
|
||||
return Config::union_get(unioned, 0);
|
||||
} else if (size == unioned->length()) {
|
||||
} else {
|
||||
Config::union_shrink(unioned, size);
|
||||
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 < unioned->length(); ++i) {
|
||||
for (int i = 0; i < Config::union_length(unioned); ++i) {
|
||||
TypeHandle type_i = Config::union_get(unioned, i);
|
||||
if (i > 0) PrintF(out, " | ");
|
||||
type_i->TypePrint(out);
|
||||
@ -612,6 +612,10 @@ 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>;
|
||||
|
194
src/types.h
194
src/types.h
@ -137,22 +137,24 @@ 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* 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 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 Type* from_bitset(int bitset);
|
||||
// static Handle<Type>::type from_bitset(int bitset, Region* region);
|
||||
// static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region)
|
||||
// static Handle<Type>::type from_constant(
|
||||
// i::Handle<i::Object> value, Region* region);
|
||||
// static Handle<Type>::type from_union(Handle<Unioned>::T unioned);
|
||||
// static Handle<Unioned>::type union_create(int size, Region* region);
|
||||
// static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i);
|
||||
// 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);
|
||||
// }
|
||||
template<class Config>
|
||||
class TypeImpl : public Config::Base {
|
||||
@ -183,14 +185,17 @@ 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); }
|
||||
@ -232,7 +237,7 @@ class TypeImpl : public Config::Base {
|
||||
return Iterator<i::Object>(Config::handle(this));
|
||||
}
|
||||
|
||||
static TypeImpl* cast(i::Object* object) {
|
||||
static TypeImpl* cast(typename Config::Base* object) {
|
||||
TypeImpl* t = static_cast<TypeImpl*>(object);
|
||||
ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
|
||||
return t;
|
||||
@ -276,9 +281,10 @@ class TypeImpl : public Config::Base {
|
||||
static int LubBitset(i::Map* map);
|
||||
|
||||
bool InUnion(UnionedHandle unioned, int current_size);
|
||||
int ExtendUnion(UnionedHandle unioned, int current_size);
|
||||
int ExtendIntersection(
|
||||
UnionedHandle unioned, TypeHandle type, 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);
|
||||
|
||||
#ifdef OBJECT_PRINT
|
||||
static const char* bitset_name(int bitset);
|
||||
@ -286,6 +292,141 @@ 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;
|
||||
@ -327,8 +468,6 @@ 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));
|
||||
}
|
||||
@ -339,13 +478,25 @@ 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;
|
||||
|
||||
|
||||
@ -399,6 +550,7 @@ struct BoundsImpl {
|
||||
}
|
||||
};
|
||||
|
||||
typedef BoundsImpl<ZoneTypeConfig> ZoneBounds;
|
||||
typedef BoundsImpl<HeapTypeConfig> Bounds;
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user