Commit 98dc857e authored by rossberg@chromium.org's avatar rossberg@chromium.org

Use unsigned type bitsets to limit undefined behaviour

R=bmeurer@chromium.org, svenpanne@chromium.org
BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23916 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a5b4beff
...@@ -70,7 +70,7 @@ T* ZoneTypeConfig::cast(Type* type) { ...@@ -70,7 +70,7 @@ T* ZoneTypeConfig::cast(Type* type) {
// static // static
bool ZoneTypeConfig::is_bitset(Type* type) { bool ZoneTypeConfig::is_bitset(Type* type) {
return reinterpret_cast<intptr_t>(type) & 1; return reinterpret_cast<uintptr_t>(type) & 1;
} }
...@@ -87,9 +87,9 @@ bool ZoneTypeConfig::is_class(Type* type) { ...@@ -87,9 +87,9 @@ bool ZoneTypeConfig::is_class(Type* type) {
// static // static
int ZoneTypeConfig::as_bitset(Type* type) { ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
DCHECK(is_bitset(type)); DCHECK(is_bitset(type));
return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1); return reinterpret_cast<Type::bitset>(type) ^ 1u;
} }
...@@ -108,13 +108,14 @@ i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) { ...@@ -108,13 +108,14 @@ i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
// static // static
ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset) { ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
return reinterpret_cast<Type*>((bitset << 1) | 1); return reinterpret_cast<Type*>(bitset | 1u);
} }
// static // static
ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) { ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
Type::bitset bitset, Zone* Zone) {
return from_bitset(bitset); return from_bitset(bitset);
} }
...@@ -229,8 +230,9 @@ bool HeapTypeConfig::is_struct(Type* type, int tag) { ...@@ -229,8 +230,9 @@ bool HeapTypeConfig::is_struct(Type* type, int tag) {
// static // static
int HeapTypeConfig::as_bitset(Type* type) { HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
return i::Smi::cast(type)->value(); // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
return reinterpret_cast<Type::bitset>(type);
} }
...@@ -247,14 +249,15 @@ i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) { ...@@ -247,14 +249,15 @@ i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
// static // static
HeapTypeConfig::Type* HeapTypeConfig::from_bitset(int bitset) { HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
return Type::cast(i::Smi::FromInt(bitset)); // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
return reinterpret_cast<Type*>(bitset);
} }
// static // static
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset( i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
int bitset, Isolate* isolate) { Type::bitset bitset, Isolate* isolate) {
return i::handle(from_bitset(bitset), isolate); return i::handle(from_bitset(bitset), isolate);
} }
......
...@@ -30,7 +30,8 @@ static bool deq(double x, double y) { ...@@ -30,7 +30,8 @@ static bool deq(double x, double y) {
// The largest bitset subsumed by this type. // The largest bitset subsumed by this type.
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (type->IsBitset()) { if (type->IsBitset()) {
return type->AsBitset(); return type->AsBitset();
...@@ -46,17 +47,18 @@ int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { ...@@ -46,17 +47,18 @@ int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
// The smallest bitset subsuming this type. // The smallest bitset subsuming this type.
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (type->IsBitset()) { if (type->IsBitset()) {
return type->AsBitset(); return type->AsBitset();
} else if (type->IsUnion()) { } else if (type->IsUnion()) {
UnionHandle unioned = handle(type->AsUnion()); UnionHandle unioned = handle(type->AsUnion());
int bitset = kNone; bitset result = kNone;
for (int i = 0; i < unioned->Length(); ++i) { for (int i = 0; i < unioned->Length(); ++i) {
bitset |= unioned->Get(i)->BitsetLub(); result |= unioned->Get(i)->BitsetLub();
} }
return bitset; return result;
} else if (type->IsClass()) { } else if (type->IsClass()) {
// Little hack to avoid the need for a region for handlification here... // Little hack to avoid the need for a region for handlification here...
return Config::is_class(type) ? Lub(*Config::as_class(type)) : return Config::is_class(type) ? Lub(*Config::as_class(type)) :
...@@ -80,17 +82,18 @@ int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { ...@@ -80,17 +82,18 @@ int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
// The smallest bitset subsuming this type, ignoring explicit bounds. // The smallest bitset subsuming this type, ignoring explicit bounds.
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (type->IsBitset()) { if (type->IsBitset()) {
return type->AsBitset(); return type->AsBitset();
} else if (type->IsUnion()) { } else if (type->IsUnion()) {
UnionHandle unioned = handle(type->AsUnion()); UnionHandle unioned = handle(type->AsUnion());
int bitset = kNone; bitset result = kNone;
for (int i = 0; i < unioned->Length(); ++i) { for (int i = 0; i < unioned->Length(); ++i) {
bitset |= unioned->Get(i)->InherentBitsetLub(); result |= unioned->Get(i)->InherentBitsetLub();
} }
return bitset; return result;
} else if (type->IsClass()) { } else if (type->IsClass()) {
return Lub(*type->AsClass()->Map()); return Lub(*type->AsClass()->Map());
} else if (type->IsConstant()) { } else if (type->IsConstant()) {
...@@ -111,7 +114,8 @@ int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { ...@@ -111,7 +114,8 @@ int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) {
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (value->IsNumber()) { if (value->IsNumber()) {
return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr);
...@@ -121,7 +125,8 @@ int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { ...@@ -121,7 +125,8 @@ int TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(double value) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(double value) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (i::IsMinusZero(value)) return kMinusZero; if (i::IsMinusZero(value)) return kMinusZero;
if (std::isnan(value)) return kNaN; if (std::isnan(value)) return kNaN;
...@@ -132,19 +137,21 @@ int TypeImpl<Config>::BitsetType::Lub(double value) { ...@@ -132,19 +137,21 @@ int TypeImpl<Config>::BitsetType::Lub(double value) {
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(double min, double max) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(double min, double max) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
DCHECK(dle(min, max)); DCHECK(dle(min, max));
if (deq(min, max)) return BitsetType::Lub(min); // Singleton range. if (deq(min, max)) return BitsetType::Lub(min); // Singleton range.
int bitset = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); bitset result = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN);
if (dle(0, min) || max < 0) bitset ^= SEMANTIC(BitsetType::kMinusZero); if (dle(0, min) || max < 0) result ^= SEMANTIC(BitsetType::kMinusZero);
return bitset; return result;
// TODO(neis): Could refine this further by doing more checks on min/max. // TODO(neis): Could refine this further by doing more checks on min/max.
} }
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(int32_t value) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(int32_t value) {
if (value >= 0x40000000) { if (value >= 0x40000000) {
return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
} }
...@@ -155,7 +162,8 @@ int TypeImpl<Config>::BitsetType::Lub(int32_t value) { ...@@ -155,7 +162,8 @@ int TypeImpl<Config>::BitsetType::Lub(int32_t value) {
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(uint32_t value) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(uint32_t value) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (value >= 0x80000000u) return kOtherUnsigned32; if (value >= 0x80000000u) return kOtherUnsigned32;
if (value >= 0x40000000u) { if (value >= 0x40000000u) {
...@@ -166,7 +174,8 @@ int TypeImpl<Config>::BitsetType::Lub(uint32_t value) { ...@@ -166,7 +174,8 @@ int TypeImpl<Config>::BitsetType::Lub(uint32_t value) {
template<class Config> template<class Config>
int TypeImpl<Config>::BitsetType::Lub(i::Map* map) { typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
switch (map->instance_type()) { switch (map->instance_type()) {
case STRING_TYPE: case STRING_TYPE:
...@@ -457,8 +466,8 @@ bool TypeImpl<Config>::UnionType::Wellformed() { ...@@ -457,8 +466,8 @@ bool TypeImpl<Config>::UnionType::Wellformed() {
template<class Config> template<class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound(
int bitset, Region* region) { bitset bitset_bound, Region* region) {
TypeHandle bound = BitsetType::New(bitset, region); TypeHandle bound = BitsetType::New(bitset_bound, region);
if (this->IsClass()) { if (this->IsClass()) {
return ClassType::New(this->AsClass()->Map(), bound, region); return ClassType::New(this->AsClass()->Map(), bound, region);
} else if (this->IsConstant()) { } else if (this->IsConstant()) {
...@@ -486,16 +495,16 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( ...@@ -486,16 +495,16 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound(
template<class Config> template<class Config>
int TypeImpl<Config>::BoundBy(TypeImpl* that) { typename TypeImpl<Config>::bitset TypeImpl<Config>::BoundBy(TypeImpl* that) {
DCHECK(!this->IsUnion()); DCHECK(!this->IsUnion());
if (that->IsUnion()) { if (that->IsUnion()) {
UnionType* unioned = that->AsUnion(); UnionType* unioned = that->AsUnion();
int length = unioned->Length(); int length = unioned->Length();
int bitset = BitsetType::kNone; bitset result = BitsetType::kNone;
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
bitset |= BoundBy(unioned->Get(i)->unhandle()); result |= BoundBy(unioned->Get(i)->unhandle());
} }
return bitset; return result;
} else if (that->IsClass() && this->IsClass() && } else if (that->IsClass() && this->IsClass() &&
*this->AsClass()->Map() == *that->AsClass()->Map()) { *this->AsClass()->Map() == *that->AsClass()->Map()) {
return that->BitsetLub(); return that->BitsetLub();
...@@ -515,7 +524,7 @@ int TypeImpl<Config>::BoundBy(TypeImpl* that) { ...@@ -515,7 +524,7 @@ int TypeImpl<Config>::BoundBy(TypeImpl* that) {
template<class Config> template<class Config>
int TypeImpl<Config>::IndexInUnion( int TypeImpl<Config>::IndexInUnion(
int bound, UnionHandle unioned, int current_size) { bitset bound, UnionHandle unioned, int current_size) {
DCHECK(!this->IsUnion()); DCHECK(!this->IsUnion());
for (int i = 0; i < current_size; ++i) { for (int i = 0; i < current_size; ++i) {
TypeHandle that = unioned->Get(i); TypeHandle that = unioned->Get(i);
...@@ -545,7 +554,7 @@ int TypeImpl<Config>::ExtendUnion( ...@@ -545,7 +554,7 @@ int TypeImpl<Config>::ExtendUnion(
UnionHandle result, int size, TypeHandle type, UnionHandle result, int size, TypeHandle type,
TypeHandle other, bool is_intersect, Region* region) { TypeHandle other, bool is_intersect, Region* region) {
if (type->IsUnion()) { if (type->IsUnion()) {
UnionHandle unioned = handle(type->AsUnion()); UnionHandle unioned = Config::template cast<UnionType>(type);
for (int i = 0; i < unioned->Length(); ++i) { for (int i = 0; i < unioned->Length(); ++i) {
TypeHandle type_i = unioned->Get(i); TypeHandle type_i = unioned->Get(i);
DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0))));
...@@ -556,10 +565,10 @@ int TypeImpl<Config>::ExtendUnion( ...@@ -556,10 +565,10 @@ int TypeImpl<Config>::ExtendUnion(
} else if (!type->IsBitset()) { } else if (!type->IsBitset()) {
DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() ||
type->IsContext() || type->IsArray() || type->IsFunction()); type->IsContext() || type->IsArray() || type->IsFunction());
int inherent_bound = type->InherentBitsetLub(); bitset inherent_bound = type->InherentBitsetLub();
int old_bound = type->BitsetLub(); bitset old_bound = type->BitsetLub();
int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; bitset other_bound = type->BoundBy(other->unhandle()) & inherent_bound;
int new_bound = bitset new_bound =
is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); is_intersect ? (old_bound & other_bound) : (old_bound | other_bound);
if (new_bound != BitsetType::kNone) { if (new_bound != BitsetType::kNone) {
int i = type->IndexInUnion(new_bound, result, size); int i = type->IndexInUnion(new_bound, result, size);
...@@ -568,7 +577,7 @@ int TypeImpl<Config>::ExtendUnion( ...@@ -568,7 +577,7 @@ int TypeImpl<Config>::ExtendUnion(
} else if (result->Get(i)->IsBitset()) { } else if (result->Get(i)->IsBitset()) {
return size; // Already fully subsumed. return size; // Already fully subsumed.
} else { } else {
int type_i_bound = result->Get(i)->BitsetLub(); bitset type_i_bound = result->Get(i)->BitsetLub();
new_bound |= type_i_bound; new_bound |= type_i_bound;
if (new_bound == type_i_bound) return size; if (new_bound == type_i_bound) return size;
} }
...@@ -607,14 +616,14 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( ...@@ -607,14 +616,14 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
if (!type2->IsBitset()) { if (!type2->IsBitset()) {
size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
} }
int bitset = type1->BitsetGlb() | type2->BitsetGlb(); bitset bits = type1->BitsetGlb() | type2->BitsetGlb();
if (bitset != BitsetType::kNone) ++size; if (bits != BitsetType::kNone) ++size;
DCHECK(size >= 1); DCHECK(size >= 1);
UnionHandle unioned = UnionType::New(size, region); UnionHandle unioned = UnionType::New(size, region);
size = 0; size = 0;
if (bitset != BitsetType::kNone) { if (bits != BitsetType::kNone) {
unioned->Set(size++, BitsetType::New(bitset, region)); unioned->Set(size++, BitsetType::New(bits, region));
} }
size = ExtendUnion(unioned, size, type1, type2, false, region); size = ExtendUnion(unioned, size, type1, type2, false, region);
size = ExtendUnion(unioned, size, type2, type1, false, region); size = ExtendUnion(unioned, size, type2, type1, false, region);
...@@ -656,14 +665,14 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( ...@@ -656,14 +665,14 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
if (!type2->IsBitset()) { if (!type2->IsBitset()) {
size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
} }
int bitset = type1->BitsetGlb() & type2->BitsetGlb(); bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
if (bitset != BitsetType::kNone) ++size; if (bits != BitsetType::kNone) ++size;
DCHECK(size >= 1); DCHECK(size >= 1);
UnionHandle unioned = UnionType::New(size, region); UnionHandle unioned = UnionType::New(size, region);
size = 0; size = 0;
if (bitset != BitsetType::kNone) { if (bits != BitsetType::kNone) {
unioned->Set(size++, BitsetType::New(bitset, region)); unioned->Set(size++, BitsetType::New(bits, region));
} }
size = ExtendUnion(unioned, size, type1, type2, true, region); size = ExtendUnion(unioned, size, type1, type2, true, region);
size = ExtendUnion(unioned, size, type2, type1, true, region); size = ExtendUnion(unioned, size, type2, type1, true, region);
...@@ -772,7 +781,7 @@ void TypeImpl<Config>::Iterator<T>::Advance() { ...@@ -772,7 +781,7 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
++index_; ++index_;
if (type_->IsUnion()) { if (type_->IsUnion()) {
UnionHandle unioned = handle(type_->AsUnion()); UnionHandle unioned = Config::template cast<UnionType>(type_);
for (; index_ < unioned->Length(); ++index_) { for (; index_ < unioned->Length(); ++index_) {
if (matches(unioned->Get(index_))) return; if (matches(unioned->Get(index_))) return;
} }
...@@ -841,8 +850,8 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( ...@@ -841,8 +850,8 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
// Printing. // Printing.
template<class Config> template<class Config>
const char* TypeImpl<Config>::BitsetType::Name(int bitset) { const char* TypeImpl<Config>::BitsetType::Name(bitset bits) {
switch (bitset) { switch (bits) {
case REPRESENTATION(kAny): return "Any"; case REPRESENTATION(kAny): return "Any";
#define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
case REPRESENTATION(k##type): return #type; case REPRESENTATION(k##type): return #type;
...@@ -862,15 +871,15 @@ const char* TypeImpl<Config>::BitsetType::Name(int bitset) { ...@@ -862,15 +871,15 @@ const char* TypeImpl<Config>::BitsetType::Name(int bitset) {
template <class Config> template <class Config>
void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT
int bitset) { bitset bits) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
const char* name = Name(bitset); const char* name = Name(bits);
if (name != NULL) { if (name != NULL) {
os << name; os << name;
return; return;
} }
static const int named_bitsets[] = { static const bitset named_bitsets[] = {
#define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type),
REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
#undef BITSET_CONSTANT #undef BITSET_CONSTANT
...@@ -882,16 +891,16 @@ void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT ...@@ -882,16 +891,16 @@ void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT
bool is_first = true; bool is_first = true;
os << "("; os << "(";
for (int i(arraysize(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
int subset = named_bitsets[i]; bitset subset = named_bitsets[i];
if ((bitset & subset) == subset) { if ((bits & subset) == subset) {
if (!is_first) os << " | "; if (!is_first) os << " | ";
is_first = false; is_first = false;
os << Name(subset); os << Name(subset);
bitset -= subset; bits -= subset;
} }
} }
DCHECK(bitset == 0); DCHECK(bits == 0);
os << ")"; os << ")";
} }
......
...@@ -122,8 +122,8 @@ namespace internal { ...@@ -122,8 +122,8 @@ namespace internal {
// IMPLEMENTATION // IMPLEMENTATION
// //
// Internally, all 'primitive' types, and their unions, are represented as // Internally, all 'primitive' types, and their unions, are represented as
// bitsets. Class is a heap pointer to the respective map. Only Constant's, or // bitsets. Bit 0 is reserved for tagging. Class is a heap pointer to the
// unions containing Class'es or Constant's, currently require allocation. // respective map. Only structured types require allocation.
// Note that the bitset representation is closed under both Union and Intersect. // Note that the bitset representation is closed under both Union and Intersect.
// //
// There are two type representations, using different allocation: // There are two type representations, using different allocation:
...@@ -139,24 +139,23 @@ namespace internal { ...@@ -139,24 +139,23 @@ namespace internal {
// Values for bitset types // Values for bitset types
#define MASK_BITSET_TYPE_LIST(V) \ #define MASK_BITSET_TYPE_LIST(V) \
V(Representation, static_cast<int>(0xffc00000)) \ V(Representation, 0xff800000u) \
V(Semantic, static_cast<int>(0x003fffff)) V(Semantic, 0x007ffffeu)
#define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
#define SEMANTIC(k) ((k) & BitsetType::kSemantic) #define SEMANTIC(k) ((k) & BitsetType::kSemantic)
#define REPRESENTATION_BITSET_TYPE_LIST(V) \ #define REPRESENTATION_BITSET_TYPE_LIST(V) \
V(None, 0) \ V(None, 0) \
V(UntaggedInt1, 1 << 22 | kSemantic) \ V(UntaggedInt1, 1 << 23 | kSemantic) \
V(UntaggedInt8, 1 << 23 | kSemantic) \ V(UntaggedInt8, 1 << 24 | kSemantic) \
V(UntaggedInt16, 1 << 24 | kSemantic) \ V(UntaggedInt16, 1 << 25 | kSemantic) \
V(UntaggedInt32, 1 << 25 | kSemantic) \ V(UntaggedInt32, 1 << 26 | kSemantic) \
V(UntaggedFloat32, 1 << 26 | kSemantic) \ V(UntaggedFloat32, 1 << 27 | kSemantic) \
V(UntaggedFloat64, 1 << 27 | kSemantic) \ V(UntaggedFloat64, 1 << 28 | kSemantic) \
V(UntaggedPtr, 1 << 28 | kSemantic) \ V(UntaggedPtr, 1 << 29 | kSemantic) \
V(TaggedInt, 1 << 29 | kSemantic) \ V(TaggedInt, 1 << 30 | kSemantic) \
/* MSB has to be sign-extended */ \ V(TaggedPtr, 1 << 31 | kSemantic) \
V(TaggedPtr, static_cast<int>(~0u << 30) | kSemantic) \
\ \
V(UntaggedInt, kUntaggedInt1 | kUntaggedInt8 | \ V(UntaggedInt, kUntaggedInt1 | kUntaggedInt8 | \
kUntaggedInt16 | kUntaggedInt32) \ kUntaggedInt16 | kUntaggedInt32) \
...@@ -166,28 +165,28 @@ namespace internal { ...@@ -166,28 +165,28 @@ namespace internal {
V(Tagged, kTaggedInt | kTaggedPtr) V(Tagged, kTaggedInt | kTaggedPtr)
#define SEMANTIC_BITSET_TYPE_LIST(V) \ #define SEMANTIC_BITSET_TYPE_LIST(V) \
V(Null, 1 << 0 | REPRESENTATION(kTaggedPtr)) \ V(Null, 1 << 1 | REPRESENTATION(kTaggedPtr)) \
V(Undefined, 1 << 1 | REPRESENTATION(kTaggedPtr)) \ V(Undefined, 1 << 2 | REPRESENTATION(kTaggedPtr)) \
V(Boolean, 1 << 2 | REPRESENTATION(kTaggedPtr)) \ V(Boolean, 1 << 3 | REPRESENTATION(kTaggedPtr)) \
V(UnsignedSmall, 1 << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(UnsignedSmall, 1 << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherSignedSmall, 1 << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(OtherSignedSmall, 1 << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherUnsigned31, 1 << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(OtherUnsigned31, 1 << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherUnsigned32, 1 << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(OtherUnsigned32, 1 << 7 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherSigned32, 1 << 7 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(OtherSigned32, 1 << 8 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(MinusZero, 1 << 8 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(MinusZero, 1 << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(NaN, 1 << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(NaN, 1 << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherNumber, 1 << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(OtherNumber, 1 << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(Symbol, 1 << 11 | REPRESENTATION(kTaggedPtr)) \ V(Symbol, 1 << 12 | REPRESENTATION(kTaggedPtr)) \
V(InternalizedString, 1 << 12 | REPRESENTATION(kTaggedPtr)) \ V(InternalizedString, 1 << 13 | REPRESENTATION(kTaggedPtr)) \
V(OtherString, 1 << 13 | REPRESENTATION(kTaggedPtr)) \ V(OtherString, 1 << 14 | REPRESENTATION(kTaggedPtr)) \
V(Undetectable, 1 << 14 | REPRESENTATION(kTaggedPtr)) \ V(Undetectable, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
V(Array, 1 << 15 | REPRESENTATION(kTaggedPtr)) \ V(Array, 1 << 16 | REPRESENTATION(kTaggedPtr)) \
V(Buffer, 1 << 16 | REPRESENTATION(kTaggedPtr)) \ V(Buffer, 1 << 17 | REPRESENTATION(kTaggedPtr)) \
V(Function, 1 << 17 | REPRESENTATION(kTaggedPtr)) \ V(Function, 1 << 18 | REPRESENTATION(kTaggedPtr)) \
V(RegExp, 1 << 18 | REPRESENTATION(kTaggedPtr)) \ V(RegExp, 1 << 19 | REPRESENTATION(kTaggedPtr)) \
V(OtherObject, 1 << 19 | REPRESENTATION(kTaggedPtr)) \ V(OtherObject, 1 << 20 | REPRESENTATION(kTaggedPtr)) \
V(Proxy, 1 << 20 | REPRESENTATION(kTaggedPtr)) \ V(Proxy, 1 << 21 | REPRESENTATION(kTaggedPtr)) \
V(Internal, 1 << 21 | REPRESENTATION(kTagged | kUntagged)) \ V(Internal, 1 << 22 | REPRESENTATION(kTagged | kUntagged)) \
\ \
V(SignedSmall, kUnsignedSmall | kOtherSignedSmall) \ V(SignedSmall, kUnsignedSmall | kOtherSignedSmall) \
V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \ V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
...@@ -207,7 +206,7 @@ namespace internal { ...@@ -207,7 +206,7 @@ namespace internal {
V(Receiver, kObject | kProxy) \ V(Receiver, kObject | kProxy) \
V(NonNumber, kBoolean | kName | kNull | kReceiver | \ V(NonNumber, kBoolean | kName | kNull | kReceiver | \
kUndefined | kInternal) \ kUndefined | kInternal) \
V(Any, -1) V(Any, 0xfffffffeu)
#define BITSET_TYPE_LIST(V) \ #define BITSET_TYPE_LIST(V) \
MASK_BITSET_TYPE_LIST(V) \ MASK_BITSET_TYPE_LIST(V) \
...@@ -229,11 +228,11 @@ namespace internal { ...@@ -229,11 +228,11 @@ namespace internal {
// static bool is_bitset(Type*); // static bool is_bitset(Type*);
// static bool is_class(Type*); // static bool is_class(Type*);
// static bool is_struct(Type*, int tag); // static bool is_struct(Type*, int tag);
// static int as_bitset(Type*); // static bitset as_bitset(Type*);
// static i::Handle<i::Map> as_class(Type*); // static i::Handle<i::Map> as_class(Type*);
// static Handle<Struct>::type as_struct(Type*); // static Handle<Struct>::type as_struct(Type*);
// static Type* from_bitset(int bitset); // static Type* from_bitset(bitset);
// static Handle<Type>::type from_bitset(int bitset, Region*); // static Handle<Type>::type from_bitset(bitset, Region*);
// static Handle<Type>::type from_class(i::Handle<Map>, Region*); // static Handle<Type>::type from_class(i::Handle<Map>, Region*);
// static Handle<Type>::type from_struct(Handle<Struct>::type, int tag); // static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
// static Handle<Struct>::type struct_create(int tag, int length, Region*); // static Handle<Struct>::type struct_create(int tag, int length, Region*);
...@@ -252,9 +251,10 @@ class TypeImpl : public Config::Base { ...@@ -252,9 +251,10 @@ class TypeImpl : public Config::Base {
public: public:
// Auxiliary types. // Auxiliary types.
class BitsetType; // Internal typedef uintptr_t bitset; // Internal
class StructuralType; // Internal class BitsetType; // Internal
class UnionType; // Internal class StructuralType; // Internal
class UnionType; // Internal
class ClassType; class ClassType;
class ConstantType; class ConstantType;
...@@ -457,7 +457,7 @@ class TypeImpl : public Config::Base { ...@@ -457,7 +457,7 @@ class TypeImpl : public Config::Base {
bool IsBitset() { return Config::is_bitset(this); } bool IsBitset() { return Config::is_bitset(this); }
bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); } bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); }
int AsBitset() { bitset AsBitset() {
DCHECK(this->IsBitset()); DCHECK(this->IsBitset());
return static_cast<BitsetType*>(this)->Bitset(); return static_cast<BitsetType*>(this)->Bitset();
} }
...@@ -465,15 +465,15 @@ class TypeImpl : public Config::Base { ...@@ -465,15 +465,15 @@ class TypeImpl : public Config::Base {
// Auxiliary functions. // Auxiliary functions.
int BitsetGlb() { return BitsetType::Glb(this); } bitset BitsetGlb() { return BitsetType::Glb(this); }
int BitsetLub() { return BitsetType::Lub(this); } bitset BitsetLub() { return BitsetType::Lub(this); }
int InherentBitsetLub() { return BitsetType::InherentLub(this); } bitset InherentBitsetLub() { return BitsetType::InherentLub(this); }
bool SlowIs(TypeImpl* that); bool SlowIs(TypeImpl* that);
TypeHandle Rebound(int bitset, Region* region); TypeHandle Rebound(bitset bound, Region* region);
int BoundBy(TypeImpl* that); bitset BoundBy(TypeImpl* that);
int IndexInUnion(int bound, UnionHandle unioned, int current_size); int IndexInUnion(bitset bound, UnionHandle unioned, int current_size);
static int ExtendUnion( static int ExtendUnion(
UnionHandle unioned, int current_size, TypeHandle t, UnionHandle unioned, int current_size, TypeHandle t,
TypeHandle other, bool is_intersect, Region* region); TypeHandle other, bool is_intersect, Region* region);
...@@ -495,35 +495,35 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { ...@@ -495,35 +495,35 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
kUnusedEOL = 0 kUnusedEOL = 0
}; };
int Bitset() { return Config::as_bitset(this); } bitset Bitset() { return Config::as_bitset(this); }
static TypeImpl* New(int bitset) { static TypeImpl* New(bitset bits) {
return static_cast<BitsetType*>(Config::from_bitset(bitset)); return static_cast<BitsetType*>(Config::from_bitset(bits));
} }
static TypeHandle New(int bitset, Region* region) { static TypeHandle New(bitset bits, Region* region) {
return Config::from_bitset(bitset, region); return Config::from_bitset(bits, region);
} }
static bool IsInhabited(int bitset) { static bool IsInhabited(bitset bits) {
return (bitset & kRepresentation) && (bitset & kSemantic); return (bits & kRepresentation) && (bits & kSemantic);
} }
static bool Is(int bitset1, int bitset2) { static bool Is(bitset bits1, bitset bits2) {
return (bitset1 | bitset2) == bitset2; return (bits1 | bits2) == bits2;
} }
static int Glb(TypeImpl* type); // greatest lower bound that's a bitset static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset
static int Lub(TypeImpl* type); // least upper bound that's a bitset static bitset Lub(TypeImpl* type); // least upper bound that's a bitset
static int Lub(i::Object* value); static bitset Lub(i::Object* value);
static int Lub(double value); static bitset Lub(double value);
static int Lub(int32_t value); static bitset Lub(int32_t value);
static int Lub(uint32_t value); static bitset Lub(uint32_t value);
static int Lub(i::Map* map); static bitset Lub(i::Map* map);
static int Lub(double min, double max); static bitset Lub(double min, double max);
static int InherentLub(TypeImpl* type); static bitset InherentLub(TypeImpl* type);
static const char* Name(int bitset); static const char* Name(bitset);
static void Print(OStream& os, int bitset); // NOLINT static void Print(OStream& os, bitset); // NOLINT
using TypeImpl::PrintTo; using TypeImpl::PrintTo;
}; };
...@@ -866,12 +866,12 @@ struct ZoneTypeConfig { ...@@ -866,12 +866,12 @@ struct ZoneTypeConfig {
static inline bool is_class(Type* type); static inline bool is_class(Type* type);
static inline bool is_struct(Type* type, int tag); static inline bool is_struct(Type* type, int tag);
static inline int as_bitset(Type* type); static inline Type::bitset 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 Struct* as_struct(Type* type); static inline Struct* as_struct(Type* type);
static inline Type* from_bitset(int bitset); static inline Type* from_bitset(Type::bitset);
static inline Type* from_bitset(int bitset, Zone* zone); static inline Type* from_bitset(Type::bitset, Zone* zone);
static inline Type* from_class(i::Handle<i::Map> map, Zone* zone); static inline Type* from_class(i::Handle<i::Map> map, Zone* zone);
static inline Type* from_struct(Struct* structured); static inline Type* from_struct(Struct* structured);
...@@ -913,12 +913,12 @@ struct HeapTypeConfig { ...@@ -913,12 +913,12 @@ struct HeapTypeConfig {
static inline bool is_class(Type* type); static inline bool is_class(Type* type);
static inline bool is_struct(Type* type, int tag); static inline bool is_struct(Type* type, int tag);
static inline int as_bitset(Type* type); static inline Type::bitset 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<Struct> as_struct(Type* type); static inline i::Handle<Struct> as_struct(Type* type);
static inline Type* from_bitset(int bitset); static inline Type* from_bitset(Type::bitset);
static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate); static inline i::Handle<Type> from_bitset(Type::bitset, Isolate* isolate);
static inline i::Handle<Type> from_class( static inline i::Handle<Type> from_class(
i::Handle<i::Map> map, Isolate* isolate); i::Handle<i::Map> map, Isolate* isolate);
static inline i::Handle<Type> from_struct(i::Handle<Struct> structure); static inline i::Handle<Type> from_struct(i::Handle<Struct> structure);
......
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