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

Side by Side 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: This addresses the issue I pointed out on Friday. In order to keep the changes as simple as possib… 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | 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/factory.h" 9 #include "src/factory.h"
9 #include "src/handles.h" 10 #include "src/handles.h"
10 #include "src/ostreams.h" 11 #include "src/ostreams.h"
11 12
12 namespace v8 { 13 namespace v8 {
13 namespace internal { 14 namespace internal {
14 15
15 // SUMMARY 16 // SUMMARY
16 // 17 //
17 // A simple type system for compiler-internal use. It is based entirely on 18 // A simple type system for compiler-internal use. It is based entirely on
18 // union types, and all subtyping hence amounts to set inclusion. Besides the 19 // union types, and all subtyping hence amounts to set inclusion. Besides the
19 // obvious primitive types and some predefined unions, the type language also 20 // obvious primitive types and some predefined unions, the type language also
20 // can express class types (a.k.a. specific maps) and singleton types (i.e., 21 // can express class types (a.k.a. specific maps) and singleton types (i.e.,
21 // concrete constants). 22 // concrete constants).
22 // 23 //
23 // Types consist of two dimensions: semantic (value range) and representation. 24 // Types consist of two dimensions: semantic (value range) and representation.
24 // Both are related through subtyping. 25 // Both are related through subtyping.
25 // 26 //
27 //
26 // SEMANTIC DIMENSION 28 // SEMANTIC DIMENSION
27 // 29 //
28 // The following equations and inequations hold for the semantic axis: 30 // The following equations and inequations hold for the semantic axis:
29 // 31 //
30 // None <= T 32 // None <= T
31 // T <= Any 33 // T <= Any
32 // 34 //
33 // Number = Signed32 \/ Unsigned32 \/ Double 35 // Number = Signed32 \/ Unsigned32 \/ Double
34 // Smi <= Signed32 36 // Smi <= Signed32
35 // Name = String \/ Symbol 37 // Name = String \/ Symbol
(...skipping 18 matching lines...) Expand all
54 // There is no subtyping relation between Array, Function, or Context types 56 // There is no subtyping relation between Array, Function, or Context types
55 // and respective Constant types, since these types cannot be reconstructed 57 // and respective Constant types, since these types cannot be reconstructed
56 // for arbitrary heap values. 58 // for arbitrary heap values.
57 // Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can 59 // Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
58 // change! (Its instance type cannot, however.) 60 // change! (Its instance type cannot, however.)
59 // TODO(rossberg): the latter is not currently true for proxies, because of fix, 61 // TODO(rossberg): the latter is not currently true for proxies, because of fix,
60 // but will hold once we implement direct proxies. 62 // but will hold once we implement direct proxies.
61 // However, we also define a 'temporal' variant of the subtyping relation that 63 // However, we also define a 'temporal' variant of the subtyping relation that
62 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)). 64 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)).
63 // 65 //
66 //
64 // REPRESENTATIONAL DIMENSION 67 // REPRESENTATIONAL DIMENSION
65 // 68 //
66 // For the representation axis, the following holds: 69 // For the representation axis, the following holds:
67 // 70 //
68 // None <= R 71 // None <= R
69 // R <= Any 72 // R <= Any
70 // 73 //
71 // UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/ 74 // UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/
72 // UntaggedInt16 \/ UntaggedInt32 75 // UntaggedInt16 \/ UntaggedInt32
73 // UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64 76 // UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64
74 // UntaggedNumber = UntaggedInt \/ UntaggedFloat 77 // UntaggedNumber = UntaggedInt \/ UntaggedFloat
75 // Untagged = UntaggedNumber \/ UntaggedPtr 78 // Untagged = UntaggedNumber \/ UntaggedPtr
76 // Tagged = TaggedInt \/ TaggedPtr 79 // Tagged = TaggedInt \/ TaggedPtr
77 // 80 //
78 // Subtyping relates the two dimensions, for example: 81 // Subtyping relates the two dimensions, for example:
79 // 82 //
80 // Number <= Tagged \/ UntaggedNumber 83 // Number <= Tagged \/ UntaggedNumber
81 // Object <= TaggedPtr \/ UntaggedPtr 84 // Object <= TaggedPtr \/ UntaggedPtr
82 // 85 //
83 // 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
84 // 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
85 // representation types initially include all semantic ranges. Representations 88 // representation types initially include all semantic ranges. Representations
86 // 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:
87 // 90 //
88 // SignedSmall /\ TaggedInt (a 'smi') 91 // SignedSmall /\ TaggedInt (a 'smi')
89 // Number /\ TaggedPtr (a heap number) 92 // Number /\ TaggedPtr (a heap number)
90 // 93 //
94 //
95 // RANGE TYPES
96 //
97 // A range type represents a continuous integer interval by its minimum and
98 // maximum value. Either value might be an infinity.
99 //
100 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an
101 // integer between x and y.
102 //
103 //
91 // PREDICATES 104 // PREDICATES
92 // 105 //
93 // There are two main functions for testing types: 106 // There are two main functions for testing types:
94 // 107 //
95 // 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)
96 // 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)
97 // 110 //
98 // 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
99 // T->Is(SignedSmall())), and the latter to check whether a specific case needs 112 // T->Is(SignedSmall())), and the latter to check whether a specific case needs
100 // handling (e.g., via T->Maybe(Number())). 113 // handling (e.g., via T->Maybe(Number())).
101 // 114 //
102 // 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
103 // 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
104 // lattice (e.g., splitting up number types further) without invalidating any 117 // lattice (e.g., splitting up number types further) without invalidating any
105 // existing assumptions or tests. 118 // existing assumptions or tests.
106 // 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!
107 // 120 //
108 // The NowIs operator implements state-sensitive subtying, as described above. 121 // The NowIs operator implements state-sensitive subtying, as described above.
109 // Any compilation decision based on such temporary properties requires runtime 122 // Any compilation decision based on such temporary properties requires runtime
110 // guarding! 123 // guarding!
111 // 124 //
125 //
112 // PROPERTIES 126 // PROPERTIES
113 // 127 //
114 // Various formal properties hold for constructors, operators, and predicates 128 // Various formal properties hold for constructors, operators, and predicates
115 // over types. For example, constructors are injective, subtyping is a complete 129 // over types. For example, constructors are injective and subtyping is a
116 // partial order, union and intersection satisfy the usual algebraic properties. 130 // complete partial order.
117 // 131 //
118 // See test/cctest/test-types.cc for a comprehensive executable specification, 132 // See test/cctest/test-types.cc for a comprehensive executable specification,
119 // especially with respect to the properties of the more exotic 'temporal' 133 // especially with respect to the properties of the more exotic 'temporal'
120 // constructors and predicates (those prefixed 'Now'). 134 // constructors and predicates (those prefixed 'Now').
121 // 135 //
136 //
122 // IMPLEMENTATION 137 // IMPLEMENTATION
123 // 138 //
124 // Internally, all 'primitive' types, and their unions, are represented as 139 // Internally, all 'primitive' types, and their unions, are represented as
125 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or 140 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or
126 // unions containing Class'es or Constant's, currently require allocation. 141 // unions containing Class'es or Constant's, currently require allocation.
127 // Note that the bitset representation is closed under both Union and Intersect. 142 // Note that the bitset representation is closed under both Union and Intersect.
128 // 143 //
129 // There are two type representations, using different allocation: 144 // There are two type representations, using different allocation:
130 // 145 //
131 // - class Type (zone-allocated, for compiler and concurrent compilation) 146 // - class Type (zone-allocated, for compiler and concurrent compilation)
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 V(Primitive, kNumber | kName | kBoolean | kNull | kUndefined) \ 216 V(Primitive, kNumber | kName | kBoolean | kNull | kUndefined) \
202 V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \ 217 V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
203 V(DetectableReceiver, kDetectableObject | kProxy) \ 218 V(DetectableReceiver, kDetectableObject | kProxy) \
204 V(Detectable, kDetectableReceiver | kNumber | kName) \ 219 V(Detectable, kDetectableReceiver | kNumber | kName) \
205 V(Object, kDetectableObject | kUndetectable) \ 220 V(Object, kDetectableObject | kUndetectable) \
206 V(Receiver, kObject | kProxy) \ 221 V(Receiver, kObject | kProxy) \
207 V(NonNumber, kBoolean | kName | kNull | kReceiver | \ 222 V(NonNumber, kBoolean | kName | kNull | kReceiver | \
208 kUndefined | kInternal) \ 223 kUndefined | kInternal) \
209 V(Any, -1) 224 V(Any, -1)
210 225
226 /*
227 * The following diagrams show how integers (in the mathematical sense) are
228 * divided among the different atomic numerical types.
229 *
230 * If SmiValuesAre31Bits():
231 *
232 * ON OS32 OSS US OU31 OU32 ON
233 * ______[_______[_______[_______[_______[_______[_______
234 * -2^31 -2^30 0 2^30 2^31 2^32
235 *
236 * Otherwise:
237 *
238 * ON OSS US OU32 ON
239 * ______[_______________[_______________[_______[_______
240 * -2^31 0 2^31 2^32
241 *
242 *
243 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
244 *
245 */
246
247 #define PROPER_BITSET_TYPE_LIST(V) \
248 REPRESENTATION_BITSET_TYPE_LIST(V) \
249 SEMANTIC_BITSET_TYPE_LIST(V)
250
211 #define BITSET_TYPE_LIST(V) \ 251 #define BITSET_TYPE_LIST(V) \
212 MASK_BITSET_TYPE_LIST(V) \ 252 MASK_BITSET_TYPE_LIST(V) \
213 REPRESENTATION_BITSET_TYPE_LIST(V) \ 253 PROPER_BITSET_TYPE_LIST(V)
214 SEMANTIC_BITSET_TYPE_LIST(V)
215 254
216 255
217 // ----------------------------------------------------------------------------- 256 // -----------------------------------------------------------------------------
218 // The abstract Type class, parameterized over the low-level representation. 257 // The abstract Type class, parameterized over the low-level representation.
219 258
220 // struct Config { 259 // struct Config {
221 // typedef TypeImpl<Config> Type; 260 // typedef TypeImpl<Config> Type;
222 // typedef Base; 261 // typedef Base;
223 // typedef Struct; 262 // typedef Struct;
224 // typedef Region; 263 // typedef Region;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 typedef typename Config::template Handle<UnionType>::type UnionHandle; 311 typedef typename Config::template Handle<UnionType>::type UnionHandle;
273 typedef typename Config::Region Region; 312 typedef typename Config::Region Region;
274 313
275 // Constructors. 314 // Constructors.
276 315
277 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 316 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
278 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \ 317 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \
279 static TypeHandle type(Region* region) { \ 318 static TypeHandle type(Region* region) { \
280 return BitsetType::New(BitsetType::k##type, region); \ 319 return BitsetType::New(BitsetType::k##type, region); \
281 } 320 }
282 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 321 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
283 #undef DEFINE_TYPE_CONSTRUCTOR 322 #undef DEFINE_TYPE_CONSTRUCTOR
284 323
285 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { 324 static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
286 return ClassType::New(map, region); 325 return ClassType::New(map, region);
287 } 326 }
288 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { 327 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
289 // TODO(neis): Return RangeType for numerical values.
290 return ConstantType::New(value, region); 328 return ConstantType::New(value, region);
291 } 329 }
292 static TypeHandle Range(double min, double max, Region* region) { 330 static TypeHandle Range(
331 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
293 return RangeType::New(min, max, region); 332 return RangeType::New(min, max, region);
294 } 333 }
295 static TypeHandle Context(TypeHandle outer, Region* region) { 334 static TypeHandle Context(TypeHandle outer, Region* region) {
296 return ContextType::New(outer, region); 335 return ContextType::New(outer, region);
297 } 336 }
298 static TypeHandle Array(TypeHandle element, Region* region) { 337 static TypeHandle Array(TypeHandle element, Region* region) {
299 return ArrayType::New(element, region); 338 return ArrayType::New(element, region);
300 } 339 }
301 static FunctionHandle Function( 340 static FunctionHandle Function(
302 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 341 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 bool Is(TypeHandle that) { return this->Is(*that); } 389 bool Is(TypeHandle that) { return this->Is(*that); }
351 390
352 bool Maybe(TypeImpl* that); 391 bool Maybe(TypeImpl* that);
353 template<class TypeHandle> 392 template<class TypeHandle>
354 bool Maybe(TypeHandle that) { return this->Maybe(*that); } 393 bool Maybe(TypeHandle that) { return this->Maybe(*that); }
355 394
356 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); } 395 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
357 template<class TypeHandle> 396 template<class TypeHandle>
358 bool Equals(TypeHandle that) { return this->Equals(*that); } 397 bool Equals(TypeHandle that) { return this->Equals(*that); }
359 398
360 // Equivalent to Constant(value)->Is(this), but avoiding allocation. 399 // Equivalent to Constant(val)->Is(this), but avoiding allocation.
361 bool Contains(i::Object* val); 400 bool Contains(i::Object* val);
362 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } 401 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
363 402
364 // State-dependent versions of the above that consider subtyping between 403 // State-dependent versions of the above that consider subtyping between
365 // a constant and its map class. 404 // a constant and its map class.
366 inline static TypeHandle NowOf(i::Object* value, Region* region); 405 inline static TypeHandle NowOf(i::Object* value, Region* region);
367 static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) { 406 static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) {
368 return NowOf(*value, region); 407 return NowOf(*value, region);
369 } 408 }
370 bool NowIs(TypeImpl* that); 409 bool NowIs(TypeImpl* that);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 int AsBitset() { 498 int AsBitset() {
460 DCHECK(this->IsBitset()); 499 DCHECK(this->IsBitset());
461 return static_cast<BitsetType*>(this)->Bitset(); 500 return static_cast<BitsetType*>(this)->Bitset();
462 } 501 }
463 UnionType* AsUnion() { return UnionType::cast(this); } 502 UnionType* AsUnion() { return UnionType::cast(this); }
464 503
465 // Auxiliary functions. 504 // Auxiliary functions.
466 505
467 int BitsetGlb() { return BitsetType::Glb(this); } 506 int BitsetGlb() { return BitsetType::Glb(this); }
468 int BitsetLub() { return BitsetType::Lub(this); } 507 int BitsetLub() { return BitsetType::Lub(this); }
469 int InherentBitsetLub() { return BitsetType::InherentLub(this); }
470 508
471 bool SlowIs(TypeImpl* that); 509 bool SlowIs(TypeImpl* that);
472 510
473 TypeHandle Rebound(int bitset, Region* region); 511 static bool IsInteger(double x) {
474 int BoundBy(TypeImpl* that); 512 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
475 int IndexInUnion(int bound, UnionHandle unioned, int current_size); 513 }
476 static int ExtendUnion( 514 static bool IsInteger(i::Object* x) {
477 UnionHandle unioned, int current_size, TypeHandle t, 515 return x->IsNumber() && IsInteger(x->Number());
478 TypeHandle other, bool is_intersect, Region* region); 516 }
517
518 struct Limits {
519 i::Handle<i::Object> min;
520 i::Handle<i::Object> max;
521 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) :
522 min(min), max(max) {}
523 explicit Limits(RangeType* range) :
524 min(range->MinV()), max(range->MaxV()) {}
525 };
526
527 static Limits intersect(Limits lhs, Limits rhs);
rossberg 2014/09/15 15:58:30 Nit: use uppercase names.
neis1 2014/09/16 10:04:00 Done.
528 static Limits union_(Limits lhs, Limits rhs);
529 static bool overlap(RangeType* lhs, RangeType* rhs);
530 static bool contains(RangeType* lhs, RangeType* rhs);
531 static bool contains(RangeType* range, i::Object* val);
532
533 RangeType* GetRange();
534 static int UpdateRange(
535 RangeHandle type, UnionHandle result, int size, Region* region);
536
537 bool SimplyEquals(TypeImpl* that);
538 static int AddToUnion(
539 TypeHandle type, UnionHandle result, int size, Region* region);
540 static int IntersectAux(
541 TypeHandle type, TypeHandle other,
542 UnionHandle result, int size, Region* region);
543 static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
479 }; 544 };
480 545
481 546
482 // ----------------------------------------------------------------------------- 547 // -----------------------------------------------------------------------------
483 // Bitset types (internal). 548 // Bitset types (internal).
484 549
485 template<class Config> 550 template<class Config>
486 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { 551 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
487 protected: 552 protected:
488 friend class TypeImpl<Config>; 553 friend class TypeImpl<Config>;
489 554
490 enum { 555 enum {
491 #define DECLARE_TYPE(type, value) k##type = (value), 556 #define DECLARE_TYPE(type, value) k##type = (value),
492 BITSET_TYPE_LIST(DECLARE_TYPE) 557 BITSET_TYPE_LIST(DECLARE_TYPE)
493 #undef DECLARE_TYPE 558 #undef DECLARE_TYPE
494 kUnusedEOL = 0 559 kUnusedEOL = 0
495 }; 560 };
496 561
497 int Bitset() { return Config::as_bitset(this); } 562 int Bitset() { return Config::as_bitset(this); }
498 563
499 static TypeImpl* New(int bitset) { 564 static TypeImpl* New(int bitset) {
565 DCHECK(bitset == kNone || IsInhabited(bitset));
500 return static_cast<BitsetType*>(Config::from_bitset(bitset)); 566 return static_cast<BitsetType*>(Config::from_bitset(bitset));
501 } 567 }
502 static TypeHandle New(int bitset, Region* region) { 568 static TypeHandle New(int bitset, Region* region) {
569 DCHECK(bitset == kNone || IsInhabited(bitset));
503 return Config::from_bitset(bitset, region); 570 return Config::from_bitset(bitset, region);
504 } 571 }
505 572
506 static bool IsInhabited(int bitset) { 573 static bool IsInhabited(int bitset) {
507 return (bitset & kRepresentation) && (bitset & kSemantic); 574 return bitset & kSemantic;
rossberg 2014/09/15 15:58:30 Hm, well, this doesn't really reflect the function
neis1 2014/09/16 10:04:00 Depends on your definition of inhabited ;) I have
508 } 575 }
509 576
510 static bool Is(int bitset1, int bitset2) { 577 static bool Is(int bitset1, int bitset2) {
511 return (bitset1 | bitset2) == bitset2; 578 return (bitset1 | bitset2) == bitset2;
512 } 579 }
513 580
514 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset 581 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset
515 static int Lub(TypeImpl* type); // least upper bound that's a bitset 582 static int Lub(TypeImpl* type); // least upper bound that's a bitset
516 static int Lub(i::Object* value); 583 static int Lub(i::Object* value);
517 static int Lub(double value); 584 static int Lub(double value);
518 static int Lub(int32_t value); 585 static int Lub(int32_t value);
519 static int Lub(uint32_t value); 586 static int Lub(uint32_t value);
520 static int Lub(i::Map* map); 587 static int Lub(i::Map* map);
521 static int Lub(double min, double max); 588 static int Lub(Limits lim);
522 static int InherentLub(TypeImpl* type);
523 589
524 static const char* Name(int bitset); 590 static const char* Name(int bitset);
525 static void Print(OStream& os, int bitset); // NOLINT 591 static void Print(OStream& os, int bitset); // NOLINT
526 using TypeImpl::PrintTo; 592 #ifdef DEBUG
593 static void Print(int bitset);
594 #endif
527 }; 595 };
528 596
529 597
530 // ----------------------------------------------------------------------------- 598 // -----------------------------------------------------------------------------
531 // Superclass for non-bitset types (internal). 599 // Superclass for non-bitset types (internal).
532 // Contains a tag and a variable number of type or value fields. 600 // Contains a tag and a variable number of type or value fields.
533 601
534 template<class Config> 602 template<class Config>
535 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { 603 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
536 protected: 604 protected:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 bool Wellformed(); 670 bool Wellformed();
603 }; 671 };
604 672
605 673
606 // ----------------------------------------------------------------------------- 674 // -----------------------------------------------------------------------------
607 // Class types. 675 // Class types.
608 676
609 template<class Config> 677 template<class Config>
610 class TypeImpl<Config>::ClassType : public StructuralType { 678 class TypeImpl<Config>::ClassType : public StructuralType {
611 public: 679 public:
612 TypeHandle Bound(Region* region) {
613 return Config::is_class(this)
614 ? BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region)
615 : this->Get(0);
616 }
617 i::Handle<i::Map> Map() { 680 i::Handle<i::Map> Map() {
618 return Config::is_class(this) 681 return Config::is_class(this)
619 ? Config::as_class(this) 682 ? Config::as_class(this)
620 : this->template GetValue<i::Map>(1); 683 : this->template GetValue<i::Map>(0);
621 }
622
623 static ClassHandle New(
624 i::Handle<i::Map> map, TypeHandle bound, Region* region) {
625 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*map)));
626 ClassHandle type = Config::template cast<ClassType>(
627 StructuralType::New(StructuralType::kClassTag, 2, region));
628 type->Set(0, bound);
629 type->SetValue(1, map);
630 return type;
631 } 684 }
632 685
633 static ClassHandle New(i::Handle<i::Map> map, Region* region) { 686 static ClassHandle New(i::Handle<i::Map> map, Region* region) {
634 ClassHandle type = 687 ClassHandle type =
635 Config::template cast<ClassType>(Config::from_class(map, region)); 688 Config::template cast<ClassType>(Config::from_class(map, region));
636 if (type->IsClass()) { 689 if (!type->IsClass()) {
637 return type; 690 type = Config::template cast<ClassType>(
638 } else { 691 StructuralType::New(StructuralType::kClassTag, 1, region));
639 TypeHandle bound = BitsetType::New(BitsetType::Lub(*map), region); 692 type->SetValue(0, map);
640 return New(map, bound, region);
641 } 693 }
694 return type;
642 } 695 }
643 696
644 static ClassType* cast(TypeImpl* type) { 697 static ClassType* cast(TypeImpl* type) {
645 DCHECK(type->IsClass()); 698 DCHECK(type->IsClass());
646 return static_cast<ClassType*>(type); 699 return static_cast<ClassType*>(type);
647 } 700 }
648 }; 701 };
649 702
650 703
651 // ----------------------------------------------------------------------------- 704 // -----------------------------------------------------------------------------
652 // Constant types. 705 // Constant types.
653 706
654 template<class Config> 707 template<class Config>
655 class TypeImpl<Config>::ConstantType : public StructuralType { 708 class TypeImpl<Config>::ConstantType : public StructuralType {
656 public: 709 public:
657 TypeHandle Bound() { return this->Get(0); } 710 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(0); }
658 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
659
660 static ConstantHandle New(
661 i::Handle<i::Object> value, TypeHandle bound, Region* region) {
662 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*value)));
663 ConstantHandle type = Config::template cast<ConstantType>(
664 StructuralType::New(StructuralType::kConstantTag, 2, region));
665 type->Set(0, bound);
666 type->SetValue(1, value);
667 return type;
668 }
669 711
670 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { 712 static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
671 TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region); 713 ConstantHandle type = Config::template cast<ConstantType>(
672 return New(value, bound, region); 714 StructuralType::New(StructuralType::kConstantTag, 1, region));
715 type->SetValue(0, value);
716 return type;
673 } 717 }
674 718
675 static ConstantType* cast(TypeImpl* type) { 719 static ConstantType* cast(TypeImpl* type) {
676 DCHECK(type->IsConstant()); 720 DCHECK(type->IsConstant());
677 return static_cast<ConstantType*>(type); 721 return static_cast<ConstantType*>(type);
678 } 722 }
679 }; 723 };
680 724
681 725
682 // ----------------------------------------------------------------------------- 726 // -----------------------------------------------------------------------------
683 // Range types. 727 // Range types.
684 728
685 template<class Config> 729 template<class Config>
686 class TypeImpl<Config>::RangeType : public StructuralType { 730 class TypeImpl<Config>::RangeType : public StructuralType {
687 public: 731 public:
688 TypeHandle Bound() { return this->Get(0); } 732 i::Handle<i::Object> MinV() { return this->template GetValue<i::Object>(0); }
689 double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } 733 i::Handle<i::Object> MaxV() { return this->template GetValue<i::Object>(1); }
690 double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } 734 double Min() { return MinV()->Number(); }
735 double Max() { return MaxV()->Number(); }
691 736
692 static RangeHandle New( 737 static RangeHandle New(
693 double min, double max, TypeHandle bound, Region* region) { 738 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
694 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(min, max))); 739 DCHECK(min->Number() <= max->Number());
695 RangeHandle type = Config::template cast<RangeType>( 740 RangeHandle type = Config::template cast<RangeType>(
696 StructuralType::New(StructuralType::kRangeTag, 3, region)); 741 StructuralType::New(StructuralType::kRangeTag, 2, region));
697 type->Set(0, bound); 742 type->SetValue(0, min);
698 Factory* factory = Config::isolate(region)->factory(); 743 type->SetValue(1, max);
699 Handle<HeapNumber> minV = factory->NewHeapNumber(min);
700 Handle<HeapNumber> maxV = factory->NewHeapNumber(max);
701 type->SetValue(1, minV);
702 type->SetValue(2, maxV);
703 return type; 744 return type;
704 } 745 }
705 746
706 static RangeHandle New(double min, double max, Region* region) { 747 static RangeHandle New(Limits lim, Region* region) {
707 TypeHandle bound = BitsetType::New(BitsetType::Lub(min, max), region); 748 return New(lim.min, lim.max, region);
708 return New(min, max, bound, region);
709 } 749 }
710 750
711 static RangeType* cast(TypeImpl* type) { 751 static RangeType* cast(TypeImpl* type) {
712 DCHECK(type->IsRange()); 752 DCHECK(type->IsRange());
713 return static_cast<RangeType*>(type); 753 return static_cast<RangeType*>(type);
714 } 754 }
715 }; 755 };
716 756
717 757
718 // ----------------------------------------------------------------------------- 758 // -----------------------------------------------------------------------------
719 // Context types. 759 // Context types.
720 760
721 template<class Config> 761 template<class Config>
722 class TypeImpl<Config>::ContextType : public StructuralType { 762 class TypeImpl<Config>::ContextType : public StructuralType {
723 public: 763 public:
724 TypeHandle Bound() { return this->Get(0); } 764 TypeHandle Outer() { return this->Get(0); }
725 TypeHandle Outer() { return this->Get(1); }
726
727 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) {
728 DCHECK(BitsetType::Is(
729 bound->AsBitset(), BitsetType::kInternal & BitsetType::kTaggedPtr));
730 ContextHandle type = Config::template cast<ContextType>(
731 StructuralType::New(StructuralType::kContextTag, 2, region));
732 type->Set(0, bound);
733 type->Set(1, outer);
734 return type;
735 }
736 765
737 static ContextHandle New(TypeHandle outer, Region* region) { 766 static ContextHandle New(TypeHandle outer, Region* region) {
738 TypeHandle bound = BitsetType::New( 767 ContextHandle type = Config::template cast<ContextType>(
739 BitsetType::kInternal & BitsetType::kTaggedPtr, region); 768 StructuralType::New(StructuralType::kContextTag, 1, region));
740 return New(outer, bound, region); 769 type->Set(0, outer);
770 return type;
741 } 771 }
742 772
743 static ContextType* cast(TypeImpl* type) { 773 static ContextType* cast(TypeImpl* type) {
744 DCHECK(type->IsContext()); 774 DCHECK(type->IsContext());
745 return static_cast<ContextType*>(type); 775 return static_cast<ContextType*>(type);
746 } 776 }
747 }; 777 };
748 778
749 779
750 // ----------------------------------------------------------------------------- 780 // -----------------------------------------------------------------------------
751 // Array types. 781 // Array types.
752 782
753 template<class Config> 783 template<class Config>
754 class TypeImpl<Config>::ArrayType : public StructuralType { 784 class TypeImpl<Config>::ArrayType : public StructuralType {
755 public: 785 public:
756 TypeHandle Bound() { return this->Get(0); } 786 TypeHandle Element() { return this->Get(0); }
757 TypeHandle Element() { return this->Get(1); }
758
759 static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) {
760 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kArray));
761 ArrayHandle type = Config::template cast<ArrayType>(
762 StructuralType::New(StructuralType::kArrayTag, 2, region));
763 type->Set(0, bound);
764 type->Set(1, element);
765 return type;
766 }
767 787
768 static ArrayHandle New(TypeHandle element, Region* region) { 788 static ArrayHandle New(TypeHandle element, Region* region) {
769 TypeHandle bound = BitsetType::New(BitsetType::kArray, region); 789 ArrayHandle type = Config::template cast<ArrayType>(
770 return New(element, bound, region); 790 StructuralType::New(StructuralType::kArrayTag, 1, region));
791 type->Set(0, element);
792 return type;
771 } 793 }
772 794
773 static ArrayType* cast(TypeImpl* type) { 795 static ArrayType* cast(TypeImpl* type) {
774 DCHECK(type->IsArray()); 796 DCHECK(type->IsArray());
775 return static_cast<ArrayType*>(type); 797 return static_cast<ArrayType*>(type);
776 } 798 }
777 }; 799 };
778 800
779 801
780 // ----------------------------------------------------------------------------- 802 // -----------------------------------------------------------------------------
781 // Function types. 803 // Function types.
782 804
783 template<class Config> 805 template<class Config>
784 class TypeImpl<Config>::FunctionType : public StructuralType { 806 class TypeImpl<Config>::FunctionType : public StructuralType {
785 public: 807 public:
786 int Arity() { return this->Length() - 3; } 808 int Arity() { return this->Length() - 2; }
787 TypeHandle Bound() { return this->Get(0); } 809 TypeHandle Result() { return this->Get(0); }
788 TypeHandle Result() { return this->Get(1); } 810 TypeHandle Receiver() { return this->Get(1); }
789 TypeHandle Receiver() { return this->Get(2); } 811 TypeHandle Parameter(int i) { return this->Get(2 + i); }
790 TypeHandle Parameter(int i) { return this->Get(3 + i); }
791 812
792 void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); } 813 void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
793
794 static FunctionHandle New(
795 TypeHandle result, TypeHandle receiver, TypeHandle bound,
796 int arity, Region* region) {
797 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kFunction));
798 FunctionHandle type = Config::template cast<FunctionType>(
799 StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region));
800 type->Set(0, bound);
801 type->Set(1, result);
802 type->Set(2, receiver);
803 return type;
804 }
805 814
806 static FunctionHandle New( 815 static FunctionHandle New(
807 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 816 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
808 TypeHandle bound = BitsetType::New(BitsetType::kFunction, region); 817 FunctionHandle type = Config::template cast<FunctionType>(
809 return New(result, receiver, bound, arity, region); 818 StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
819 type->Set(0, result);
820 type->Set(1, receiver);
821 return type;
810 } 822 }
811 823
812 static FunctionType* cast(TypeImpl* type) { 824 static FunctionType* cast(TypeImpl* type) {
813 DCHECK(type->IsFunction()); 825 DCHECK(type->IsFunction());
814 return static_cast<FunctionType*>(type); 826 return static_cast<FunctionType*>(type);
815 } 827 }
816 }; 828 };
817 829
818 830
819 // ----------------------------------------------------------------------------- 831 // -----------------------------------------------------------------------------
(...skipping 26 matching lines...) Expand all
846 // Zone-allocated types; they are either (odd) integers to represent bitsets, or 858 // Zone-allocated types; they are either (odd) integers to represent bitsets, or
847 // (even) pointers to structures for everything else. 859 // (even) pointers to structures for everything else.
848 860
849 struct ZoneTypeConfig { 861 struct ZoneTypeConfig {
850 typedef TypeImpl<ZoneTypeConfig> Type; 862 typedef TypeImpl<ZoneTypeConfig> Type;
851 class Base {}; 863 class Base {};
852 typedef void* Struct; 864 typedef void* Struct;
853 typedef i::Zone Region; 865 typedef i::Zone Region;
854 template<class T> struct Handle { typedef T* type; }; 866 template<class T> struct Handle { typedef T* type; };
855 867
856 // TODO(neis): This will be removed again once we have struct_get_double().
857 static inline i::Isolate* isolate(Region* region) {
858 return region->isolate();
859 }
860
861 template<class T> static inline T* handle(T* type); 868 template<class T> static inline T* handle(T* type);
862 template<class T> static inline T* cast(Type* type); 869 template<class T> static inline T* cast(Type* type);
863 870
864 static inline bool is_bitset(Type* type); 871 static inline bool is_bitset(Type* type);
865 static inline bool is_class(Type* type); 872 static inline bool is_class(Type* type);
866 static inline bool is_struct(Type* type, int tag); 873 static inline bool is_struct(Type* type, int tag);
867 874
868 static inline int as_bitset(Type* type); 875 static inline int as_bitset(Type* type);
869 static inline i::Handle<i::Map> as_class(Type* type); 876 static inline i::Handle<i::Map> as_class(Type* type);
870 static inline Struct* as_struct(Type* type); 877 static inline Struct* as_struct(Type* type);
(...skipping 22 matching lines...) Expand all
893 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for 900 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for
894 // constants, or fixed arrays for unions. 901 // constants, or fixed arrays for unions.
895 902
896 struct HeapTypeConfig { 903 struct HeapTypeConfig {
897 typedef TypeImpl<HeapTypeConfig> Type; 904 typedef TypeImpl<HeapTypeConfig> Type;
898 typedef i::Object Base; 905 typedef i::Object Base;
899 typedef i::FixedArray Struct; 906 typedef i::FixedArray Struct;
900 typedef i::Isolate Region; 907 typedef i::Isolate Region;
901 template<class T> struct Handle { typedef i::Handle<T> type; }; 908 template<class T> struct Handle { typedef i::Handle<T> type; };
902 909
903 // TODO(neis): This will be removed again once we have struct_get_double().
904 static inline i::Isolate* isolate(Region* region) {
905 return region;
906 }
907
908 template<class T> static inline i::Handle<T> handle(T* type); 910 template<class T> static inline i::Handle<T> handle(T* type);
909 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); 911 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
910 912
911 static inline bool is_bitset(Type* type); 913 static inline bool is_bitset(Type* type);
912 static inline bool is_class(Type* type); 914 static inline bool is_class(Type* type);
913 static inline bool is_struct(Type* type, int tag); 915 static inline bool is_struct(Type* type, int tag);
914 916
915 static inline int as_bitset(Type* type); 917 static inline int as_bitset(Type* type);
916 static inline i::Handle<i::Map> as_class(Type* type); 918 static inline i::Handle<i::Map> as_class(Type* type);
917 static inline i::Handle<Struct> as_struct(Type* type); 919 static inline i::Handle<Struct> as_struct(Type* type);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 bool Narrows(BoundsImpl that) { 997 bool Narrows(BoundsImpl that) {
996 return that.lower->Is(this->lower) && this->upper->Is(that.upper); 998 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
997 } 999 }
998 }; 1000 };
999 1001
1000 typedef BoundsImpl<ZoneTypeConfig> Bounds; 1002 typedef BoundsImpl<ZoneTypeConfig> Bounds;
1001 1003
1002 } } // namespace v8::internal 1004 } } // namespace v8::internal
1003 1005
1004 #endif // V8_TYPES_H_ 1006 #endif // V8_TYPES_H_
OLDNEW
« 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