OLD | NEW |
---|---|
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_COMPILER_TYPES_H_ | 5 #ifndef V8_COMPILER_TYPES_H_ |
6 #define V8_COMPILER_TYPES_H_ | 6 #define V8_COMPILER_TYPES_H_ |
7 | 7 |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 #include "src/ostreams.h" | 11 #include "src/ostreams.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 // SUMMARY | 17 // SUMMARY |
18 // | 18 // |
19 // A simple type system for compiler-internal use. It is based entirely on | 19 // A simple type system for compiler-internal use. It is based entirely on |
20 // union types, and all subtyping hence amounts to set inclusion. Besides the | 20 // union types, and all subtyping hence amounts to set inclusion. Besides the |
21 // obvious primitive types and some predefined unions, the type language also | 21 // obvious primitive types and some predefined unions, the type language also |
22 // can express class types (a.k.a. specific maps) and singleton types (i.e., | 22 // can express class types (a.k.a. specific maps) and singleton types (i.e., |
23 // concrete constants). | 23 // concrete constants). |
24 // | 24 // |
25 // Types consist of two dimensions: semantic (value range) and representation. | 25 // The following equations and inequations hold: |
26 // Both are related through subtyping. | |
27 // | |
28 // | |
29 // SEMANTIC DIMENSION | |
30 // | |
31 // The following equations and inequations hold for the semantic axis: | |
32 // | 26 // |
33 // None <= T | 27 // None <= T |
34 // T <= Any | 28 // T <= Any |
35 // | 29 // |
36 // Number = Signed32 \/ Unsigned32 \/ Double | 30 // Number = Signed32 \/ Unsigned32 \/ Double |
37 // Smi <= Signed32 | 31 // Smi <= Signed32 |
38 // Name = String \/ Symbol | 32 // Name = String \/ Symbol |
39 // UniqueName = InternalizedString \/ Symbol | 33 // UniqueName = InternalizedString \/ Symbol |
40 // InternalizedString < String | 34 // InternalizedString < String |
41 // | 35 // |
42 // Receiver = Object \/ Proxy | 36 // Receiver = Object \/ Proxy |
43 // RegExp < Object | 37 // RegExp < Object |
Jarin
2016/09/23 09:23:39
While you are here, can you remove this line?
mvstanton
2016/09/23 11:23:57
Done.
| |
44 // OtherUndetectable < Object | 38 // OtherUndetectable < Object |
45 // DetectableReceiver = Receiver - OtherUndetectable | 39 // DetectableReceiver = Receiver - OtherUndetectable |
46 // | 40 // |
47 // Constant(x) < T iff instance_type(map(x)) < T | 41 // Constant(x) < T iff instance_type(map(x)) < T |
48 // | 42 // |
49 // | 43 // |
50 // RANGE TYPES | 44 // RANGE TYPES |
51 // | 45 // |
52 // A range type represents a continuous integer interval by its minimum and | 46 // A range type represents a continuous integer interval by its minimum and |
53 // maximum value. Either value may be an infinity, in which case that infinity | 47 // maximum value. Either value may be an infinity, in which case that infinity |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 // | 90 // |
97 // Internally, all 'primitive' types, and their unions, are represented as | 91 // Internally, all 'primitive' types, and their unions, are represented as |
98 // bitsets. Bit 0 is reserved for tagging. Only structured types require | 92 // bitsets. Bit 0 is reserved for tagging. Only structured types require |
99 // allocation. | 93 // allocation. |
100 | 94 |
101 // ----------------------------------------------------------------------------- | 95 // ----------------------------------------------------------------------------- |
102 // Values for bitset types | 96 // Values for bitset types |
103 | 97 |
104 // clang-format off | 98 // clang-format off |
105 | 99 |
106 #define MASK_BITSET_TYPE_LIST(V) \ | |
107 V(Semantic, 0xfffffffeu) | |
108 | |
109 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) | |
110 | |
111 #define INTERNAL_BITSET_TYPE_LIST(V) \ | 100 #define INTERNAL_BITSET_TYPE_LIST(V) \ |
112 V(OtherUnsigned31, 1u << 1) \ | 101 V(OtherUnsigned31, 1u << 1) \ |
113 V(OtherUnsigned32, 1u << 2) \ | 102 V(OtherUnsigned32, 1u << 2) \ |
114 V(OtherSigned32, 1u << 3) \ | 103 V(OtherSigned32, 1u << 3) \ |
115 V(OtherNumber, 1u << 4) \ | 104 V(OtherNumber, 1u << 4) \ |
116 | 105 |
117 #define SEMANTIC_BITSET_TYPE_LIST(V) \ | 106 #define NONINTERNAL_BITSET_TYPE_LIST(V) \ |
Jarin
2016/09/23 09:23:39
How about calling this PROPER_BITSET_TYPE_LIST?
mvstanton
2016/09/23 11:23:57
Done.
| |
118 V(None, 0u) \ | 107 V(None, 0u) \ |
119 V(Negative31, 1u << 5) \ | 108 V(Negative31, 1u << 5) \ |
120 V(Null, 1u << 6) \ | 109 V(Null, 1u << 6) \ |
121 V(Undefined, 1u << 7) \ | 110 V(Undefined, 1u << 7) \ |
122 V(Boolean, 1u << 8) \ | 111 V(Boolean, 1u << 8) \ |
123 V(Unsigned30, 1u << 9) \ | 112 V(Unsigned30, 1u << 9) \ |
124 V(MinusZero, 1u << 10) \ | 113 V(MinusZero, 1u << 10) \ |
125 V(NaN, 1u << 11) \ | 114 V(NaN, 1u << 11) \ |
126 V(Symbol, 1u << 12) \ | 115 V(Symbol, 1u << 12) \ |
127 V(InternalizedString, 1u << 13) \ | 116 V(InternalizedString, 1u << 13) \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 * ______[_______[_______[_______[_______[_______[_______ | 174 * ______[_______[_______[_______[_______[_______[_______ |
186 * -2^31 -2^30 0 2^30 2^31 2^32 | 175 * -2^31 -2^30 0 2^30 2^31 2^32 |
187 * | 176 * |
188 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. | 177 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. |
189 * | 178 * |
190 * Some of the atomic numerical bitsets are internal only (see | 179 * Some of the atomic numerical bitsets are internal only (see |
191 * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in | 180 * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in |
192 * union with certain other bitsets. For instance, OtherNumber should only | 181 * union with certain other bitsets. For instance, OtherNumber should only |
193 * occur as part of PlainNumber. | 182 * occur as part of PlainNumber. |
194 */ | 183 */ |
184 #define PROPER_BITSET_TYPE_LIST(V) NONINTERNAL_BITSET_TYPE_LIST(V) | |
195 | 185 |
196 #define PROPER_BITSET_TYPE_LIST(V) \ | 186 #define BITSET_TYPE_LIST(V) \ |
197 SEMANTIC_BITSET_TYPE_LIST(V) | 187 INTERNAL_BITSET_TYPE_LIST(V) \ |
198 | 188 NONINTERNAL_BITSET_TYPE_LIST(V) |
199 #define BITSET_TYPE_LIST(V) \ | |
200 MASK_BITSET_TYPE_LIST(V) \ | |
201 INTERNAL_BITSET_TYPE_LIST(V) \ | |
202 SEMANTIC_BITSET_TYPE_LIST(V) | |
203 | 189 |
204 class Type; | 190 class Type; |
205 | 191 |
206 // ----------------------------------------------------------------------------- | 192 // ----------------------------------------------------------------------------- |
207 // Bitset types (internal). | 193 // Bitset types (internal). |
208 | 194 |
209 class BitsetType { | 195 class BitsetType { |
210 public: | 196 public: |
211 typedef uint32_t bitset; // Internal | 197 typedef uint32_t bitset; // Internal |
212 | 198 |
213 enum : uint32_t { | 199 enum : uint32_t { |
214 #define DECLARE_TYPE(type, value) k##type = (value), | 200 #define DECLARE_TYPE(type, value) k##type = (value), |
215 BITSET_TYPE_LIST(DECLARE_TYPE) | 201 BITSET_TYPE_LIST(DECLARE_TYPE) |
216 #undef DECLARE_TYPE | 202 #undef DECLARE_TYPE |
217 kUnusedEOL = 0 | 203 kUnusedEOL = 0 |
218 }; | 204 }; |
219 | 205 |
220 static bitset SignedSmall(); | 206 static bitset SignedSmall(); |
221 static bitset UnsignedSmall(); | 207 static bitset UnsignedSmall(); |
222 | 208 |
223 bitset Bitset() { | 209 bitset Bitset() { |
224 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u); | 210 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u); |
225 } | 211 } |
226 | 212 |
227 static bool IsInhabited(bitset bits) { return SemanticIsInhabited(bits); } | 213 static bool IsInhabited(bitset bits) { return bits != kNone; } |
228 | |
229 static bool SemanticIsInhabited(bitset bits) { | |
230 return SEMANTIC(bits) != kNone; | |
231 } | |
232 | 214 |
233 static bool Is(bitset bits1, bitset bits2) { | 215 static bool Is(bitset bits1, bitset bits2) { |
234 return (bits1 | bits2) == bits2; | 216 return (bits1 | bits2) == bits2; |
235 } | 217 } |
236 | 218 |
237 static double Min(bitset); | 219 static double Min(bitset); |
238 static double Max(bitset); | 220 static double Max(bitset); |
239 | 221 |
240 static bitset Glb(Type* type); // greatest lower bound that's a bitset | 222 static bitset Glb(Type* type); // greatest lower bound that's a bitset |
241 static bitset Glb(double min, double max); | 223 static bitset Glb(double min, double max); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 return New(Limits(min, max), zone); | 346 return New(Limits(min, max), zone); |
365 } | 347 } |
366 | 348 |
367 static bool IsInteger(double x) { | 349 static bool IsInteger(double x) { |
368 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 350 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
369 } | 351 } |
370 | 352 |
371 static Type* New(Limits lim, Zone* zone) { | 353 static Type* New(Limits lim, Zone* zone) { |
372 DCHECK(IsInteger(lim.min) && IsInteger(lim.max)); | 354 DCHECK(IsInteger(lim.min) && IsInteger(lim.max)); |
373 DCHECK(lim.min <= lim.max); | 355 DCHECK(lim.min <= lim.max); |
374 BitsetType::bitset bits = SEMANTIC(BitsetType::Lub(lim.min, lim.max)); | 356 BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max); |
375 | 357 |
376 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim)); | 358 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim)); |
377 } | 359 } |
378 | 360 |
379 static RangeType* cast(Type* type) { | 361 static RangeType* cast(Type* type) { |
380 DCHECK(IsKind(type, kRange)); | 362 DCHECK(IsKind(type, kRange)); |
381 return static_cast<RangeType*>(FromType(type)); | 363 return static_cast<RangeType*>(FromType(type)); |
382 } | 364 } |
383 | 365 |
384 RangeType(BitsetType::bitset bitset, Limits limits) | 366 RangeType(BitsetType::bitset bitset, Limits limits) |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 } | 501 } |
520 static Type* Of(i::Handle<i::Object> value, Zone* zone) { | 502 static Type* Of(i::Handle<i::Object> value, Zone* zone) { |
521 return Of(*value, zone); | 503 return Of(*value, zone); |
522 } | 504 } |
523 | 505 |
524 static Type* For(i::Map* map) { | 506 static Type* For(i::Map* map) { |
525 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); | 507 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); |
526 } | 508 } |
527 static Type* For(i::Handle<i::Map> map) { return For(*map); } | 509 static Type* For(i::Handle<i::Map> map) { return For(*map); } |
528 | 510 |
529 // Extraction of components. | |
530 static Type* Semantic(Type* t, Zone* zone); | |
531 | |
532 // Predicates. | 511 // Predicates. |
533 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } | 512 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } |
534 | 513 |
535 bool Is(Type* that) { return this == that || this->SlowIs(that); } | 514 bool Is(Type* that) { return this == that || this->SlowIs(that); } |
536 bool Maybe(Type* that); | 515 bool Maybe(Type* that); |
537 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } | 516 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } |
538 | 517 |
539 // Equivalent to Constant(val)->Is(this), but avoiding allocation. | 518 // Equivalent to Constant(val)->Is(this), but avoiding allocation. |
540 bool Contains(i::Object* val); | 519 bool Contains(i::Object* val); |
541 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } | 520 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 bool IsAny() { return this == Any(); } | 599 bool IsAny() { return this == Any(); } |
621 bool IsBitset() { return BitsetType::IsBitset(this); } | 600 bool IsBitset() { return BitsetType::IsBitset(this); } |
622 bool IsUnion() { return IsKind(TypeBase::kUnion); } | 601 bool IsUnion() { return IsKind(TypeBase::kUnion); } |
623 | 602 |
624 bitset AsBitset() { | 603 bitset AsBitset() { |
625 DCHECK(this->IsBitset()); | 604 DCHECK(this->IsBitset()); |
626 return reinterpret_cast<BitsetType*>(this)->Bitset(); | 605 return reinterpret_cast<BitsetType*>(this)->Bitset(); |
627 } | 606 } |
628 UnionType* AsUnion() { return UnionType::cast(this); } | 607 UnionType* AsUnion() { return UnionType::cast(this); } |
629 | 608 |
630 // Auxiliary functions. | |
631 bool SemanticMaybe(Type* that); | |
632 | |
633 bitset BitsetGlb() { return BitsetType::Glb(this); } | 609 bitset BitsetGlb() { return BitsetType::Glb(this); } |
634 bitset BitsetLub() { return BitsetType::Lub(this); } | 610 bitset BitsetLub() { return BitsetType::Lub(this); } |
635 | 611 |
636 bool SlowIs(Type* that); | 612 bool SlowIs(Type* that); |
637 bool SemanticIs(Type* that); | |
638 | 613 |
639 static bool Overlap(RangeType* lhs, RangeType* rhs); | 614 static bool Overlap(RangeType* lhs, RangeType* rhs); |
640 static bool Contains(RangeType* lhs, RangeType* rhs); | 615 static bool Contains(RangeType* lhs, RangeType* rhs); |
641 static bool Contains(RangeType* range, ConstantType* constant); | 616 static bool Contains(RangeType* range, ConstantType* constant); |
642 static bool Contains(RangeType* range, i::Object* val); | 617 static bool Contains(RangeType* range, i::Object* val); |
643 | 618 |
644 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); | 619 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); |
645 | 620 |
646 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits, | 621 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits, |
647 Zone* zone); | 622 Zone* zone); |
648 static RangeType::Limits ToLimits(bitset bits, Zone* zone); | 623 static RangeType::Limits ToLimits(bitset bits, Zone* zone); |
649 | 624 |
650 bool SimplyEquals(Type* that); | 625 bool SimplyEquals(Type* that); |
651 | 626 |
652 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone); | 627 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone); |
653 static int IntersectAux(Type* type, Type* other, UnionType* result, int size, | 628 static int IntersectAux(Type* type, Type* other, UnionType* result, int size, |
654 RangeType::Limits* limits, Zone* zone); | 629 RangeType::Limits* limits, Zone* zone); |
655 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); | 630 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); |
656 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); | 631 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); |
657 }; | 632 }; |
658 | 633 |
659 } // namespace compiler | 634 } // namespace compiler |
660 } // namespace internal | 635 } // namespace internal |
661 } // namespace v8 | 636 } // namespace v8 |
662 | 637 |
663 #endif // V8_COMPILER_TYPES_H_ | 638 #endif // V8_COMPILER_TYPES_H_ |
OLD | NEW |