Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(876)

Unified Diff: src/types.h

Issue 176843006: Introduce representation types (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use smi MSB Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.cc ('k') | src/types.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/types.h
diff --git a/src/types.h b/src/types.h
index 48b39335b63dcd5c4da0f468f30afd4efaa409d4..d9dc1e915c691e438361b598a340c62fc600a881 100644
--- a/src/types.h
+++ b/src/types.h
@@ -42,7 +42,10 @@ namespace internal {
// 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 @@ namespace internal {
// 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,65 +72,121 @@ namespace internal {
// 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
-// bitsets via smis. Class is a heap pointer to the respective map. Only
-// Constant's, or unions containing Class'es or Constant's, require allocation.
+// bitsets. Class is a heap pointer to the respective map. Only Constant's, or
+// unions containing Class'es or Constant's, currently require allocation.
// Note that the bitset representation is closed under both Union and Intersect.
//
-// The type representation is heap-allocated, so cannot (currently) be used in
-// a concurrent compilation context.
-
-
-#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) \
+// There are two type representations, using different allocation:
+//
+// - class Type (zone-allocated, for compiler and concurrent compilation)
+// - class HeapType (heap-allocated, for persistent types)
+//
+// Both provide the same API, and the Convert method can be used to interconvert
+// them.
+
+
+#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 */ \
Michael Starzinger 2014/03/04 15:02:25 I would be fine with this. If either Benedikt or S
Sven Panne 2014/03/05 07:22:36 As already discussed yesterday, I consider this si
Benedikt Meurer 2014/03/05 07:28:07 I agree. We should not introduce hacks like this u
rossberg 2014/03/14 10:37:37 Michael yesterday (after you had left) expressed v
Michael Starzinger 2014/03/14 10:49:36 So just to clarify: My strong disagreement is agai
+ \
+ 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 {
@@ -248,8 +306,9 @@ class TypeImpl : public Config::Base {
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:
@@ -286,6 +345,10 @@ class TypeImpl : public Config::Base {
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
@@ -300,6 +363,7 @@ class TypeImpl : public Config::Base {
#ifdef OBJECT_PRINT
static const char* bitset_name(int bitset);
+ static void BitsetTypePrint(FILE* out, int bitset);
#endif
};
« no previous file with comments | « src/ic.cc ('k') | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698