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

Unified Diff: src/types.h

Issue 558193003: Redesign of the internal type system. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | « no previous file | src/types.cc » ('j') | src/types.cc » ('J')
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 cca8b3167b4bb9b86773d7fcf40959490a9164f0..2f96c333f2f0446f991a845d855563578c660b41 100644
--- a/src/types.h
+++ b/src/types.h
@@ -5,6 +5,7 @@
#ifndef V8_TYPES_H_
#define V8_TYPES_H_
+#include "src/conversions.h"
#include "src/factory.h"
#include "src/handles.h"
#include "src/ostreams.h"
@@ -112,8 +113,8 @@ namespace internal {
// PROPERTIES
//
// Various formal properties hold for constructors, operators, and predicates
-// over types. For example, constructors are injective, subtyping is a complete
-// partial order, union and intersection satisfy the usual algebraic properties.
+// over types. For example, constructors are injective and subtyping is a
+// complete partial order.
//
// See test/cctest/test-types.cc for a comprehensive executable specification,
// especially with respect to the properties of the more exotic 'temporal'
@@ -208,11 +209,35 @@ namespace internal {
kUndefined | kInternal) \
V(Any, -1)
-#define BITSET_TYPE_LIST(V) \
- MASK_BITSET_TYPE_LIST(V) \
+/*
+ * The following diagrams show how integers (in the mathematical sense) are
+ * divided among the different atomic numerical types.
+ *
+ * If SmiValuesAre31Bits():
+ *
+ * ON OS32 OSS US OU31 OU32 ON
+ * ______[_______[_______[_______[_______[_______[_______
+ * -2^31 -2^30 0 2^30 2^31 2^32
+ *
+ * Otherwise:
rossberg 2014/09/10 15:44:15 Nit: indentation off
neis1 2014/09/11 12:58:12 Done.
+ *
+ * ON OSS US OU32 ON
+ * ______[_______________[_______________[_______[_______
+ * -2^31 0 2^31 2^32
+ *
+ *
+ * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
+ *
+ */
+
+#define PROPER_BITSET_TYPE_LIST(V) \
REPRESENTATION_BITSET_TYPE_LIST(V) \
SEMANTIC_BITSET_TYPE_LIST(V)
+#define BITSET_TYPE_LIST(V) \
+ MASK_BITSET_TYPE_LIST(V) \
+ PROPER_BITSET_TYPE_LIST(V)
+
// -----------------------------------------------------------------------------
// The abstract Type class, parameterized over the low-level representation.
@@ -279,17 +304,17 @@ class TypeImpl : public Config::Base {
static TypeHandle type(Region* region) { \
return BitsetType::New(BitsetType::k##type, region); \
}
- BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
+ PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
#undef DEFINE_TYPE_CONSTRUCTOR
static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
return ClassType::New(map, region);
}
static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
- // TODO(neis): Return RangeType for numerical values.
return ConstantType::New(value, region);
}
- static TypeHandle Range(double min, double max, Region* region) {
+ static TypeHandle Range(
+ i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
return RangeType::New(min, max, region);
}
static TypeHandle Context(TypeHandle outer, Region* region) {
@@ -357,7 +382,7 @@ class TypeImpl : public Config::Base {
template<class TypeHandle>
bool Equals(TypeHandle that) { return this->Equals(*that); }
- // Equivalent to Constant(value)->Is(this), but avoiding allocation.
+ // Equivalent to Constant(val)->Is(this), but avoiding allocation.
bool Contains(i::Object* val);
bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
@@ -466,16 +491,42 @@ class TypeImpl : public Config::Base {
int BitsetGlb() { return BitsetType::Glb(this); }
int BitsetLub() { return BitsetType::Lub(this); }
- int InherentBitsetLub() { return BitsetType::InherentLub(this); }
bool SlowIs(TypeImpl* that);
- TypeHandle Rebound(int bitset, Region* region);
- int BoundBy(TypeImpl* that);
- int IndexInUnion(int bound, UnionHandle unioned, int current_size);
- static int ExtendUnion(
- UnionHandle unioned, int current_size, TypeHandle t,
- TypeHandle other, bool is_intersect, Region* region);
+ static bool IsInteger(double x) {
+ return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
+ }
+ static bool IsInteger(i::Object* x) {
+ return x->IsNumber() && IsInteger(x->Number());
+ }
+
+ struct Limits {
+ i::Handle<i::Object> min;
+ i::Handle<i::Object> max;
+ Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) :
+ min(min), max(max) {}
+ explicit Limits(RangeType* range) :
+ min(range->MinV()), max(range->MaxV()) {}
+ };
+
+ static Limits intersect(Limits lhs, Limits rhs);
+ static Limits union_(Limits lhs, Limits rhs);
+ static bool overlap(RangeType* lhs, RangeType* rhs);
+ static bool contains(RangeType* lhs, RangeType* rhs);
+ static bool contains(RangeType* range, i::Object* val);
+
+ RangeType* GetRange();
+ static int UpdateRange(
+ RangeHandle type, UnionHandle result, int size, Region* region);
+
+ bool SimplyEquals(TypeImpl* that);
+ static int AddToUnion(
+ TypeHandle type, UnionHandle result, int size, Region* region);
+ static int IntersectAux(
+ TypeHandle type, TypeHandle other,
+ UnionHandle result, int size, Region* region);
+ static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
};
@@ -497,9 +548,11 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
int Bitset() { return Config::as_bitset(this); }
static TypeImpl* New(int bitset) {
+ DCHECK(bitset == kNone || IsInhabited(bitset));
return static_cast<BitsetType*>(Config::from_bitset(bitset));
}
static TypeHandle New(int bitset, Region* region) {
+ DCHECK(bitset == kNone || IsInhabited(bitset));
return Config::from_bitset(bitset, region);
}
@@ -518,12 +571,14 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
static int Lub(int32_t value);
static int Lub(uint32_t value);
static int Lub(i::Map* map);
- static int Lub(double min, double max);
- static int InherentLub(TypeImpl* type);
+ static int Lub(Limits lim);
+ static double Min(int bitset);
static const char* Name(int bitset);
static void Print(OStream& os, int bitset); // NOLINT
- using TypeImpl::PrintTo;
+#ifdef DEBUG
+ static void Print(int bitset);
+#endif
};
@@ -609,36 +664,21 @@ class TypeImpl<Config>::UnionType : public StructuralType {
template<class Config>
class TypeImpl<Config>::ClassType : public StructuralType {
public:
- TypeHandle Bound(Region* region) {
- return Config::is_class(this)
- ? BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region)
- : this->Get(0);
- }
i::Handle<i::Map> Map() {
return Config::is_class(this)
? Config::as_class(this)
- : this->template GetValue<i::Map>(1);
- }
-
- static ClassHandle New(
- i::Handle<i::Map> map, TypeHandle bound, Region* region) {
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*map)));
- ClassHandle type = Config::template cast<ClassType>(
- StructuralType::New(StructuralType::kClassTag, 2, region));
- type->Set(0, bound);
- type->SetValue(1, map);
- return type;
+ : this->template GetValue<i::Map>(0);
}
static ClassHandle New(i::Handle<i::Map> map, Region* region) {
ClassHandle type =
Config::template cast<ClassType>(Config::from_class(map, region));
- if (type->IsClass()) {
- return type;
- } else {
- TypeHandle bound = BitsetType::New(BitsetType::Lub(*map), region);
- return New(map, bound, region);
+ if (!type->IsClass()) {
+ type = Config::template cast<ClassType>(
+ StructuralType::New(StructuralType::kClassTag, 1, region));
rossberg 2014/09/10 15:44:15 Nit: style guide wants +4 indentation for line con
neis1 2014/09/11 12:58:12 Done.
+ type->SetValue(0, map);
}
+ return type;
}
static ClassType* cast(TypeImpl* type) {
@@ -654,22 +694,15 @@ class TypeImpl<Config>::ClassType : public StructuralType {
template<class Config>
class TypeImpl<Config>::ConstantType : public StructuralType {
public:
- TypeHandle Bound() { return this->Get(0); }
- i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
-
- static ConstantHandle New(
- i::Handle<i::Object> value, TypeHandle bound, Region* region) {
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*value)));
- ConstantHandle type = Config::template cast<ConstantType>(
- StructuralType::New(StructuralType::kConstantTag, 2, region));
- type->Set(0, bound);
- type->SetValue(1, value);
- return type;
+ i::Handle<i::Object> Value() {
+ return this->template GetValue<i::Object>(0);
rossberg 2014/09/10 15:44:15 Nit: probably fits on previous line
neis1 2014/09/11 12:58:12 Done.
}
static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
- TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region);
- return New(value, bound, region);
+ ConstantHandle type = Config::template cast<ConstantType>(
+ StructuralType::New(StructuralType::kConstantTag, 1, region));
+ type->SetValue(0, value);
+ return type;
}
static ConstantType* cast(TypeImpl* type) {
@@ -681,31 +714,35 @@ class TypeImpl<Config>::ConstantType : public StructuralType {
// -----------------------------------------------------------------------------
// Range types.
+// They represent continuous integer intervals in the form of a minimum
rossberg 2014/09/10 15:44:15 This should go to the top, along with the other ex
neis1 2014/09/11 12:58:12 Done.
+// and a maximum value. Either value might be an infinity.
+//
+// Constant(v) is considered a subtype of Range(x..y) if v happens to be an
+// integer between x and y.
template<class Config>
class TypeImpl<Config>::RangeType : public StructuralType {
public:
- TypeHandle Bound() { return this->Get(0); }
- double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); }
- double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); }
+ i::Handle<i::Object> MinV() { return this->template GetValue<i::Object>(0); }
+ i::Handle<i::Object> MaxV() { return this->template GetValue<i::Object>(1); }
+ double Min() { return MinV()->Number(); }
+ double Max() { return MaxV()->Number(); }
rossberg 2014/09/10 15:44:15 Since we call the method to get a numeric value fr
neis1 2014/09/11 12:58:12 Not sure I'm following. Are you suggesting to exp
rossberg 2014/09/15 15:58:29 The latter. It's more consistent with our naming e
neis1 2014/09/16 10:03:59 But less consistent with the naming here, such as
rossberg 2014/09/16 14:04:40 OK, fair enough. Actually, I'd say, just remove th
neis1 2014/09/18 13:05:18 Done.
static RangeHandle New(
- double min, double max, TypeHandle bound, Region* region) {
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(min, max)));
+ i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
+ DCHECK(min->Number() <= max->Number());
RangeHandle type = Config::template cast<RangeType>(
- StructuralType::New(StructuralType::kRangeTag, 3, region));
- type->Set(0, bound);
- Factory* factory = Config::isolate(region)->factory();
- Handle<HeapNumber> minV = factory->NewHeapNumber(min);
- Handle<HeapNumber> maxV = factory->NewHeapNumber(max);
- type->SetValue(1, minV);
- type->SetValue(2, maxV);
+ StructuralType::New(StructuralType::kRangeTag, 2, region));
+ type->SetValue(0, min);
+ type->SetValue(1, max);
+#ifdef DEBUG
rossberg 2014/09/10 15:44:15 Debugging left-overs?
neis1 2014/09/11 12:58:12 Done.
+ type->Print();
+#endif
return type;
}
- static RangeHandle New(double min, double max, Region* region) {
- TypeHandle bound = BitsetType::New(BitsetType::Lub(min, max), region);
- return New(min, max, bound, region);
+ static RangeHandle New(Limits lim, Region* region) {
+ return New(lim.min, lim.max, region);
}
static RangeType* cast(TypeImpl* type) {
@@ -721,25 +758,15 @@ class TypeImpl<Config>::RangeType : public StructuralType {
template<class Config>
class TypeImpl<Config>::ContextType : public StructuralType {
public:
- TypeHandle Bound() { return this->Get(0); }
- TypeHandle Outer() { return this->Get(1); }
+ TypeHandle Outer() { return this->Get(0); }
- static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) {
- DCHECK(BitsetType::Is(
- bound->AsBitset(), BitsetType::kInternal & BitsetType::kTaggedPtr));
+ static ContextHandle New(TypeHandle outer, Region* region) {
ContextHandle type = Config::template cast<ContextType>(
- StructuralType::New(StructuralType::kContextTag, 2, region));
- type->Set(0, bound);
- type->Set(1, outer);
+ StructuralType::New(StructuralType::kContextTag, 1, region));
+ type->Set(0, outer);
return type;
}
- static ContextHandle New(TypeHandle outer, Region* region) {
- TypeHandle bound = BitsetType::New(
- BitsetType::kInternal & BitsetType::kTaggedPtr, region);
- return New(outer, bound, region);
- }
-
static ContextType* cast(TypeImpl* type) {
DCHECK(type->IsContext());
return static_cast<ContextType*>(type);
@@ -753,23 +780,15 @@ class TypeImpl<Config>::ContextType : public StructuralType {
template<class Config>
class TypeImpl<Config>::ArrayType : public StructuralType {
public:
- TypeHandle Bound() { return this->Get(0); }
- TypeHandle Element() { return this->Get(1); }
+ TypeHandle Element() { return this->Get(0); }
- static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) {
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kArray));
+ static ArrayHandle New(TypeHandle element, Region* region) {
ArrayHandle type = Config::template cast<ArrayType>(
- StructuralType::New(StructuralType::kArrayTag, 2, region));
- type->Set(0, bound);
- type->Set(1, element);
+ StructuralType::New(StructuralType::kArrayTag, 1, region));
+ type->Set(0, element);
return type;
}
- static ArrayHandle New(TypeHandle element, Region* region) {
- TypeHandle bound = BitsetType::New(BitsetType::kArray, region);
- return New(element, bound, region);
- }
-
static ArrayType* cast(TypeImpl* type) {
DCHECK(type->IsArray());
return static_cast<ArrayType*>(type);
@@ -783,32 +802,22 @@ class TypeImpl<Config>::ArrayType : public StructuralType {
template<class Config>
class TypeImpl<Config>::FunctionType : public StructuralType {
public:
- int Arity() { return this->Length() - 3; }
- TypeHandle Bound() { return this->Get(0); }
- TypeHandle Result() { return this->Get(1); }
- TypeHandle Receiver() { return this->Get(2); }
- TypeHandle Parameter(int i) { return this->Get(3 + i); }
+ int Arity() { return this->Length() - 2; }
+ TypeHandle Result() { return this->Get(0); }
+ TypeHandle Receiver() { return this->Get(1); }
+ TypeHandle Parameter(int i) { return this->Get(2 + i); }
- void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); }
+ void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
static FunctionHandle New(
- TypeHandle result, TypeHandle receiver, TypeHandle bound,
- int arity, Region* region) {
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kFunction));
+ TypeHandle result, TypeHandle receiver, int arity, Region* region) {
FunctionHandle type = Config::template cast<FunctionType>(
- StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region));
- type->Set(0, bound);
- type->Set(1, result);
- type->Set(2, receiver);
+ StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
+ type->Set(0, result);
+ type->Set(1, receiver);
return type;
}
- static FunctionHandle New(
- TypeHandle result, TypeHandle receiver, int arity, Region* region) {
- TypeHandle bound = BitsetType::New(BitsetType::kFunction, region);
- return New(result, receiver, bound, arity, region);
- }
-
static FunctionType* cast(TypeImpl* type) {
DCHECK(type->IsFunction());
return static_cast<FunctionType*>(type);
@@ -853,11 +862,6 @@ struct ZoneTypeConfig {
typedef i::Zone Region;
template<class T> struct Handle { typedef T* type; };
- // TODO(neis): This will be removed again once we have struct_get_double().
- static inline i::Isolate* isolate(Region* region) {
- return region->isolate();
- }
-
template<class T> static inline T* handle(T* type);
template<class T> static inline T* cast(Type* type);
@@ -900,11 +904,6 @@ struct HeapTypeConfig {
typedef i::Isolate Region;
template<class T> struct Handle { typedef i::Handle<T> type; };
- // TODO(neis): This will be removed again once we have struct_get_double().
- static inline i::Isolate* isolate(Region* region) {
- return region;
- }
-
template<class T> static inline i::Handle<T> handle(T* type);
template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
« no previous file with comments | « no previous file | src/types.cc » ('j') | src/types.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698