Chromium Code Reviews| 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 |