Commit 21e0e00a authored by rossberg@chromium.org's avatar rossberg@chromium.org

Reland "Use unsigned type bitsets to limit undefined behaviour"

Temporary debug attempt; adds output to failing test in test-types.cc, otherwise unchanged.

Windows f

R=ulan@chromium.org
BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23936 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f38258b4
...@@ -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);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -12,20 +12,22 @@ ...@@ -12,20 +12,22 @@
using namespace v8::internal; using namespace v8::internal;
// Testing auxiliaries (breaking the Type abstraction). // Testing auxiliaries (breaking the Type abstraction).
typedef uintptr_t bitset;
struct ZoneRep { struct ZoneRep {
typedef void* Struct; typedef void* Struct;
static bool IsStruct(Type* t, int tag) { static bool IsStruct(Type* t, int tag) {
return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
} }
static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } static bool IsBitset(Type* t) { return reinterpret_cast<bitset>(t) & 1; }
static bool IsUnion(Type* t) { return IsStruct(t, 6); } static bool IsUnion(Type* t) { return IsStruct(t, 6); }
static Struct* AsStruct(Type* t) { static Struct* AsStruct(Type* t) {
return reinterpret_cast<Struct*>(t); return reinterpret_cast<Struct*>(t);
} }
static int AsBitset(Type* t) { static bitset AsBitset(Type* t) {
return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); return reinterpret_cast<bitset>(t) ^ 1u;
} }
static Struct* AsUnion(Type* t) { static Struct* AsUnion(Type* t) {
return AsStruct(t); return AsStruct(t);
...@@ -55,7 +57,9 @@ struct HeapRep { ...@@ -55,7 +57,9 @@ struct HeapRep {
static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); } static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } static bitset AsBitset(Handle<HeapType> t) {
return reinterpret_cast<bitset>(*t);
}
static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
static int Length(Struct* structured) { return structured->length() - 1; } static int Length(Struct* structured) { return structured->length() - 1; }
...@@ -66,9 +70,11 @@ struct HeapRep { ...@@ -66,9 +70,11 @@ struct HeapRep {
using HeapType::BitsetType::Glb; using HeapType::BitsetType::Glb;
using HeapType::BitsetType::Lub; using HeapType::BitsetType::Lub;
using HeapType::BitsetType::InherentLub; using HeapType::BitsetType::InherentLub;
static int Glb(Handle<HeapType> type) { return Glb(*type); } static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
static int Lub(Handle<HeapType> type) { return Lub(*type); } static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); } static bitset InherentLub(Handle<HeapType> type) {
return InherentLub(*type);
}
}; };
}; };
...@@ -365,7 +371,7 @@ struct Tests : Rep { ...@@ -365,7 +371,7 @@ struct Tests : Rep {
CHECK(type1->Is(type2)); CHECK(type1->Is(type2));
CHECK(!type2->Is(type1)); CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); CHECK(Rep::AsBitset(type1) != Rep::AsBitset(type2));
} }
} }
...@@ -373,7 +379,7 @@ struct Tests : Rep { ...@@ -373,7 +379,7 @@ struct Tests : Rep {
CHECK(!type1->Is(type2)); CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1)); CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); CHECK(Rep::AsBitset(type1) != Rep::AsBitset(type2));
} }
} }
...@@ -381,8 +387,8 @@ struct Tests : Rep { ...@@ -381,8 +387,8 @@ struct Tests : Rep {
CHECK(type1->Maybe(type2)); CHECK(type1->Maybe(type2));
CHECK(type2->Maybe(type1)); CHECK(type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_NE(0, CHECK(0 !=
Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); (Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)));
} }
} }
...@@ -392,8 +398,8 @@ struct Tests : Rep { ...@@ -392,8 +398,8 @@ struct Tests : Rep {
CHECK(!type1->Maybe(type2)); CHECK(!type1->Maybe(type2));
CHECK(!type2->Maybe(type1)); CHECK(!type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
CHECK_EQ(0, CHECK(0 ==
Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); (Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)));
} }
} }
...@@ -402,8 +408,11 @@ struct Tests : Rep { ...@@ -402,8 +408,11 @@ struct Tests : Rep {
CHECK(this->IsBitset(T.None)); CHECK(this->IsBitset(T.None));
CHECK(this->IsBitset(T.Any)); CHECK(this->IsBitset(T.Any));
CHECK_EQ(0, this->AsBitset(T.None)); CHECK(bitset(0) == this->AsBitset(T.None));
CHECK_EQ(-1, this->AsBitset(T.Any)); printf("[BitSet] %p == %p\n",
reinterpret_cast<void*>(bitset(0xfffffffeu)),
reinterpret_cast<void*>(this->AsBitset(T.Any)));
CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any));
// Union(T1, T2) is bitset for bitsets T1,T2 // Union(T1, T2) is bitset for bitsets T1,T2
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
...@@ -445,8 +454,8 @@ struct Tests : Rep { ...@@ -445,8 +454,8 @@ struct Tests : Rep {
TypeHandle type2 = *it2; TypeHandle type2 = *it2;
TypeHandle union12 = T.Union(type1, type2); TypeHandle union12 = T.Union(type1, type2);
if (this->IsBitset(type1) && this->IsBitset(type2)) { if (this->IsBitset(type1) && this->IsBitset(type2)) {
CHECK_EQ( CHECK(
this->AsBitset(type1) | this->AsBitset(type2), (this->AsBitset(type1) | this->AsBitset(type2)) ==
this->AsBitset(union12)); this->AsBitset(union12));
} }
} }
...@@ -459,8 +468,8 @@ struct Tests : Rep { ...@@ -459,8 +468,8 @@ struct Tests : Rep {
TypeHandle type2 = *it2; TypeHandle type2 = *it2;
TypeHandle intersect12 = T.Intersect(type1, type2); TypeHandle intersect12 = T.Intersect(type1, type2);
if (this->IsBitset(type1) && this->IsBitset(type2)) { if (this->IsBitset(type1) && this->IsBitset(type2)) {
CHECK_EQ( CHECK(
this->AsBitset(type1) & this->AsBitset(type2), (this->AsBitset(type1) & this->AsBitset(type2)) ==
this->AsBitset(intersect12)); this->AsBitset(intersect12));
} }
} }
......
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