Revision: 20025
Author: [email protected]
Date: Tue Mar 18 11:50:18 2014 UTC
Log: Introduce representation types
Also:
- improve type pretty-printing,
- update doc comments,
- some renamings for consistency.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/176843006
http://code.google.com/p/v8/source/detail?r=20025
Modified:
/branches/bleeding_edge/src/code-stubs-hydrogen.cc
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/types.cc
/branches/bleeding_edge/src/types.h
/branches/bleeding_edge/src/typing.cc
/branches/bleeding_edge/test/cctest/test-types.cc
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Thu Mar 13 10:57:07
2014 UTC
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Tue Mar 18 11:50:18
2014 UTC
@@ -941,7 +941,7 @@
// If we encounter a generic argument, the number conversion is
// observable, thus we cannot afford to bail out after the fact.
if (!state.HasSideEffects()) {
- if (result_type->Is(Type::Smi())) {
+ if (result_type->Is(Type::SignedSmall())) {
if (state.op() == Token::SHR) {
// TODO(olivf) Replace this by a SmiTagU Instruction.
// 0x40000000: this number would convert to negative when
interpreting
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Mar 17 13:42:37 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Tue Mar 18 11:50:18 2014 UTC
@@ -1674,7 +1674,7 @@
}
if_objectissmi.Else();
{
- if (type->Is(Type::Smi())) {
+ if (type->Is(Type::SignedSmall())) {
if_objectissmi.Deopt("Expected smi");
} else {
// Check if the object is a heap number.
@@ -8980,7 +8980,7 @@
HValue* HGraphBuilder::EnforceNumberType(HValue* number,
Type* expected) {
- if (expected->Is(Type::Smi())) {
+ if (expected->Is(Type::SignedSmall())) {
return AddUncasted<HForceRepresentation>(number,
Representation::Smi());
}
if (expected->Is(Type::Signed32())) {
@@ -9023,7 +9023,7 @@
if (expected_obj->Is(Type::Undefined(zone()))) {
// This is already done by HChange.
- *expected = Type::Union(expected_number, Type::Double(zone()), zone());
+ *expected = Type::Union(expected_number, Type::Float(zone()), zone());
return value;
}
=======================================
--- /branches/bleeding_edge/src/ic.cc Mon Mar 17 17:19:39 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Tue Mar 18 11:50:18 2014 UTC
@@ -2372,7 +2372,7 @@
Type* BinaryOpIC::State::KindToType(Kind kind, Zone* zone) {
switch (kind) {
case NONE: return Type::None(zone);
- case SMI: return Type::Smi(zone);
+ case SMI: return Type::SignedSmall(zone);
case INT32: return Type::Signed32(zone);
case NUMBER: return Type::Number(zone);
case STRING: return Type::String(zone);
@@ -2518,7 +2518,7 @@
Handle<Map> map) {
switch (state) {
case CompareIC::UNINITIALIZED: return Type::None(zone);
- case CompareIC::SMI: return Type::Smi(zone);
+ case CompareIC::SMI: return Type::SignedSmall(zone);
case CompareIC::NUMBER: return Type::Number(zone);
case CompareIC::STRING: return Type::String(zone);
case CompareIC::INTERNALIZED_STRING: return
Type::InternalizedString(zone);
=======================================
--- /branches/bleeding_edge/src/types.cc Tue Mar 11 10:28:38 2014 UTC
+++ /branches/bleeding_edge/src/types.cc Tue Mar 18 11:50:18 2014 UTC
@@ -152,14 +152,14 @@
template<class Config>
int TypeImpl<Config>::LubBitset(i::Object* value) {
- if (value->IsSmi()) return kSmi;
+ if (value->IsSmi()) return kSignedSmall & kTaggedInt;
i::Map* map = i::HeapObject::cast(value)->map();
if (map->instance_type() == HEAP_NUMBER_TYPE) {
int32_t i;
uint32_t u;
- if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
- if (value->ToUint32(&u)) return kUnsigned32;
- return kDouble;
+ return kTaggedPtr & (
+ value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall :
kOtherSigned32) :
+ value->ToUint32(&u) ? kUnsigned32 : kFloat);
}
if (map->instance_type() == ODDBALL_TYPE) {
if (value->IsUndefined()) return kUndefined;
@@ -204,7 +204,7 @@
case ODDBALL_TYPE:
return kOddball;
case HEAP_NUMBER_TYPE:
- return kDouble;
+ return kFloat & kTaggedPtr;
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_OBJECT_TYPE:
@@ -247,7 +247,7 @@
case EXECUTABLE_ACCESSOR_INFO_TYPE:
case ACCESSOR_PAIR_TYPE:
case FIXED_ARRAY_TYPE:
- return kInternal;
+ return kInternal & kTaggedPtr;
default:
UNREACHABLE();
return kNone;
@@ -273,13 +273,12 @@
template<class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently(
i::Handle<i::Object> value, Region* region) {
- if (value->IsSmi()) return Smi(region);
- i::Map* map = i::HeapObject::cast(*value)->map();
- if (map->instance_type() == HEAP_NUMBER_TYPE ||
- map->instance_type() == ODDBALL_TYPE) {
+ if (value->IsSmi() ||
+ i::HeapObject::cast(*value)->map()->instance_type() ==
HEAP_NUMBER_TYPE ||
+ i::HeapObject::cast(*value)->map()->instance_type() == ODDBALL_TYPE)
{
return Of(value, region);
}
- return Class(i::handle(map), region);
+ return Class(i::handle(i::HeapObject::cast(*value)->map()), region);
}
@@ -340,10 +339,10 @@
bool TypeImpl<Config>::Maybe(TypeImpl* that) {
// Fast path for bitsets.
if (this->IsBitset()) {
- return (this->AsBitset() & that->LubBitset()) != 0;
+ return IsInhabited(this->AsBitset() & that->LubBitset());
}
if (that->IsBitset()) {
- return (this->LubBitset() & that->AsBitset()) != 0;
+ return IsInhabited(this->LubBitset() & that->AsBitset());
}
// (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn
overlaps T)
@@ -570,7 +569,7 @@
// TODO(rossberg): this does not belong here.
Representation Representation::FromType(Type* type) {
if (type->Is(Type::None())) return Representation::None();
- if (type->Is(Type::Smi())) return Representation::Smi();
+ if (type->Is(Type::SignedSmall())) return Representation::Smi();
if (type->Is(Type::Signed32())) return Representation::Integer32();
if (type->Is(Type::Number())) return Representation::Double();
return Representation::Tagged();
@@ -579,8 +578,8 @@
#ifdef OBJECT_PRINT
template<class Config>
-void TypeImpl<Config>::TypePrint() {
- TypePrint(stdout);
+void TypeImpl<Config>::TypePrint(PrintDimension dim) {
+ TypePrint(stdout, dim);
PrintF(stdout, "\n");
Flush(stdout);
}
@@ -589,9 +588,17 @@
template<class Config>
const char* TypeImpl<Config>::bitset_name(int bitset) {
switch (bitset) {
- #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type;
- BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
+ case kAny & kRepresentation: return "Any";
+ #define PRINT_COMPOSED_TYPE(type, value) \
+ case k##type & kRepresentation: return #type;
+ REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
#undef PRINT_COMPOSED_TYPE
+
+ #define PRINT_COMPOSED_TYPE(type, value) \
+ case k##type & kSemantic: return #type;
+ SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
+ #undef PRINT_COMPOSED_TYPE
+
default:
return NULL;
}
@@ -599,23 +606,54 @@
template<class Config>
-void TypeImpl<Config>::TypePrint(FILE* out) {
+void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
+ const char* name = bitset_name(bitset);
+ if (name != NULL) {
+ PrintF(out, "%s", name);
+ } else {
+ static const int named_bitsets[] = {
+ #define BITSET_CONSTANT(type, value) k##type & kRepresentation,
+ REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
+ #undef BITSET_CONSTANT
+
+ #define BITSET_CONSTANT(type, value) k##type & kSemantic,
+ SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
+ #undef BITSET_CONSTANT
+ };
+
+ bool is_first = true;
+ PrintF(out, "(");
+ for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i)
{
+ int subset = named_bitsets[i];
+ if ((bitset & subset) == subset) {
+ if (!is_first) PrintF(out, " | ");
+ is_first = false;
+ PrintF(out, "%s", bitset_name(subset));
+ bitset -= subset;
+ }
+ }
+ ASSERT(bitset == 0);
+ PrintF(out, ")");
+ }
+}
+
+
+template<class Config>
+void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
if (this->IsBitset()) {
int bitset = this->AsBitset();
- const char* name = bitset_name(bitset);
- if (name != NULL) {
- PrintF(out, "%s", name);
- } else {
- bool is_first = true;
- PrintF(out, "(");
- for (int mask = 1; mask != 0; mask = mask << 1) {
- if ((bitset & mask) != 0) {
- if (!is_first) PrintF(out, " | ");
- is_first = false;
- PrintF(out, "%s", bitset_name(mask));
- }
- }
- PrintF(out, ")");
+ switch (dim) {
+ case BOTH_DIMS:
+ BitsetTypePrint(out, bitset & kSemantic);
+ PrintF("/");
+ BitsetTypePrint(out, bitset & kRepresentation);
+ break;
+ case SEMANTIC_DIM:
+ BitsetTypePrint(out, bitset & kSemantic);
+ break;
+ case REPRESENTATION_DIM:
+ BitsetTypePrint(out, bitset & kRepresentation);
+ break;
}
} else if (this->IsConstant()) {
PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
=======================================
--- /branches/bleeding_edge/src/types.h Tue Mar 11 10:53:13 2014 UTC
+++ /branches/bleeding_edge/src/types.h Tue Mar 18 11:50:18 2014 UTC
@@ -42,7 +42,10 @@
// can express class types (a.k.a. specific maps) and singleton types
(i.e.,
// concrete constants).
//
-// The following equations and inequations hold:
+// Types consist of two dimensions: semantic (value range) and
representation.
+// Both are related through subtyping.
+//
+// The following equations and inequations hold for the semantic axis:
//
// None <= T
// T <= Any
@@ -54,13 +57,12 @@
// UniqueName = InternalizedString \/ Symbol
// InternalizedString < String
//
-// Allocated = Receiver \/ Number \/ Name
-// Detectable = Allocated - Undetectable
-// Undetectable < Object
// Receiver = Object \/ Proxy
// Array < Object
// Function < Object
// RegExp < Object
+// Undetectable < Object
+// Detectable = Receiver \/ Number \/ Name - Undetectable
//
// Class(map) < T iff instance_type(map) < T
// Constant(x) < T iff instance_type(map(x)) < T
@@ -70,20 +72,43 @@
// TODO(rossberg): the latter is not currently true for proxies, because
of fix,
// but will hold once we implement direct proxies.
//
+// For the representation axis, the following holds:
+//
+// None <= R
+// R <= Any
+//
+// UntaggedInt <= UntaggedInt8 \/ UntaggedInt16 \/ UntaggedInt32)
+// UntaggedFloat <= UntaggedFloat32 \/ UntaggedFloat64
+// UntaggedNumber <= UntaggedInt \/ UntaggedFloat
+// Untagged <= UntaggedNumber \/ UntaggedPtr
+// Tagged <= TaggedInt \/ TaggedPtr
+//
+// Subtyping relates the two dimensions, for example:
+//
+// Number <= Tagged \/ UntaggedNumber
+// Object <= TaggedPtr \/ UntaggedPtr
+//
+// That holds because the semantic type constructors defined by the API
create
+// types that allow for all possible representations, and dually, the ones
for
+// representation types initially include all semantic ranges.
Representations
+// can then e.g. be narrowed for a given semantic type using intersection:
+//
+// SignedSmall /\ TaggedInt (a 'smi')
+// Number /\ TaggedPtr (a heap number)
+//
// There are two main functions for testing types:
//
// T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
// T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/=
0)
//
// Typically, the former is to be used to select representations (e.g., via
-// T->Is(Integer31())), and the to check whether a specific case needs
handling
-// (e.g., via T->Maybe(Number())).
+// T->Is(SignedSmall())), and the latter to check whether a specific case
needs
+// handling (e.g., via T->Maybe(Number())).
//
// There is no functionality to discover whether a type is a leaf in the
// lattice. That is intentional. It should always be possible to refine the
// lattice (e.g., splitting up number types further) without invalidating
any
// existing assumptions or tests.
-//
// Consequently, do not use pointer equality for type tests, always use Is!
//
// Internally, all 'primitive' types, and their unions, are represented as
@@ -100,40 +125,68 @@
// them. For zone types, no query method touches the heap, only
constructors do.
-#define BITSET_TYPE_LIST(V) \
- V(None, 0) \
- V(Null, 1 << 0) \
- V(Undefined, 1 << 1) \
- V(Boolean, 1 << 2) \
- V(Smi, 1 << 3) \
- V(OtherSigned32, 1 << 4) \
- V(Unsigned32, 1 << 5) \
- V(Double, 1 << 6) \
- V(Symbol, 1 << 7) \
- V(InternalizedString, 1 << 8) \
- V(OtherString, 1 << 9) \
- V(Undetectable, 1 << 10) \
- V(Array, 1 << 11) \
- V(Function, 1 << 12) \
- V(RegExp, 1 << 13) \
- V(OtherObject, 1 << 14) \
- V(Proxy, 1 << 15) \
- V(Internal, 1 << 16) \
+#define MASK_BITSET_TYPE_LIST(V) \
+ V(Representation, static_cast<int>(0xff800000)) \
+ V(Semantic, static_cast<int>(0x007fffff))
+
+#define REPRESENTATION(k) ((k) & kRepresentation)
+#define SEMANTIC(k) ((k) & kSemantic)
+
+#define REPRESENTATION_BITSET_TYPE_LIST(V) \
+ V(None, 0) \
+ V(UntaggedInt8, 1 << 23 | kSemantic) \
+ V(UntaggedInt16, 1 << 24 | kSemantic) \
+ V(UntaggedInt32, 1 << 25 | kSemantic) \
+ V(UntaggedFloat32, 1 << 26 | kSemantic) \
+ V(UntaggedFloat64, 1 << 27 | kSemantic) \
+ V(UntaggedPtr, 1 << 28 | kSemantic) \
+ V(TaggedInt, 1 << 29 | kSemantic) \
+ V(TaggedPtr, -1 << 30 | kSemantic) /* MSB has to be
sign-extended */ \
+ \
+ V(UntaggedInt, kUntaggedInt8 | kUntaggedInt16 | kUntaggedInt32) \
+ V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
+ V(UntaggedNumber, kUntaggedInt | kUntaggedFloat) \
+ V(Untagged, kUntaggedNumber | kUntaggedPtr) \
+ V(Tagged, kTaggedInt | kTaggedPtr)
+
+#define SEMANTIC_BITSET_TYPE_LIST(V) \
+ V(Null, 1 << 0 | REPRESENTATION(kTaggedPtr)) \
+ V(Undefined, 1 << 1 | REPRESENTATION(kTaggedPtr)) \
+ V(Boolean, 1 << 2 | REPRESENTATION(kTaggedPtr)) \
+ V(SignedSmall, 1 << 3 | REPRESENTATION(kTagged |
kUntaggedNumber)) \
+ V(OtherSigned32, 1 << 4 | REPRESENTATION(kTagged |
kUntaggedNumber)) \
+ V(Unsigned32, 1 << 5 | REPRESENTATION(kTagged |
kUntaggedNumber)) \
+ V(Float, 1 << 6 | REPRESENTATION(kTagged |
kUntaggedNumber)) \
+ V(Symbol, 1 << 7 | REPRESENTATION(kTaggedPtr)) \
+ V(InternalizedString, 1 << 8 | REPRESENTATION(kTaggedPtr)) \
+ V(OtherString, 1 << 9 | REPRESENTATION(kTaggedPtr)) \
+ V(Undetectable, 1 << 10 | REPRESENTATION(kTaggedPtr)) \
+ V(Array, 1 << 11 | REPRESENTATION(kTaggedPtr)) \
+ V(Function, 1 << 12 | REPRESENTATION(kTaggedPtr)) \
+ V(RegExp, 1 << 13 | REPRESENTATION(kTaggedPtr)) \
+ V(OtherObject, 1 << 14 | REPRESENTATION(kTaggedPtr)) \
+ V(Proxy, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
+ V(Internal, 1 << 16 | REPRESENTATION(kTagged | kUntagged)) \
\
- V(Oddball, kBoolean | kNull | kUndefined) \
- V(Signed32, kSmi | kOtherSigned32) \
- V(Number, kSigned32 | kUnsigned32 | kDouble) \
- V(String, kInternalizedString | kOtherString) \
- V(UniqueName, kSymbol | kInternalizedString) \
- V(Name, kSymbol | kString) \
- V(NumberOrString, kNumber | kString) \
- V(Object, kUndetectable | kArray | kFunction | \
- kRegExp | kOtherObject) \
- V(Receiver, kObject | kProxy) \
- V(Allocated, kDouble | kName | kReceiver) \
- V(Any, kOddball | kNumber | kAllocated | kInternal) \
- V(NonNumber, kAny - kNumber) \
- V(Detectable, kAllocated - kUndetectable)
+ V(Oddball, kBoolean | kNull | kUndefined) \
+ V(Signed32, kSignedSmall | kOtherSigned32) \
+ V(Number, kSigned32 | kUnsigned32 | kFloat) \
+ V(String, kInternalizedString | kOtherString) \
+ V(UniqueName, kSymbol | kInternalizedString) \
+ V(Name, kSymbol | kString) \
+ V(NumberOrString, kNumber | kString) \
+ V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
+ V(DetectableReceiver, kDetectableObject | kProxy) \
+ V(Detectable, kDetectableReceiver | kNumber | kName) \
+ V(Object, kDetectableObject | kUndetectable) \
+ V(Receiver, kObject | kProxy) \
+ V(NonNumber, kOddball | kName | kReceiver | kInternal) \
+ V(Any, kNumber | kNonNumber)
+
+#define BITSET_TYPE_LIST(V) \
+ MASK_BITSET_TYPE_LIST(V) \
+ REPRESENTATION_BITSET_TYPE_LIST(V) \
+ SEMANTIC_BITSET_TYPE_LIST(V)
// struct Config {
@@ -254,8 +307,9 @@
typename OtherTypeImpl::TypeHandle type, Region* region);
#ifdef OBJECT_PRINT
- void TypePrint();
- void TypePrint(FILE* out);
+ enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
+ void TypePrint(PrintDimension = BOTH_DIMS);
+ void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
#endif
private:
@@ -292,6 +346,10 @@
bool SlowIs(TypeImpl* that);
+ static bool IsInhabited(int bitset) {
+ return (bitset & kRepresentation) && (bitset & kSemantic);
+ }
+
int LubBitset(); // least upper bound that's a bitset
int GlbBitset(); // greatest lower bound that's a bitset
@@ -306,6 +364,7 @@
#ifdef OBJECT_PRINT
static const char* bitset_name(int bitset);
+ static void BitsetTypePrint(FILE* out, int bitset);
#endif
};
=======================================
--- /branches/bleeding_edge/src/typing.cc Mon Mar 17 08:31:21 2014 UTC
+++ /branches/bleeding_edge/src/typing.cc Tue Mar 18 11:50:18 2014 UTC
@@ -612,7 +612,7 @@
RECURSE(Visit(expr->expression()));
- NarrowType(expr, Bounds(Type::Smi(zone()), Type::Number(zone())));
+ NarrowType(expr, Bounds(Type::SignedSmall(zone()),
Type::Number(zone())));
VariableProxy* proxy = expr->expression()->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsStackAllocated()) {
@@ -668,7 +668,7 @@
Type* upper = Type::Union(
expr->left()->bounds().upper, expr->right()->bounds().upper,
zone());
if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
- Type* lower = Type::Intersect(Type::Smi(zone()), upper, zone());
+ Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper,
zone());
NarrowType(expr, Bounds(lower, upper));
break;
}
@@ -677,7 +677,8 @@
case Token::SAR:
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- NarrowType(expr, Bounds(Type::Smi(zone()), Type::Signed32(zone())));
+ NarrowType(expr,
+ Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())));
break;
case Token::SHR:
RECURSE(Visit(expr->left()));
@@ -685,7 +686,7 @@
// TODO(rossberg): The upper bound would be Unsigned32, but since
there
// is no 'positive Smi' type for the lower bound, we use the smallest
// union of Smi and Unsigned32 as upper bound instead.
- NarrowType(expr, Bounds(Type::Smi(zone()), Type::Number(zone())));
+ NarrowType(expr, Bounds(Type::SignedSmall(zone()),
Type::Number(zone())));
break;
case Token::ADD: {
RECURSE(Visit(expr->left()));
@@ -698,7 +699,7 @@
l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ?
Type::String(zone()) :
l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ?
- Type::Smi(zone()) : Type::None(zone());
+ Type::SignedSmall(zone()) : Type::None(zone());
Type* upper =
l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ?
Type::String(zone()) :
@@ -713,7 +714,7 @@
case Token::MOD:
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- NarrowType(expr, Bounds(Type::Smi(zone()), Type::Number(zone())));
+ NarrowType(expr, Bounds(Type::SignedSmall(zone()),
Type::Number(zone())));
break;
default:
UNREACHABLE();
=======================================
--- /branches/bleeding_edge/test/cctest/test-types.cc Tue Mar 11 10:28:38
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-types.cc Tue Mar 18 11:50:18
2014 UTC
@@ -34,6 +34,8 @@
class Types {
public:
Types(Region* region, Isolate* isolate) :
+ Representation(Type::Representation(region)),
+ Semantic(Type::Semantic(region)),
None(Type::None(region)),
Any(Type::Any(region)),
Oddball(Type::Oddball(region)),
@@ -41,9 +43,9 @@
Null(Type::Null(region)),
Undefined(Type::Undefined(region)),
Number(Type::Number(region)),
- Smi(Type::Smi(region)),
+ SignedSmall(Type::SignedSmall(region)),
Signed32(Type::Signed32(region)),
- Double(Type::Double(region)),
+ Float(Type::Float(region)),
Name(Type::Name(region)),
UniqueName(Type::UniqueName(region)),
String(Type::String(region)),
@@ -72,6 +74,8 @@
ArrayConstant2 = Type::Constant(array, region);
}
+ TypeHandle Representation;
+ TypeHandle Semantic;
TypeHandle None;
TypeHandle Any;
TypeHandle Oddball;
@@ -79,9 +83,9 @@
TypeHandle Null;
TypeHandle Undefined;
TypeHandle Number;
- TypeHandle Smi;
+ TypeHandle SignedSmall;
TypeHandle Signed32;
- TypeHandle Double;
+ TypeHandle Float;
TypeHandle Name;
TypeHandle UniqueName;
TypeHandle String;
@@ -236,7 +240,7 @@
T(Rep::ToRegion(&zone, isolate), isolate) {
}
- static void CheckEqual(TypeHandle type1, TypeHandle type2) {
+ 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));
@@ -256,7 +260,7 @@
CHECK(type2->Is(type1));
}
- static void CheckSub(TypeHandle type1, TypeHandle type2) {
+ void CheckSub(TypeHandle type1, TypeHandle type2) {
CHECK(type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
@@ -264,7 +268,7 @@
}
}
- static void CheckUnordered(TypeHandle type1, TypeHandle type2) {
+ void CheckUnordered(TypeHandle type1, TypeHandle type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
@@ -272,21 +276,23 @@
}
}
- static void CheckOverlap(TypeHandle type1, TypeHandle type2) {
+ void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
CHECK(type1->Maybe(type2));
CHECK(type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
- CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
+ CHECK_NE(0,
+ Rep::AsBitset(type1) & Rep::AsBitset(type2) &
Rep::AsBitset(mask));
}
}
- static void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
+ void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
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));
+ CHECK_EQ(0,
+ Rep::AsBitset(type1) & Rep::AsBitset(type2) &
Rep::AsBitset(mask));
}
}
@@ -300,10 +306,12 @@
CHECK(this->IsBitset(T.Union(T.String, T.Receiver)));
CHECK_EQ(0, this->AsBitset(T.None));
- CHECK_EQ(this->AsBitset(T.Number) | this->AsBitset(T.String),
- this->AsBitset(T.Union(T.String, T.Number)));
- CHECK_EQ(this->AsBitset(T.Receiver),
- this->AsBitset(T.Union(T.Receiver, T.Object)));
+ CHECK_EQ(
+ this->AsBitset(T.Number) | this->AsBitset(T.String),
+ this->AsBitset(T.Union(T.String, T.Number)));
+ CHECK_EQ(
+ this->AsBitset(T.Receiver),
+ this->AsBitset(T.Union(T.Receiver, T.Object)));
}
void Class() {
@@ -352,12 +360,12 @@
CheckUnordered(T.Boolean, T.Undefined);
CheckSub(T.Number, T.Any);
- CheckSub(T.Smi, T.Number);
+ CheckSub(T.SignedSmall, 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.Float, T.Number);
+ CheckSub(T.SignedSmall, T.Signed32);
+ CheckUnordered(T.SignedSmall, T.Float);
+ CheckUnordered(T.Signed32, T.Float);
CheckSub(T.Name, T.Any);
CheckSub(T.UniqueName, T.Any);
@@ -391,7 +399,7 @@
CheckSub(T.ArrayClass, T.Object);
CheckUnordered(T.ObjectClass, T.ArrayClass);
- CheckSub(T.SmiConstant, T.Smi);
+ CheckSub(T.SmiConstant, T.SignedSmall);
CheckSub(T.SmiConstant, T.Signed32);
CheckSub(T.SmiConstant, T.Number);
CheckSub(T.ObjectConstant1, T.Object);
@@ -409,71 +417,71 @@
}
void Maybe() {
- CheckOverlap(T.Any, T.Any);
- CheckOverlap(T.Object, T.Object);
+ CheckOverlap(T.Any, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Object, T.Semantic);
- 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.Oddball, T.Any, T.Semantic);
+ CheckOverlap(T.Boolean, T.Oddball, T.Semantic);
+ CheckOverlap(T.Null, T.Oddball, T.Semantic);
+ CheckOverlap(T.Undefined, T.Oddball, T.Semantic);
+ CheckDisjoint(T.Boolean, T.Null, T.Semantic);
+ CheckDisjoint(T.Undefined, T.Null, T.Semantic);
+ CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
- CheckOverlap(T.Number, T.Any);
- CheckOverlap(T.Smi, T.Number);
- CheckOverlap(T.Double, T.Number);
- CheckDisjoint(T.Signed32, T.Double);
+ CheckOverlap(T.Number, T.Any, T.Semantic);
+ CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
+ CheckOverlap(T.Float, T.Number, T.Semantic);
+ CheckDisjoint(T.Signed32, T.Float, T.Semantic);
- 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.Name, T.Any, T.Semantic);
+ CheckOverlap(T.UniqueName, T.Any, T.Semantic);
+ CheckOverlap(T.UniqueName, T.Name, T.Semantic);
+ CheckOverlap(T.String, T.Name, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.String, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.Name, T.Semantic);
+ CheckOverlap(T.Symbol, T.UniqueName, T.Semantic);
+ CheckOverlap(T.Symbol, T.Name, T.Semantic);
+ CheckOverlap(T.String, T.UniqueName, T.Semantic);
+ CheckDisjoint(T.String, T.Symbol, T.Semantic);
+ CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
- 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.Receiver, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Receiver, T.Semantic);
+ CheckOverlap(T.Array, T.Object, T.Semantic);
+ CheckOverlap(T.Function, T.Object, T.Semantic);
+ CheckOverlap(T.Proxy, T.Receiver, T.Semantic);
+ CheckDisjoint(T.Object, T.Proxy, T.Semantic);
+ CheckDisjoint(T.Array, T.Function, T.Semantic);
- CheckOverlap(T.ObjectClass, T.Any);
- CheckOverlap(T.ObjectConstant1, T.Any);
+ CheckOverlap(T.ObjectClass, T.Any, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.Any, T.Semantic);
- 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.ObjectClass, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
+ CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
+ CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic);
- 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);
+ CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
+ CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
+ CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
+ CheckDisjoint(T.SmiConstant, T.Float, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
+ CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.Array, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.ArrayConstant2, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1, T.Semantic);
- 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);
+ CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ArrayConstant1, T.ObjectClass, T.Semantic);
}
void Union() {
@@ -498,8 +506,8 @@
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);
+ CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array,
T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number,
T.Semantic);
// Constant-constant
CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
@@ -520,11 +528,16 @@
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);
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array, T.Semantic);
+ CheckOverlap(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2,
+ T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number,
T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass,
+ T.Semantic);
// Bitset-class
CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object)));
@@ -533,11 +546,12 @@
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.SignedSmall), 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);
+ CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic);
// Bitset-constant
CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number)));
@@ -552,8 +566,8 @@
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);
+ CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object,
T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number,
T.Semantic);
CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
// Class-constant
@@ -569,8 +583,11 @@
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);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2,
+ T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass,
T.Semantic);
// Bitset-union
CHECK(this->IsBitset(
@@ -585,19 +602,19 @@
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
CheckSub(
- T.Double,
+ T.Float,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
CheckSub(
T.ObjectConstant1,
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float));
CheckSub(
T.None,
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float));
CheckSub(
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
T.Any);
CheckSub(
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
// Class-union
@@ -661,7 +678,9 @@
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.Union(T.Number, T.ArrayClass),
+ T.Union(T.SignedSmall, T.Array)),
T.Union(T.Number, T.Array));
}
@@ -672,7 +691,7 @@
CHECK(this->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);
+ CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation);
CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String,
T.Name));
CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
@@ -699,15 +718,15 @@
CHECK(this->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);
+ CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
+ CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
// Bitset-constant
- CHECK(this->IsBitset(T.Intersect(T.Smi, T.Number)));
+ CHECK(this->IsBitset(T.Intersect(T.SignedSmall, T.Number)));
CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number)));
CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
- CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
+ CheckEqual(T.Intersect(T.SignedSmall, T.Number), T.SignedSmall);
CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
CheckEqual(T.Intersect(T.ObjectConstant1, T.Object),
T.ObjectConstant1);
@@ -778,8 +797,8 @@
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ArrayClass),
- T.Union(T.Smi, T.Array)),
- T.Union(T.Smi, T.ArrayClass));
+ T.Union(T.SignedSmall, T.Array)),
+ T.Union(T.SignedSmall, T.ArrayClass));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ObjectClass),
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.