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

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: Fix BitsetType::Max for OtherNumber with missing representation Created 6 years 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
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')
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
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)) \
rossberg 2014/12/12 13:57:51 Hm, I'd really prefer to make any bits referring t
Jarin 2015/01/08 14:30:27 I am not entirely sure why are these types bad. Ev
rossberg 2015/01/15 15:15:12 Mainly to prevent misuse --- for portability, nobo
Jarin 2015/01/16 16:28:39 I changed the tests back (where it made sense).
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(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ 236 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \
235 kReceiver) \ 237 kReceiver) \
236 V(NonNumber, kUnique | kString | kInternal) \ 238 V(NonNumber, kUnique | kString | kInternal) \
237 V(Any, 0xfffffffeu) 239 V(Any, 0xfffffffeu)
238 240
241 // clang-format on
239 242
240 /* 243 /*
241 * The following diagrams show how integers (in the mathematical sense) are 244 * The following diagrams show how integers (in the mathematical sense) are
242 * divided among the different atomic numerical types. 245 * divided among the different atomic numerical types.
243 * 246 *
244 * If SmiValuesAre31Bits(): 247 * ON OS32 N31 U30 OU31 OU32 ON
245 *
246 * ON OS32 OSS US OU31 OU32 ON
247 * ______[_______[_______[_______[_______[_______[_______ 248 * ______[_______[_______[_______[_______[_______[_______
248 * -2^31 -2^30 0 2^30 2^31 2^32 249 * -2^31 -2^30 0 2^30 2^31 2^32
249 * 250 *
250 * Otherwise:
251 *
252 * ON OSS US OU32 ON
253 * ______[_______________[_______________[_______[_______
254 * -2^31 0 2^31 2^32
255 *
256 *
257 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. 251 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
258 *
259 * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are
260 * 32-bit wide. They should thus never be used directly, only indirectly
261 * via e.g. Number.
262 */ 252 */
263 253
264 #define PROPER_BITSET_TYPE_LIST(V) \ 254 #define PROPER_BITSET_TYPE_LIST(V) \
265 REPRESENTATION_BITSET_TYPE_LIST(V) \ 255 REPRESENTATION_BITSET_TYPE_LIST(V) \
266 SEMANTIC_BITSET_TYPE_LIST(V) 256 SEMANTIC_BITSET_TYPE_LIST(V)
267 257
268 #define BITSET_TYPE_LIST(V) \ 258 #define BITSET_TYPE_LIST(V) \
269 MASK_BITSET_TYPE_LIST(V) \ 259 MASK_BITSET_TYPE_LIST(V) \
270 REPRESENTATION_BITSET_TYPE_LIST(V) \ 260 REPRESENTATION_BITSET_TYPE_LIST(V) \
271 INTERNAL_BITSET_TYPE_LIST(V) \ 261 INTERNAL_BITSET_TYPE_LIST(V) \
(...skipping 25 matching lines...) Expand all
297 // static Handle<Struct>::type struct_create(int tag, int length, Region*); 287 // static Handle<Struct>::type struct_create(int tag, int length, Region*);
298 // static void struct_shrink(Handle<Struct>::type, int length); 288 // static void struct_shrink(Handle<Struct>::type, int length);
299 // static int struct_tag(Handle<Struct>::type); 289 // static int struct_tag(Handle<Struct>::type);
300 // static int struct_length(Handle<Struct>::type); 290 // static int struct_length(Handle<Struct>::type);
301 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); 291 // static Handle<Type>::type struct_get(Handle<Struct>::type, int);
302 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); 292 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
303 // template<class V> 293 // template<class V>
304 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); 294 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
305 // template<class V> 295 // template<class V>
306 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); 296 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
297 // static i::Isolate* get_isolate(Region* region);
rossberg 2014/12/12 13:57:51 Nit: remove the get_ prefix
Jarin 2015/01/08 14:30:27 Done.
307 // } 298 // }
308 template<class Config> 299 template<class Config>
309 class TypeImpl : public Config::Base { 300 class TypeImpl : public Config::Base {
310 public: 301 public:
311 // Auxiliary types. 302 // Auxiliary types.
312 303
313 typedef uint32_t bitset; // Internal 304 typedef uint32_t bitset; // Internal
314 class BitsetType; // Internal 305 class BitsetType; // Internal
315 class StructuralType; // Internal 306 class StructuralType; // Internal
316 class UnionType; // Internal 307 class UnionType; // Internal
(...skipping 20 matching lines...) Expand all
337 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 328 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
338 static TypeImpl* type() { \ 329 static TypeImpl* type() { \
339 return BitsetType::New(BitsetType::k##type); \ 330 return BitsetType::New(BitsetType::k##type); \
340 } \ 331 } \
341 static TypeHandle type(Region* region) { \ 332 static TypeHandle type(Region* region) { \
342 return BitsetType::New(BitsetType::k##type, region); \ 333 return BitsetType::New(BitsetType::k##type, region); \
343 } 334 }
344 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 335 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
345 #undef DEFINE_TYPE_CONSTRUCTOR 336 #undef DEFINE_TYPE_CONSTRUCTOR
346 337
338 static TypeImpl* SignedSmall() { return BitsetType::New(SignedSmallBits()); }
339 static TypeHandle SignedSmall(Region* region) {
340 return BitsetType::New(SignedSmallBits(), region);
341 }
342 static TypeImpl* UnsignedSmall() {
343 return BitsetType::New(UnsignedSmallBits());
344 }
345 static TypeHandle UnsignedSmall(Region* region) {
346 return BitsetType::New(UnsignedSmallBits(), region);
347 }
348
347 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { 349 static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
348 return ClassType::New(map, region); 350 return ClassType::New(map, region);
349 } 351 }
350 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { 352 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
351 return ConstantType::New(value, region); 353 return ConstantType::New(value, region);
352 } 354 }
353 static TypeHandle Range( 355 static TypeHandle Range(
354 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { 356 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
355 return RangeType::New(min, max, region); 357 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged |
358 BitsetType::kUntaggedNumber),
359 region);
356 } 360 }
357 static TypeHandle Context(TypeHandle outer, Region* region) { 361 static TypeHandle Context(TypeHandle outer, Region* region) {
358 return ContextType::New(outer, region); 362 return ContextType::New(outer, region);
359 } 363 }
360 static TypeHandle Array(TypeHandle element, Region* region) { 364 static TypeHandle Array(TypeHandle element, Region* region) {
361 return ArrayType::New(element, region); 365 return ArrayType::New(element, region);
362 } 366 }
363 static FunctionHandle Function( 367 static FunctionHandle Function(
364 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 368 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
365 return FunctionType::New(result, receiver, arity, region); 369 return FunctionType::New(result, receiver, arity, region);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 DCHECK(this->IsBitset()); 544 DCHECK(this->IsBitset());
541 return static_cast<BitsetType*>(this)->Bitset(); 545 return static_cast<BitsetType*>(this)->Bitset();
542 } 546 }
543 UnionType* AsUnion() { return UnionType::cast(this); } 547 UnionType* AsUnion() { return UnionType::cast(this); }
544 548
545 // Auxiliary functions. 549 // Auxiliary functions.
546 550
547 bitset BitsetGlb() { return BitsetType::Glb(this); } 551 bitset BitsetGlb() { return BitsetType::Glb(this); }
548 bitset BitsetLub() { return BitsetType::Lub(this); } 552 bitset BitsetLub() { return BitsetType::Lub(this); }
549 553
554 static bitset SignedSmallBits();
555 static bitset UnsignedSmallBits();
556
550 bool SlowIs(TypeImpl* that); 557 bool SlowIs(TypeImpl* that);
551 558
552 static bool IsInteger(double x) { 559 static bool IsInteger(double x) {
553 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. 560 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
554 } 561 }
555 static bool IsInteger(i::Object* x) { 562 static bool IsInteger(i::Object* x) {
556 return x->IsNumber() && IsInteger(x->Number()); 563 return x->IsNumber() && IsInteger(x->Number());
557 } 564 }
558 565
559 struct Limits { 566 struct Limits {
560 i::Handle<i::Object> min; 567 i::Handle<i::Object> min;
561 i::Handle<i::Object> max; 568 i::Handle<i::Object> max;
562 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : 569 bitset representation;
563 min(min), max(max) {} 570 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max,
564 explicit Limits(RangeType* range) : 571 bitset representation)
565 min(range->Min()), max(range->Max()) {} 572 : min(min), max(max), representation(representation) {}
573 explicit Limits(RangeType* range)
574 : min(range->Min()),
575 max(range->Max()),
576 representation(range->Representation()) {}
577 static Limits Empty(Region* region) {
578 i::Factory* f = Config::get_isolate(region)->factory();
579 i::Handle<i::Object> min = f->NewNumber(1);
580 i::Handle<i::Object> max = f->NewNumber(0);
581 return Limits(min, max, BitsetType::kNone);
582 }
566 }; 583 };
567 584
585 static bool IsEmpty(Limits lim);
568 static Limits Intersect(Limits lhs, Limits rhs); 586 static Limits Intersect(Limits lhs, Limits rhs);
569 static Limits Union(Limits lhs, Limits rhs); 587 static Limits Union(Limits lhs, Limits rhs);
570 static bool Overlap(RangeType* lhs, RangeType* rhs); 588 static bool Overlap(RangeType* lhs, RangeType* rhs);
571 static bool Contains(RangeType* lhs, RangeType* rhs); 589 static bool Contains(RangeType* lhs, RangeType* rhs);
590 static bool Contains(RangeType* range, ConstantType* constant);
572 static bool Contains(RangeType* range, i::Object* val); 591 static bool Contains(RangeType* range, i::Object* val);
573 592
574 static int UpdateRange( 593 static int UpdateRange(
575 RangeHandle type, UnionHandle result, int size, Region* region); 594 RangeHandle type, UnionHandle result, int size, Region* region);
576 595
596 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits,
597 Region* region);
598 static Limits NumberBitsetToLimits(bitset bits, Region* region);
rossberg 2014/12/12 13:57:51 Nit: ToLimits would seem good enough a name
Jarin 2015/01/08 14:30:27 Done.
599
577 bool SimplyEquals(TypeImpl* that); 600 bool SimplyEquals(TypeImpl* that);
578 template<class TypeHandle> 601 template<class TypeHandle>
579 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } 602 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); }
580 603
581 static int AddToUnion( 604 static int AddToUnion(
582 TypeHandle type, UnionHandle result, int size, Region* region); 605 TypeHandle type, UnionHandle result, int size, Region* region);
583 static int IntersectAux( 606 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result,
584 TypeHandle type, TypeHandle other, 607 int size, Limits* limits, Region* region);
585 UnionHandle result, int size, Region* region);
586 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); 608 static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
609 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits,
610 Region* region);
587 }; 611 };
588 612
589 613
590 // ----------------------------------------------------------------------------- 614 // -----------------------------------------------------------------------------
591 // Bitset types (internal). 615 // Bitset types (internal).
592 616
593 template<class Config> 617 template<class Config>
594 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { 618 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
595 protected: 619 protected:
596 friend class TypeImpl<Config>; 620 friend class TypeImpl<Config>;
597 621
598 enum { 622 enum {
599 #define DECLARE_TYPE(type, value) k##type = (value), 623 #define DECLARE_TYPE(type, value) k##type = (value),
600 BITSET_TYPE_LIST(DECLARE_TYPE) 624 BITSET_TYPE_LIST(DECLARE_TYPE)
601 #undef DECLARE_TYPE 625 #undef DECLARE_TYPE
602 kUnusedEOL = 0 626 kUnusedEOL = 0
603 }; 627 };
604 628
605 bitset Bitset() { return Config::as_bitset(this); } 629 bitset Bitset() { return Config::as_bitset(this); }
606 630
607 static TypeImpl* New(bitset bits) { 631 static TypeImpl* New(bitset bits) {
608 DCHECK(bits == kNone || IsInhabited(bits)); 632 DCHECK(bits == kNone || IsInhabited(bits));
609 633
610 if (FLAG_enable_slow_asserts) { 634 if (FLAG_enable_slow_asserts) {
611 // Check that the bitset does not contain any holes in number ranges. 635 // Check that the bitset does not contain any holes in number ranges.
612 bitset mask = kSemantic; 636 bitset number_bits = NumberBits(bits);
613 if (!i::SmiValuesAre31Bits()) {
614 mask &= ~(kOtherUnsigned31 | kOtherSigned32);
615 }
616 bitset number_bits = bits & kPlainNumber & mask;
617 if (number_bits != 0) { 637 if (number_bits != 0) {
618 bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask; 638 bitset lub = SEMANTIC(Lub(Min(number_bits), Max(number_bits)));
619 CHECK(lub == number_bits); 639 CHECK(lub == number_bits);
620 } 640 }
621 } 641 }
622 642
623 return Config::from_bitset(bits); 643 return Config::from_bitset(bits);
624 } 644 }
625 static TypeHandle New(bitset bits, Region* region) { 645 static TypeHandle New(bitset bits, Region* region) {
626 DCHECK(bits == kNone || IsInhabited(bits)); 646 DCHECK(bits == kNone || IsInhabited(bits));
627 return Config::from_bitset(bits, region); 647 return Config::from_bitset(bits, region);
628 } 648 }
629 // TODO(neis): Eventually allow again for types with empty semantics 649 // TODO(neis): Eventually allow again for types with empty semantics
630 // part and modify intersection and possibly subtyping accordingly. 650 // part and modify intersection and possibly subtyping accordingly.
631 651
632 static bool IsInhabited(bitset bits) { 652 static bool IsInhabited(bitset bits) {
633 return bits & kSemantic; 653 return bits & kSemantic;
634 } 654 }
635 655
656 static bitset NumberBits(bitset bits) {
rossberg 2014/12/12 13:57:51 Move to same place as (Un)signedSmallBits.
Jarin 2015/01/08 14:30:28 Done.
657 return bits & kPlainNumber & kSemantic;
658 }
659
636 static bool Is(bitset bits1, bitset bits2) { 660 static bool Is(bitset bits1, bitset bits2) {
637 return (bits1 | bits2) == bits2; 661 return (bits1 | bits2) == bits2;
638 } 662 }
639 663
640 static double Min(bitset); 664 static double Min(bitset);
641 static double Max(bitset); 665 static double Max(bitset);
642 666
643 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset 667 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset
668 static bitset Glb(double min, double max);
644 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset 669 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset
645 static bitset Lub(i::Map* map); 670 static bitset Lub(i::Map* map);
646 static bitset Lub(i::Object* value); 671 static bitset Lub(i::Object* value);
647 static bitset Lub(double value); 672 static bitset Lub(double value);
648 static bitset Lub(double min, double max); 673 static bitset Lub(double min, double max);
649 674
650 static const char* Name(bitset); 675 static const char* Name(bitset);
651 static void Print(std::ostream& os, bitset); // NOLINT 676 static void Print(std::ostream& os, bitset); // NOLINT
652 #ifdef DEBUG 677 #ifdef DEBUG
653 static void Print(bitset); 678 static void Print(bitset);
654 #endif 679 #endif
655 680
656 private: 681 private:
657 struct BitsetMin{ 682 struct BitsetMin{
658 bitset bits; 683 bitset bits;
659 double min; 684 double min;
660 }; 685 };
661 static const BitsetMin BitsetMins31[]; 686 static const BitsetMin BitsetMinsArray[];
662 static const BitsetMin BitsetMins32[]; 687 static const BitsetMin* BitsetMins() { return BitsetMinsArray; }
663 static const BitsetMin* BitsetMins() {
664 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32;
665 }
666 static size_t BitsetMinsSize() { 688 static size_t BitsetMinsSize() {
667 return i::SmiValuesAre31Bits() ? 7 : 5; 689 return 7;
668 /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ 690 /* arraysize(BitsetMinsArray); */
669 // Using arraysize here doesn't compile on Windows. 691 // Using arraysize here doesn't compile on Windows.
670 } 692 }
671 }; 693 };
672 694
673 695
674 // ----------------------------------------------------------------------------- 696 // -----------------------------------------------------------------------------
675 // Superclass for non-bitset types (internal). 697 // Superclass for non-bitset types (internal).
676 // Contains a tag and a variable number of type or value fields. 698 // Contains a tag and a variable number of type or value fields.
677 699
678 template<class Config> 700 template<class Config>
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 }; 804 };
783 805
784 806
785 // ----------------------------------------------------------------------------- 807 // -----------------------------------------------------------------------------
786 // Constant types. 808 // Constant types.
787 809
788 template<class Config> 810 template<class Config>
789 class TypeImpl<Config>::ConstantType : public StructuralType { 811 class TypeImpl<Config>::ConstantType : public StructuralType {
790 public: 812 public:
791 TypeHandle Bound() { return this->Get(0); } 813 TypeHandle Bound() { return this->Get(0); }
814 bitset Representation() { return REPRESENTATION(this->Get(0)->AsBitset()); }
rossberg 2014/12/12 13:57:51 Please don't expose bitset functionality in this i
rossberg 2014/12/12 15:30:41 s/in this interfaces/in these public interfaces/
Jarin 2015/01/08 14:30:27 Done.
792 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } 815 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
793 816
794 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { 817 static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
795 ConstantHandle type = Config::template cast<ConstantType>( 818 ConstantHandle type = Config::template cast<ConstantType>(
796 StructuralType::New(StructuralType::kConstantTag, 2, region)); 819 StructuralType::New(StructuralType::kConstantTag, 2, region));
797 type->Set(0, BitsetType::New(BitsetType::Lub(*value), region)); 820 type->Set(0, BitsetType::New(BitsetType::Lub(*value), region));
798 type->SetValue(1, value); 821 type->SetValue(1, value);
799 return type; 822 return type;
800 } 823 }
801 824
802 static ConstantType* cast(TypeImpl* type) { 825 static ConstantType* cast(TypeImpl* type) {
803 DCHECK(type->IsConstant()); 826 DCHECK(type->IsConstant());
804 return static_cast<ConstantType*>(type); 827 return static_cast<ConstantType*>(type);
805 } 828 }
806 }; 829 };
807 // TODO(neis): Also cache value if numerical. 830 // TODO(neis): Also cache value if numerical.
808 // TODO(neis): Allow restricting the representation. 831 // TODO(neis): Allow restricting the representation.
809 832
810 833
811 // ----------------------------------------------------------------------------- 834 // -----------------------------------------------------------------------------
812 // Range types. 835 // Range types.
813 836
814 template<class Config> 837 template<class Config>
815 class TypeImpl<Config>::RangeType : public StructuralType { 838 class TypeImpl<Config>::RangeType : public StructuralType {
816 public: 839 public:
817 int BitsetLub() { return this->Get(0)->AsBitset(); } 840 int BitsetLub() { return this->Get(0)->AsBitset(); }
841 bitset Representation() { return REPRESENTATION(BitsetLub()); }
rossberg 2014/12/12 13:57:51 Same here.
Jarin 2015/01/08 14:30:27 Done.
818 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } 842 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); }
819 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } 843 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); }
820 844
821 static RangeHandle New( 845 static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max,
822 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { 846 bitset representation, Region* region) {
rossberg 2014/12/12 13:57:51 For the same reason, make representation a Type he
Jarin 2015/01/08 14:30:27 Done.
823 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); 847 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number()));
824 DCHECK(min->Number() <= max->Number()); 848 DCHECK(min->Number() <= max->Number());
849 DCHECK(REPRESENTATION(representation) == representation);
850
851 // Make sure the representation does not contain non-number stuff.
rossberg 2014/12/12 13:57:51 Shouldn't this better be an assertion?
Jarin 2015/01/08 14:30:27 Removed this code. (If we want the point-wise repr
852 representation &=
853 REPRESENTATION(BitsetType::kTagged | BitsetType::kUntaggedNumber);
854
825 RangeHandle type = Config::template cast<RangeType>( 855 RangeHandle type = Config::template cast<RangeType>(
826 StructuralType::New(StructuralType::kRangeTag, 3, region)); 856 StructuralType::New(StructuralType::kRangeTag, 3, region));
827 type->Set(0, BitsetType::New( 857
828 BitsetType::Lub(min->Number(), max->Number()), region)); 858 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) |
859 representation;
860 type->Set(0, BitsetType::New(bits, region));
829 type->SetValue(1, min); 861 type->SetValue(1, min);
830 type->SetValue(2, max); 862 type->SetValue(2, max);
831 return type; 863 return type;
832 } 864 }
833 865
834 static RangeHandle New(Limits lim, Region* region) { 866 static RangeHandle New(Limits lim, Region* region) {
835 return New(lim.min, lim.max, region); 867 return New(lim.min, lim.max, lim.representation, region);
836 } 868 }
837 869
838 static RangeType* cast(TypeImpl* type) { 870 static RangeType* cast(TypeImpl* type) {
839 DCHECK(type->IsRange()); 871 DCHECK(type->IsRange());
840 return static_cast<RangeType*>(type); 872 return static_cast<RangeType*>(type);
841 } 873 }
842 }; 874 };
843 // TODO(neis): Also cache min and max values. 875 // TODO(neis): Also cache min and max values.
844 // TODO(neis): Allow restricting the representation. 876 // TODO(neis): Allow restricting the representation.
845 877
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 static inline Struct* struct_create(int tag, int length, Zone* zone); 1006 static inline Struct* struct_create(int tag, int length, Zone* zone);
975 static inline void struct_shrink(Struct* structure, int length); 1007 static inline void struct_shrink(Struct* structure, int length);
976 static inline int struct_tag(Struct* structure); 1008 static inline int struct_tag(Struct* structure);
977 static inline int struct_length(Struct* structure); 1009 static inline int struct_length(Struct* structure);
978 static inline Type* struct_get(Struct* structure, int i); 1010 static inline Type* struct_get(Struct* structure, int i);
979 static inline void struct_set(Struct* structure, int i, Type* type); 1011 static inline void struct_set(Struct* structure, int i, Type* type);
980 template<class V> 1012 template<class V>
981 static inline i::Handle<V> struct_get_value(Struct* structure, int i); 1013 static inline i::Handle<V> struct_get_value(Struct* structure, int i);
982 template<class V> static inline void struct_set_value( 1014 template<class V> static inline void struct_set_value(
983 Struct* structure, int i, i::Handle<V> x); 1015 Struct* structure, int i, i::Handle<V> x);
1016 static inline i::Isolate* get_isolate(Zone* zone);
984 }; 1017 };
985 1018
986 typedef TypeImpl<ZoneTypeConfig> Type; 1019 typedef TypeImpl<ZoneTypeConfig> Type;
987 1020
988 1021
989 // ----------------------------------------------------------------------------- 1022 // -----------------------------------------------------------------------------
990 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for 1023 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for
991 // constants, or fixed arrays for unions. 1024 // constants, or fixed arrays for unions.
992 1025
993 struct HeapTypeConfig { 1026 struct HeapTypeConfig {
(...skipping 28 matching lines...) Expand all
1022 static inline int struct_length(i::Handle<Struct> structure); 1055 static inline int struct_length(i::Handle<Struct> structure);
1023 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); 1056 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i);
1024 static inline void struct_set( 1057 static inline void struct_set(
1025 i::Handle<Struct> structure, int i, i::Handle<Type> type); 1058 i::Handle<Struct> structure, int i, i::Handle<Type> type);
1026 template<class V> 1059 template<class V>
1027 static inline i::Handle<V> struct_get_value( 1060 static inline i::Handle<V> struct_get_value(
1028 i::Handle<Struct> structure, int i); 1061 i::Handle<Struct> structure, int i);
1029 template<class V> 1062 template<class V>
1030 static inline void struct_set_value( 1063 static inline void struct_set_value(
1031 i::Handle<Struct> structure, int i, i::Handle<V> x); 1064 i::Handle<Struct> structure, int i, i::Handle<V> x);
1065 static inline i::Isolate* get_isolate(Isolate* isolate);
1032 }; 1066 };
1033 1067
1034 typedef TypeImpl<HeapTypeConfig> HeapType; 1068 typedef TypeImpl<HeapTypeConfig> HeapType;
1035 1069
1036 1070
1037 // ----------------------------------------------------------------------------- 1071 // -----------------------------------------------------------------------------
1038 // Type bounds. A simple struct to represent a pair of lower/upper types. 1072 // Type bounds. A simple struct to represent a pair of lower/upper types.
1039 1073
1040 template<class Config> 1074 template<class Config>
1041 struct BoundsImpl { 1075 struct BoundsImpl {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 bool Narrows(BoundsImpl that) { 1126 bool Narrows(BoundsImpl that) {
1093 return that.lower->Is(this->lower) && this->upper->Is(that.upper); 1127 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
1094 } 1128 }
1095 }; 1129 };
1096 1130
1097 typedef BoundsImpl<ZoneTypeConfig> Bounds; 1131 typedef BoundsImpl<ZoneTypeConfig> Bounds;
1098 1132
1099 } } // namespace v8::internal 1133 } } // namespace v8::internal
1100 1134
1101 #endif // V8_TYPES_H_ 1135 #endif // V8_TYPES_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698