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

Side by Side Diff: src/types.h

Issue 795713003: Steps towards unification of number bitset and range types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Restrict representation on ranges to numbers during normalization Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « src/compiler/typer.cc ('k') | src/types.cc » ('j') | src/types.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_TYPES_H_ 5 #ifndef V8_TYPES_H_
6 #define V8_TYPES_H_ 6 #define V8_TYPES_H_
7 7
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/handles.h" 10 #include "src/handles.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 // Subtyping relates the two dimensions, for example: 81 // Subtyping relates the two dimensions, for example:
82 // 82 //
83 // Number <= Tagged \/ UntaggedNumber 83 // Number <= Tagged \/ UntaggedNumber
84 // Object <= TaggedPtr \/ UntaggedPtr 84 // Object <= TaggedPtr \/ UntaggedPtr
85 // 85 //
86 // That holds because the semantic type constructors defined by the API create 86 // That holds because the semantic type constructors defined by the API create
87 // types that allow for all possible representations, and dually, the ones for 87 // types that allow for all possible representations, and dually, the ones for
88 // representation types initially include all semantic ranges. Representations 88 // representation types initially include all semantic ranges. Representations
89 // can then e.g. be narrowed for a given semantic type using intersection: 89 // can then e.g. be narrowed for a given semantic type using intersection:
90 // 90 //
91 // SignedSmall /\ TaggedInt (a 'smi') 91 // Signed31 /\ TaggedInt (a 'smi')
rossberg 2015/01/15 15:15:12 This doesn't make sense on 64 bit. The original co
Jarin 2015/01/16 16:28:39 Done.
92 // Number /\ TaggedPtr (a heap number) 92 // Number /\ TaggedPtr (a heap number)
93 // 93 //
94 // 94 //
95 // RANGE TYPES 95 // RANGE TYPES
96 // 96 //
97 // A range type represents a continuous integer interval by its minimum and 97 // A range type represents a continuous integer interval by its minimum and
98 // maximum value. Either value might be an infinity. 98 // maximum value. Either value might be an infinity.
99 // 99 //
100 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an 100 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an
101 // integer between x and y. 101 // integer between x and y.
102 // 102 //
103 // 103 //
104 // PREDICATES 104 // PREDICATES
105 // 105 //
106 // There are two main functions for testing types: 106 // There are two main functions for testing types:
107 // 107 //
108 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) 108 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
109 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) 109 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
110 // 110 //
111 // Typically, the former is to be used to select representations (e.g., via 111 // Typically, the former is to be used to select representations (e.g., via
112 // T->Is(SignedSmall())), and the latter to check whether a specific case needs 112 // T->Is(Signed31())), and the latter to check whether a specific case needs
rossberg 2015/01/15 15:15:12 Similarly here. Please don't encourage use of Sign
Jarin 2015/01/16 16:28:39 Done.
113 // handling (e.g., via T->Maybe(Number())). 113 // handling (e.g., via T->Maybe(Number())).
114 // 114 //
115 // There is no functionality to discover whether a type is a leaf in the 115 // There is no functionality to discover whether a type is a leaf in the
116 // lattice. That is intentional. It should always be possible to refine the 116 // lattice. That is intentional. It should always be possible to refine the
117 // lattice (e.g., splitting up number types further) without invalidating any 117 // lattice (e.g., splitting up number types further) without invalidating any
118 // existing assumptions or tests. 118 // existing assumptions or tests.
119 // Consequently, do not normally use Equals for type tests, always use Is! 119 // Consequently, do not normally use Equals for type tests, always use Is!
120 // 120 //
121 // The NowIs operator implements state-sensitive subtying, as described above. 121 // The NowIs operator implements state-sensitive subtying, as described above.
122 // Any compilation decision based on such temporary properties requires runtime 122 // Any compilation decision based on such temporary properties requires runtime
(...skipping 23 matching lines...) Expand all
146 // - class Type (zone-allocated, for compiler and concurrent compilation) 146 // - class Type (zone-allocated, for compiler and concurrent compilation)
147 // - class HeapType (heap-allocated, for persistent types) 147 // - class HeapType (heap-allocated, for persistent types)
148 // 148 //
149 // Both provide the same API, and the Convert method can be used to interconvert 149 // Both provide the same API, and the Convert method can be used to interconvert
150 // them. For zone types, no query method touches the heap, only constructors do. 150 // them. For zone types, no query method touches the heap, only constructors do.
151 151
152 152
153 // ----------------------------------------------------------------------------- 153 // -----------------------------------------------------------------------------
154 // Values for bitset types 154 // Values for bitset types
155 155
156 // clang-format off
157
156 #define MASK_BITSET_TYPE_LIST(V) \ 158 #define MASK_BITSET_TYPE_LIST(V) \
157 V(Representation, 0xfff00000u) \ 159 V(Representation, 0xfff00000u) \
158 V(Semantic, 0x000ffffeu) 160 V(Semantic, 0x000ffffeu)
159 161
160 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) 162 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
161 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) 163 #define SEMANTIC(k) ((k) & BitsetType::kSemantic)
162 164
163 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ 165 #define REPRESENTATION_BITSET_TYPE_LIST(V) \
164 V(None, 0) \ 166 V(None, 0) \
165 V(UntaggedBit, 1u << 20 | kSemantic) \ 167 V(UntaggedBit, 1u << 20 | kSemantic) \
(...skipping 22 matching lines...) Expand all
188 V(Untagged, kUntaggedNumber | kUntaggedPointer) \ 190 V(Untagged, kUntaggedNumber | kUntaggedPointer) \
189 V(Tagged, kTaggedSigned | kTaggedPointer) 191 V(Tagged, kTaggedSigned | kTaggedPointer)
190 192
191 #define INTERNAL_BITSET_TYPE_LIST(V) \ 193 #define INTERNAL_BITSET_TYPE_LIST(V) \
192 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 194 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
193 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 195 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
194 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 196 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
195 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) 197 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
196 198
197 #define SEMANTIC_BITSET_TYPE_LIST(V) \ 199 #define SEMANTIC_BITSET_TYPE_LIST(V) \
198 V(NegativeSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 200 V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
199 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ 201 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \
200 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ 202 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \
201 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ 203 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \
202 V(UnsignedSmall, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 204 V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
203 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 205 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
204 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ 206 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
205 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ 207 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \
206 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ 208 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
207 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ 209 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
208 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ 210 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \
209 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ 211 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \
210 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ 212 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \
211 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ 213 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
212 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ 214 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
213 \ 215 \
214 V(SignedSmall, kUnsignedSmall | kNegativeSignedSmall) \ 216 V(Signed31, kUnsigned30 | kNegative31) \
215 V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \ 217 V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
216 V(NegativeSigned32, kNegativeSignedSmall | kOtherSigned32) \ 218 V(Negative32, kNegative31 | kOtherSigned32) \
217 V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \ 219 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \
218 V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \ 220 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | kOtherUnsigned32) \
219 V(Integral32, kSigned32 | kUnsigned32) \ 221 V(Integral32, kSigned32 | kUnsigned32) \
220 V(PlainNumber, kIntegral32 | kOtherNumber) \ 222 V(PlainNumber, kIntegral32 | kOtherNumber) \
221 V(OrderedNumber, kPlainNumber | kMinusZero) \ 223 V(OrderedNumber, kPlainNumber | kMinusZero) \
222 V(Number, kOrderedNumber | kNaN) \ 224 V(Number, kOrderedNumber | kNaN) \
223 V(String, kInternalizedString | kOtherString) \ 225 V(String, kInternalizedString | kOtherString) \
224 V(UniqueName, kSymbol | kInternalizedString) \ 226 V(UniqueName, kSymbol | kInternalizedString) \
225 V(Name, kSymbol | kString) \ 227 V(Name, kSymbol | kString) \
226 V(NumberOrString, kNumber | kString) \ 228 V(NumberOrString, kNumber | kString) \
227 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \ 229 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \
228 V(Primitive, kSymbol | kPlainPrimitive) \ 230 V(Primitive, kSymbol | kPlainPrimitive) \
229 V(DetectableObject, kArray | kOtherObject) \ 231 V(DetectableObject, kArray | kOtherObject) \
230 V(DetectableReceiver, kDetectableObject | kProxy) \ 232 V(DetectableReceiver, kDetectableObject | kProxy) \
231 V(Detectable, kDetectableReceiver | kNumber | kName) \ 233 V(Detectable, kDetectableReceiver | kNumber | kName) \
232 V(Object, kDetectableObject | kUndetectable) \ 234 V(Object, kDetectableObject | kUndetectable) \
233 V(Receiver, kObject | kProxy) \ 235 V(Receiver, kObject | kProxy) \
234 V(StringOrReceiver, kString | kReceiver) \ 236 V(StringOrReceiver, kString | kReceiver) \
235 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ 237 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \
236 kReceiver) \ 238 kReceiver) \
237 V(NonNumber, kUnique | kString | kInternal) \ 239 V(NonNumber, kUnique | kString | kInternal) \
238 V(Any, 0xfffffffeu) 240 V(Any, 0xfffffffeu)
239 241
242 // clang-format on
240 243
241 /* 244 /*
242 * The following diagrams show how integers (in the mathematical sense) are 245 * The following diagrams show how integers (in the mathematical sense) are
243 * divided among the different atomic numerical types. 246 * divided among the different atomic numerical types.
244 * 247 *
245 * If SmiValuesAre31Bits(): 248 * ON OS32 N31 U30 OU31 OU32 ON
246 *
247 * ON OS32 OSS US OU31 OU32 ON
248 * ______[_______[_______[_______[_______[_______[_______ 249 * ______[_______[_______[_______[_______[_______[_______
249 * -2^31 -2^30 0 2^30 2^31 2^32 250 * -2^31 -2^30 0 2^30 2^31 2^32
250 * 251 *
251 * Otherwise:
252 *
253 * ON OSS US OU32 ON
254 * ______[_______________[_______________[_______[_______
255 * -2^31 0 2^31 2^32
256 *
257 *
258 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. 252 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
259 *
260 * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are
261 * 32-bit wide. They should thus never be used directly, only indirectly
262 * via e.g. Number.
263 */ 253 */
264 254
265 #define PROPER_BITSET_TYPE_LIST(V) \ 255 #define PROPER_BITSET_TYPE_LIST(V) \
266 REPRESENTATION_BITSET_TYPE_LIST(V) \ 256 REPRESENTATION_BITSET_TYPE_LIST(V) \
267 SEMANTIC_BITSET_TYPE_LIST(V) 257 SEMANTIC_BITSET_TYPE_LIST(V)
268 258
269 #define BITSET_TYPE_LIST(V) \ 259 #define BITSET_TYPE_LIST(V) \
270 MASK_BITSET_TYPE_LIST(V) \ 260 MASK_BITSET_TYPE_LIST(V) \
271 REPRESENTATION_BITSET_TYPE_LIST(V) \ 261 REPRESENTATION_BITSET_TYPE_LIST(V) \
272 INTERNAL_BITSET_TYPE_LIST(V) \ 262 INTERNAL_BITSET_TYPE_LIST(V) \
(...skipping 25 matching lines...) Expand all
298 // static Handle<Struct>::type struct_create(int tag, int length, Region*); 288 // static Handle<Struct>::type struct_create(int tag, int length, Region*);
299 // static void struct_shrink(Handle<Struct>::type, int length); 289 // static void struct_shrink(Handle<Struct>::type, int length);
300 // static int struct_tag(Handle<Struct>::type); 290 // static int struct_tag(Handle<Struct>::type);
301 // static int struct_length(Handle<Struct>::type); 291 // static int struct_length(Handle<Struct>::type);
302 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); 292 // static Handle<Type>::type struct_get(Handle<Struct>::type, int);
303 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); 293 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
304 // template<class V> 294 // template<class V>
305 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); 295 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
306 // template<class V> 296 // template<class V>
307 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); 297 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
298 // static i::Isolate* isolate(Region* region);
308 // } 299 // }
309 template<class Config> 300 template<class Config>
310 class TypeImpl : public Config::Base { 301 class TypeImpl : public Config::Base {
311 public: 302 public:
312 // Auxiliary types. 303 // Auxiliary types.
313 304
314 typedef uint32_t bitset; // Internal 305 typedef uint32_t bitset; // Internal
315 class BitsetType; // Internal 306 class BitsetType; // Internal
316 class StructuralType; // Internal 307 class StructuralType; // Internal
317 class UnionType; // Internal 308 class UnionType; // Internal
(...skipping 20 matching lines...) Expand all
338 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 329 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
339 static TypeImpl* type() { \ 330 static TypeImpl* type() { \
340 return BitsetType::New(BitsetType::k##type); \ 331 return BitsetType::New(BitsetType::k##type); \
341 } \ 332 } \
342 static TypeHandle type(Region* region) { \ 333 static TypeHandle type(Region* region) { \
343 return BitsetType::New(BitsetType::k##type, region); \ 334 return BitsetType::New(BitsetType::k##type, region); \
344 } 335 }
345 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 336 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
346 #undef DEFINE_TYPE_CONSTRUCTOR 337 #undef DEFINE_TYPE_CONSTRUCTOR
347 338
339 static TypeImpl* SignedSmall() { return BitsetType::New(SignedSmallBits()); }
340 static TypeHandle SignedSmall(Region* region) {
341 return BitsetType::New(SignedSmallBits(), region);
342 }
343 static TypeImpl* UnsignedSmall() {
344 return BitsetType::New(UnsignedSmallBits());
345 }
346 static TypeHandle UnsignedSmall(Region* region) {
347 return BitsetType::New(UnsignedSmallBits(), region);
348 }
349
348 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { 350 static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
349 return ClassType::New(map, region); 351 return ClassType::New(map, region);
350 } 352 }
351 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { 353 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
352 return ConstantType::New(value, region); 354 return ConstantType::New(value, region);
353 } 355 }
354 static TypeHandle Range( 356 static TypeHandle Range(
355 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { 357 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
356 return RangeType::New(min, max, region); 358 return RangeType::New(
359 min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged |
360 BitsetType::kUntaggedNumber),
361 region),
362 region);
357 } 363 }
358 static TypeHandle Context(TypeHandle outer, Region* region) { 364 static TypeHandle Context(TypeHandle outer, Region* region) {
359 return ContextType::New(outer, region); 365 return ContextType::New(outer, region);
360 } 366 }
361 static TypeHandle Array(TypeHandle element, Region* region) { 367 static TypeHandle Array(TypeHandle element, Region* region) {
362 return ArrayType::New(element, region); 368 return ArrayType::New(element, region);
363 } 369 }
364 static FunctionHandle Function( 370 static FunctionHandle Function(
365 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 371 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
366 return FunctionType::New(result, receiver, arity, region); 372 return FunctionType::New(result, receiver, arity, region);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 DCHECK(this->IsBitset()); 547 DCHECK(this->IsBitset());
542 return static_cast<BitsetType*>(this)->Bitset(); 548 return static_cast<BitsetType*>(this)->Bitset();
543 } 549 }
544 UnionType* AsUnion() { return UnionType::cast(this); } 550 UnionType* AsUnion() { return UnionType::cast(this); }
545 551
546 // Auxiliary functions. 552 // Auxiliary functions.
547 553
548 bitset BitsetGlb() { return BitsetType::Glb(this); } 554 bitset BitsetGlb() { return BitsetType::Glb(this); }
549 bitset BitsetLub() { return BitsetType::Lub(this); } 555 bitset BitsetLub() { return BitsetType::Lub(this); }
550 556
557 static bitset SignedSmallBits();
rossberg 2015/01/15 15:15:12 Nit: I think these belong to the Bitset class as B
Jarin 2015/01/16 16:28:39 Done.
558 static bitset UnsignedSmallBits();
559 static bitset NumberBits(bitset bits);
560
551 bool SlowIs(TypeImpl* that); 561 bool SlowIs(TypeImpl* that);
552 562
553 static bool IsInteger(double x) { 563 static bool IsInteger(double x) {
554 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. 564 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
555 } 565 }
556 static bool IsInteger(i::Object* x) { 566 static bool IsInteger(i::Object* x) {
557 return x->IsNumber() && IsInteger(x->Number()); 567 return x->IsNumber() && IsInteger(x->Number());
558 } 568 }
559 569
560 struct Limits { 570 struct Limits {
561 i::Handle<i::Object> min; 571 i::Handle<i::Object> min;
562 i::Handle<i::Object> max; 572 i::Handle<i::Object> max;
563 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : 573 bitset representation;
564 min(min), max(max) {} 574 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max,
565 explicit Limits(RangeType* range) : 575 bitset representation)
566 min(range->Min()), max(range->Max()) {} 576 : min(min), max(max), representation(representation) {}
577 explicit Limits(RangeType* range)
578 : min(range->Min()),
579 max(range->Max()),
580 representation(REPRESENTATION(range->Bound()->AsBitset())) {}
581 static Limits Empty(Region* region) {
582 i::Factory* f = Config::isolate(region)->factory();
583 i::Handle<i::Object> min = f->NewNumber(1);
584 i::Handle<i::Object> max = f->NewNumber(0);
585 return Limits(min, max, BitsetType::kNone);
586 }
567 }; 587 };
568 588
589 static bool IsEmpty(Limits lim);
569 static Limits Intersect(Limits lhs, Limits rhs); 590 static Limits Intersect(Limits lhs, Limits rhs);
570 static Limits Union(Limits lhs, Limits rhs); 591 static Limits Union(Limits lhs, Limits rhs);
571 static bool Overlap(RangeType* lhs, RangeType* rhs); 592 static bool Overlap(RangeType* lhs, RangeType* rhs);
572 static bool Contains(RangeType* lhs, RangeType* rhs); 593 static bool Contains(RangeType* lhs, RangeType* rhs);
594 static bool Contains(RangeType* range, ConstantType* constant);
573 static bool Contains(RangeType* range, i::Object* val); 595 static bool Contains(RangeType* range, i::Object* val);
574 596
575 static int UpdateRange( 597 static int UpdateRange(
576 RangeHandle type, UnionHandle result, int size, Region* region); 598 RangeHandle type, UnionHandle result, int size, Region* region);
577 599
600 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits,
601 Region* region);
602 static Limits ToLimits(bitset bits, Region* region);
603
578 bool SimplyEquals(TypeImpl* that); 604 bool SimplyEquals(TypeImpl* that);
579 template<class TypeHandle> 605 template<class TypeHandle>
580 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } 606 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); }
581 607
582 static int AddToUnion( 608 static int AddToUnion(
583 TypeHandle type, UnionHandle result, int size, Region* region); 609 TypeHandle type, UnionHandle result, int size, Region* region);
584 static int IntersectAux( 610 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result,
585 TypeHandle type, TypeHandle other, 611 int size, Limits* limits, Region* region);
586 UnionHandle result, int size, Region* region);
587 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); 612 static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
613 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits,
614 Region* region);
588 }; 615 };
589 616
590 617
591 // ----------------------------------------------------------------------------- 618 // -----------------------------------------------------------------------------
592 // Bitset types (internal). 619 // Bitset types (internal).
593 620
594 template<class Config> 621 template<class Config>
595 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { 622 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
596 protected: 623 protected:
597 friend class TypeImpl<Config>; 624 friend class TypeImpl<Config>;
598 625
599 enum { 626 enum {
600 #define DECLARE_TYPE(type, value) k##type = (value), 627 #define DECLARE_TYPE(type, value) k##type = (value),
601 BITSET_TYPE_LIST(DECLARE_TYPE) 628 BITSET_TYPE_LIST(DECLARE_TYPE)
602 #undef DECLARE_TYPE 629 #undef DECLARE_TYPE
603 kUnusedEOL = 0 630 kUnusedEOL = 0
604 }; 631 };
605 632
606 bitset Bitset() { return Config::as_bitset(this); } 633 bitset Bitset() { return Config::as_bitset(this); }
607 634
608 static TypeImpl* New(bitset bits) { 635 static TypeImpl* New(bitset bits) {
609 DCHECK(bits == kNone || IsInhabited(bits)); 636 if (FLAG_enable_slow_asserts) CheckNumberBits(bits);
610
611 if (FLAG_enable_slow_asserts) {
612 // Check that the bitset does not contain any holes in number ranges.
613 bitset mask = kSemantic;
614 if (!i::SmiValuesAre31Bits()) {
615 mask &= ~(kOtherUnsigned31 | kOtherSigned32);
616 }
617 bitset number_bits = bits & kPlainNumber & mask;
618 if (number_bits != 0) {
619 bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask;
620 CHECK(lub == number_bits);
621 }
622 }
623
624 return Config::from_bitset(bits); 637 return Config::from_bitset(bits);
625 } 638 }
626 static TypeHandle New(bitset bits, Region* region) { 639 static TypeHandle New(bitset bits, Region* region) {
627 DCHECK(bits == kNone || IsInhabited(bits)); 640 if (FLAG_enable_slow_asserts) CheckNumberBits(bits);
628 return Config::from_bitset(bits, region); 641 return Config::from_bitset(bits, region);
629 } 642 }
630 // TODO(neis): Eventually allow again for types with empty semantics 643 // TODO(neis): Eventually allow again for types with empty semantics
631 // part and modify intersection and possibly subtyping accordingly. 644 // part and modify intersection and possibly subtyping accordingly.
632 645
633 static bool IsInhabited(bitset bits) { 646 static bool IsInhabited(bitset bits) {
634 return bits & kSemantic; 647 return bits & kSemantic;
635 } 648 }
636 649
637 static bool Is(bitset bits1, bitset bits2) { 650 static bool Is(bitset bits1, bitset bits2) {
638 return (bits1 | bits2) == bits2; 651 return (bits1 | bits2) == bits2;
639 } 652 }
640 653
641 static double Min(bitset); 654 static double Min(bitset);
642 static double Max(bitset); 655 static double Max(bitset);
643 656
644 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset 657 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset
658 static bitset Glb(double min, double max);
645 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset 659 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset
646 static bitset Lub(i::Map* map); 660 static bitset Lub(i::Map* map);
647 static bitset Lub(i::Object* value); 661 static bitset Lub(i::Object* value);
648 static bitset Lub(double value); 662 static bitset Lub(double value);
649 static bitset Lub(double min, double max); 663 static bitset Lub(double min, double max);
650 664
651 static const char* Name(bitset); 665 static const char* Name(bitset);
652 static void Print(std::ostream& os, bitset); // NOLINT 666 static void Print(std::ostream& os, bitset); // NOLINT
653 #ifdef DEBUG 667 #ifdef DEBUG
654 static void Print(bitset); 668 static void Print(bitset);
655 #endif 669 #endif
656 670
657 private: 671 private:
658 struct BitsetMin{ 672 struct BitsetBoundary {
659 bitset bits; 673 bitset bits;
660 double min; 674 double min;
661 }; 675 };
662 static const BitsetMin BitsetMins31[]; 676 static const BitsetBoundary BitsetBoundariesArray[];
663 static const BitsetMin BitsetMins32[]; 677 static const BitsetBoundary* BitsetBoundaries() {
664 static const BitsetMin* BitsetMins() { 678 return BitsetBoundariesArray;
665 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32;
666 } 679 }
667 static size_t BitsetMinsSize() { 680 static size_t BitsetBoundariesSize() {
668 return i::SmiValuesAre31Bits() ? 7 : 5; 681 return 7;
rossberg 2015/01/15 15:15:12 Nit: maybe declare this 'inline' but move it to th
Jarin 2015/01/16 16:28:39 Done.
669 /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ 682 /* arraysize(BitsetBoundariesArray); */
670 // Using arraysize here doesn't compile on Windows. 683 // Using arraysize here doesn't compile on Windows.
671 } 684 }
685
686 static void CheckNumberBits(bitset bits);
672 }; 687 };
673 688
674 689
675 // ----------------------------------------------------------------------------- 690 // -----------------------------------------------------------------------------
676 // Superclass for non-bitset types (internal). 691 // Superclass for non-bitset types (internal).
677 // Contains a tag and a variable number of type or value fields. 692 // Contains a tag and a variable number of type or value fields.
678 693
679 template<class Config> 694 template<class Config>
680 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { 695 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
681 protected: 696 protected:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 // TODO(neis): Also cache value if numerical. 823 // TODO(neis): Also cache value if numerical.
809 // TODO(neis): Allow restricting the representation. 824 // TODO(neis): Allow restricting the representation.
810 825
811 826
812 // ----------------------------------------------------------------------------- 827 // -----------------------------------------------------------------------------
813 // Range types. 828 // Range types.
814 829
815 template<class Config> 830 template<class Config>
816 class TypeImpl<Config>::RangeType : public StructuralType { 831 class TypeImpl<Config>::RangeType : public StructuralType {
817 public: 832 public:
818 int BitsetLub() { return this->Get(0)->AsBitset(); } 833 TypeHandle Bound() { return this->Get(0); }
819 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } 834 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); }
820 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } 835 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); }
821 836
822 static RangeHandle New( 837 static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max,
823 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { 838 TypeHandle representation, Region* region) {
824 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); 839 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number()));
825 DCHECK(min->Number() <= max->Number()); 840 DCHECK(min->Number() <= max->Number());
841 bitset representation_bits = representation->AsBitset();
842 DCHECK(REPRESENTATION(representation_bits) == representation_bits);
843
826 RangeHandle type = Config::template cast<RangeType>( 844 RangeHandle type = Config::template cast<RangeType>(
827 StructuralType::New(StructuralType::kRangeTag, 3, region)); 845 StructuralType::New(StructuralType::kRangeTag, 3, region));
828 type->Set(0, BitsetType::New( 846
829 BitsetType::Lub(min->Number(), max->Number()), region)); 847 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) |
848 representation_bits;
849 type->Set(0, BitsetType::New(bits, region));
830 type->SetValue(1, min); 850 type->SetValue(1, min);
831 type->SetValue(2, max); 851 type->SetValue(2, max);
832 return type; 852 return type;
833 } 853 }
834 854
835 static RangeHandle New(Limits lim, Region* region) { 855 static RangeHandle New(Limits lim, Region* region) {
836 return New(lim.min, lim.max, region); 856 return New(lim.min, lim.max, BitsetType::New(lim.representation, region),
857 region);
837 } 858 }
838 859
839 static RangeType* cast(TypeImpl* type) { 860 static RangeType* cast(TypeImpl* type) {
840 DCHECK(type->IsRange()); 861 DCHECK(type->IsRange());
841 return static_cast<RangeType*>(type); 862 return static_cast<RangeType*>(type);
842 } 863 }
843 }; 864 };
844 // TODO(neis): Also cache min and max values. 865 // TODO(neis): Also cache min and max values.
845 // TODO(neis): Allow restricting the representation. 866 // TODO(neis): Allow restricting the representation.
846 867
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 static inline Struct* struct_create(int tag, int length, Zone* zone); 996 static inline Struct* struct_create(int tag, int length, Zone* zone);
976 static inline void struct_shrink(Struct* structure, int length); 997 static inline void struct_shrink(Struct* structure, int length);
977 static inline int struct_tag(Struct* structure); 998 static inline int struct_tag(Struct* structure);
978 static inline int struct_length(Struct* structure); 999 static inline int struct_length(Struct* structure);
979 static inline Type* struct_get(Struct* structure, int i); 1000 static inline Type* struct_get(Struct* structure, int i);
980 static inline void struct_set(Struct* structure, int i, Type* type); 1001 static inline void struct_set(Struct* structure, int i, Type* type);
981 template<class V> 1002 template<class V>
982 static inline i::Handle<V> struct_get_value(Struct* structure, int i); 1003 static inline i::Handle<V> struct_get_value(Struct* structure, int i);
983 template<class V> static inline void struct_set_value( 1004 template<class V> static inline void struct_set_value(
984 Struct* structure, int i, i::Handle<V> x); 1005 Struct* structure, int i, i::Handle<V> x);
1006 static inline i::Isolate* isolate(Zone* zone);
985 }; 1007 };
986 1008
987 typedef TypeImpl<ZoneTypeConfig> Type; 1009 typedef TypeImpl<ZoneTypeConfig> Type;
988 1010
989 1011
990 // ----------------------------------------------------------------------------- 1012 // -----------------------------------------------------------------------------
991 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for 1013 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for
992 // constants, or fixed arrays for unions. 1014 // constants, or fixed arrays for unions.
993 1015
994 struct HeapTypeConfig { 1016 struct HeapTypeConfig {
(...skipping 28 matching lines...) Expand all
1023 static inline int struct_length(i::Handle<Struct> structure); 1045 static inline int struct_length(i::Handle<Struct> structure);
1024 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); 1046 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i);
1025 static inline void struct_set( 1047 static inline void struct_set(
1026 i::Handle<Struct> structure, int i, i::Handle<Type> type); 1048 i::Handle<Struct> structure, int i, i::Handle<Type> type);
1027 template<class V> 1049 template<class V>
1028 static inline i::Handle<V> struct_get_value( 1050 static inline i::Handle<V> struct_get_value(
1029 i::Handle<Struct> structure, int i); 1051 i::Handle<Struct> structure, int i);
1030 template<class V> 1052 template<class V>
1031 static inline void struct_set_value( 1053 static inline void struct_set_value(
1032 i::Handle<Struct> structure, int i, i::Handle<V> x); 1054 i::Handle<Struct> structure, int i, i::Handle<V> x);
1055 static inline i::Isolate* isolate(Isolate* isolate);
1033 }; 1056 };
1034 1057
1035 typedef TypeImpl<HeapTypeConfig> HeapType; 1058 typedef TypeImpl<HeapTypeConfig> HeapType;
1036 1059
1037 1060
1038 // ----------------------------------------------------------------------------- 1061 // -----------------------------------------------------------------------------
1039 // Type bounds. A simple struct to represent a pair of lower/upper types. 1062 // Type bounds. A simple struct to represent a pair of lower/upper types.
1040 1063
1041 template<class Config> 1064 template<class Config>
1042 struct BoundsImpl { 1065 struct BoundsImpl {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 bool Narrows(BoundsImpl that) { 1116 bool Narrows(BoundsImpl that) {
1094 return that.lower->Is(this->lower) && this->upper->Is(that.upper); 1117 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
1095 } 1118 }
1096 }; 1119 };
1097 1120
1098 typedef BoundsImpl<ZoneTypeConfig> Bounds; 1121 typedef BoundsImpl<ZoneTypeConfig> Bounds;
1099 1122
1100 } } // namespace v8::internal 1123 } } // namespace v8::internal
1101 1124
1102 #endif // V8_TYPES_H_ 1125 #endif // V8_TYPES_H_
OLDNEW
« no previous file with comments | « src/compiler/typer.cc ('k') | src/types.cc » ('j') | src/types.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698