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 #include <iomanip> | 5 #include <iomanip> |
6 | 6 |
7 #include "src/types.h" | 7 #include "src/types.h" |
8 | 8 |
9 #include "src/ostreams.h" | 9 #include "src/ostreams.h" |
10 #include "src/types-inl.h" | 10 #include "src/types-inl.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 | 15 |
16 // NOTE: If code is marked as being a "shortcut", this means that removing | 16 // NOTE: If code is marked as being a "shortcut", this means that removing |
17 // the code won't affect the semantics of the surrounding function definition. | 17 // the code won't affect the semantics of the surrounding function definition. |
18 | 18 |
19 | 19 |
20 // ----------------------------------------------------------------------------- | 20 // ----------------------------------------------------------------------------- |
21 // Range-related helper functions. | 21 // Range-related helper functions. |
22 | 22 |
23 // The result may be invalid (max < min). | 23 template <class Config> |
| 24 bool TypeImpl<Config>::Limits::IsEmpty() { |
| 25 return this->min > this->max; |
| 26 } |
| 27 |
| 28 |
24 template<class Config> | 29 template<class Config> |
25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect( | 30 typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Intersect( |
26 Limits lhs, Limits rhs) { | 31 Limits lhs, Limits rhs) { |
27 DisallowHeapAllocation no_allocation; | 32 DisallowHeapAllocation no_allocation; |
28 Limits result(lhs); | 33 Limits result(lhs); |
29 if (lhs.min < rhs.min) result.min = rhs.min; | 34 if (lhs.min < rhs.min) result.min = rhs.min; |
30 if (lhs.max > rhs.max) result.max = rhs.max; | 35 if (lhs.max > rhs.max) result.max = rhs.max; |
31 return result; | 36 return result; |
32 } | 37 } |
33 | 38 |
34 | 39 |
35 template <class Config> | 40 template <class Config> |
36 bool TypeImpl<Config>::IsEmpty(Limits lim) { | 41 typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Union( |
37 return lim.min > lim.max; | 42 Limits lhs, Limits rhs) { |
38 } | |
39 | |
40 | |
41 template <class Config> | |
42 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs, | |
43 Limits rhs) { | |
44 DisallowHeapAllocation no_allocation; | 43 DisallowHeapAllocation no_allocation; |
45 if (IsEmpty(lhs)) return rhs; | 44 if (lhs.IsEmpty()) return rhs; |
46 if (IsEmpty(rhs)) return lhs; | 45 if (rhs.IsEmpty()) return lhs; |
47 Limits result(lhs); | 46 Limits result(lhs); |
48 if (lhs.min > rhs.min) result.min = rhs.min; | 47 if (lhs.min > rhs.min) result.min = rhs.min; |
49 if (lhs.max < rhs.max) result.max = rhs.max; | 48 if (lhs.max < rhs.max) result.max = rhs.max; |
50 return result; | 49 return result; |
51 } | 50 } |
52 | 51 |
53 | 52 |
54 template<class Config> | 53 template<class Config> |
55 bool TypeImpl<Config>::Overlap( | 54 bool TypeImpl<Config>::Overlap( |
56 typename TypeImpl<Config>::RangeType* lhs, | 55 typename TypeImpl<Config>::RangeType* lhs, |
57 typename TypeImpl<Config>::RangeType* rhs) { | 56 typename TypeImpl<Config>::RangeType* rhs) { |
58 DisallowHeapAllocation no_allocation; | 57 DisallowHeapAllocation no_allocation; |
59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs)); | 58 return !Limits::Intersect(Limits(lhs), Limits(rhs)).IsEmpty(); |
60 return lim.min <= lim.max; | |
61 } | 59 } |
62 | 60 |
63 | 61 |
64 template<class Config> | 62 template<class Config> |
65 bool TypeImpl<Config>::Contains( | 63 bool TypeImpl<Config>::Contains( |
66 typename TypeImpl<Config>::RangeType* lhs, | 64 typename TypeImpl<Config>::RangeType* lhs, |
67 typename TypeImpl<Config>::RangeType* rhs) { | 65 typename TypeImpl<Config>::RangeType* rhs) { |
68 DisallowHeapAllocation no_allocation; | 66 DisallowHeapAllocation no_allocation; |
69 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); | 67 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); |
70 } | 68 } |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 if (!AddIsSafe(size1, size2)) return Any(region); | 793 if (!AddIsSafe(size1, size2)) return Any(region); |
796 int size = size1 + size2; | 794 int size = size1 + size2; |
797 if (!AddIsSafe(size, 2)) return Any(region); | 795 if (!AddIsSafe(size, 2)) return Any(region); |
798 size += 2; | 796 size += 2; |
799 UnionHandle result = UnionType::New(size, region); | 797 UnionHandle result = UnionType::New(size, region); |
800 size = 0; | 798 size = 0; |
801 | 799 |
802 // Deal with bitsets. | 800 // Deal with bitsets. |
803 result->Set(size++, BitsetType::New(bits, region)); | 801 result->Set(size++, BitsetType::New(bits, region)); |
804 | 802 |
805 Limits lims = Limits::Empty(region); | 803 Limits lims = Limits::Empty(); |
806 size = IntersectAux(type1, type2, result, size, &lims, region); | 804 size = IntersectAux(type1, type2, result, size, &lims, region); |
807 | 805 |
808 // If the range is not empty, then insert it into the union and | 806 // If the range is not empty, then insert it into the union and |
809 // remove the number bits from the bitset. | 807 // remove the number bits from the bitset. |
810 if (!IsEmpty(lims)) { | 808 if (!lims.IsEmpty()) { |
811 size = UpdateRange(RangeType::New(lims, representation, region), result, | 809 size = UpdateRange(RangeType::New(lims, representation, region), result, |
812 size, region); | 810 size, region); |
813 | 811 |
814 // Remove the number bits. | 812 // Remove the number bits. |
815 bitset number_bits = BitsetType::NumberBits(bits); | 813 bitset number_bits = BitsetType::NumberBits(bits); |
816 bits &= ~number_bits; | 814 bits &= ~number_bits; |
817 result->Set(0, BitsetType::New(bits, region)); | 815 result->Set(0, BitsetType::New(bits, region)); |
818 } | 816 } |
819 return NormalizeUnion(result, size, region); | 817 return NormalizeUnion(result, size, region); |
820 } | 818 } |
(...skipping 21 matching lines...) Expand all Loading... |
842 return size; | 840 return size; |
843 } | 841 } |
844 | 842 |
845 | 843 |
846 template <class Config> | 844 template <class Config> |
847 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, | 845 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, |
848 Region* region) { | 846 Region* region) { |
849 bitset number_bits = BitsetType::NumberBits(bits); | 847 bitset number_bits = BitsetType::NumberBits(bits); |
850 | 848 |
851 if (number_bits == BitsetType::kNone) { | 849 if (number_bits == BitsetType::kNone) { |
852 return Limits::Empty(region); | 850 return Limits::Empty(); |
853 } | 851 } |
854 | 852 |
855 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits)); | 853 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits)); |
856 } | 854 } |
857 | 855 |
858 | 856 |
859 template <class Config> | 857 template <class Config> |
860 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( | 858 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( |
861 TypeHandle range, TypeHandle bitset, Region* region) { | 859 TypeHandle range, TypeHandle bitset, Region* region) { |
862 Limits range_lims(range->AsRange()); | 860 Limits range_lims(range->AsRange()); |
863 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); | 861 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); |
864 return Intersect(range_lims, bitset_lims); | 862 return Limits::Intersect(range_lims, bitset_lims); |
865 } | 863 } |
866 | 864 |
867 | 865 |
868 template <class Config> | 866 template <class Config> |
869 int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs, | 867 int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs, |
870 UnionHandle result, int size, Limits* lims, | 868 UnionHandle result, int size, Limits* lims, |
871 Region* region) { | 869 Region* region) { |
872 if (lhs->IsUnion()) { | 870 if (lhs->IsUnion()) { |
873 for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) { | 871 for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) { |
874 size = | 872 size = |
(...skipping 10 matching lines...) Expand all Loading... |
885 } | 883 } |
886 | 884 |
887 if (!BitsetType::SemanticIsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { | 885 if (!BitsetType::SemanticIsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { |
888 return size; | 886 return size; |
889 } | 887 } |
890 | 888 |
891 if (lhs->IsRange()) { | 889 if (lhs->IsRange()) { |
892 if (rhs->IsBitset()) { | 890 if (rhs->IsBitset()) { |
893 Limits lim = IntersectRangeAndBitset(lhs, rhs, region); | 891 Limits lim = IntersectRangeAndBitset(lhs, rhs, region); |
894 | 892 |
895 if (!IsEmpty(lim)) { | 893 if (!lim.IsEmpty()) { |
896 *lims = Union(lim, *lims); | 894 *lims = Limits::Union(lim, *lims); |
897 } | 895 } |
898 return size; | 896 return size; |
899 } | 897 } |
900 if (rhs->IsClass()) { | 898 if (rhs->IsClass()) { |
901 *lims = Union(Limits(lhs->AsRange()), *lims); | 899 *lims = Limits::Union(Limits(lhs->AsRange()), *lims); |
902 } | 900 } |
903 if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) { | 901 if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) { |
904 return AddToUnion(rhs, result, size, region); | 902 return AddToUnion(rhs, result, size, region); |
905 } | 903 } |
906 if (rhs->IsRange()) { | 904 if (rhs->IsRange()) { |
907 Limits lim = Intersect(Limits(lhs->AsRange()), Limits(rhs->AsRange())); | 905 Limits lim = Limits::Intersect( |
908 if (!IsEmpty(lim)) { | 906 Limits(lhs->AsRange()), Limits(rhs->AsRange())); |
909 *lims = Union(lim, *lims); | 907 if (!lim.IsEmpty()) { |
| 908 *lims = Limits::Union(lim, *lims); |
910 } | 909 } |
911 } | 910 } |
912 return size; | 911 return size; |
913 } | 912 } |
914 if (rhs->IsRange()) { | 913 if (rhs->IsRange()) { |
915 // This case is handled symmetrically above. | 914 // This case is handled symmetrically above. |
916 return IntersectAux(rhs, lhs, result, size, lims, region); | 915 return IntersectAux(rhs, lhs, result, size, lims, region); |
917 } | 916 } |
918 if (lhs->IsBitset() || rhs->IsBitset()) { | 917 if (lhs->IsBitset() || rhs->IsBitset()) { |
919 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, region); | 918 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, region); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 size = 0; | 1008 size = 0; |
1010 | 1009 |
1011 // Compute the new bitset. | 1010 // Compute the new bitset. |
1012 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); | 1011 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); |
1013 | 1012 |
1014 // Deal with ranges. | 1013 // Deal with ranges. |
1015 TypeHandle range = None(region); | 1014 TypeHandle range = None(region); |
1016 RangeType* range1 = type1->GetRange(); | 1015 RangeType* range1 = type1->GetRange(); |
1017 RangeType* range2 = type2->GetRange(); | 1016 RangeType* range2 = type2->GetRange(); |
1018 if (range1 != NULL && range2 != NULL) { | 1017 if (range1 != NULL && range2 != NULL) { |
1019 Limits lims = Union(Limits(range1), Limits(range2)); | 1018 Limits lims = Limits::Union(Limits(range1), Limits(range2)); |
1020 RangeHandle union_range = RangeType::New(lims, representation, region); | 1019 RangeHandle union_range = RangeType::New(lims, representation, region); |
1021 range = NormalizeRangeAndBitset(union_range, &new_bitset, region); | 1020 range = NormalizeRangeAndBitset(union_range, &new_bitset, region); |
1022 } else if (range1 != NULL) { | 1021 } else if (range1 != NULL) { |
1023 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); | 1022 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); |
1024 } else if (range2 != NULL) { | 1023 } else if (range2 != NULL) { |
1025 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); | 1024 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); |
1026 } | 1025 } |
1027 new_bitset = SEMANTIC(new_bitset) | representation; | 1026 new_bitset = SEMANTIC(new_bitset) | representation; |
1028 TypeHandle bits = BitsetType::New(new_bitset, region); | 1027 TypeHandle bits = BitsetType::New(new_bitset, region); |
1029 result->Set(size++, bits); | 1028 result->Set(size++, bits); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 switch (bits) { | 1258 switch (bits) { |
1260 case REPRESENTATION(kAny): return "Any"; | 1259 case REPRESENTATION(kAny): return "Any"; |
1261 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ | 1260 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ |
1262 case REPRESENTATION(k##type): return #type; | 1261 case REPRESENTATION(k##type): return #type; |
1263 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) | 1262 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) |
1264 #undef RETURN_NAMED_REPRESENTATION_TYPE | 1263 #undef RETURN_NAMED_REPRESENTATION_TYPE |
1265 | 1264 |
1266 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 1265 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
1267 case SEMANTIC(k##type): return #type; | 1266 case SEMANTIC(k##type): return #type; |
1268 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 1267 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 1268 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
1269 #undef RETURN_NAMED_SEMANTIC_TYPE | 1269 #undef RETURN_NAMED_SEMANTIC_TYPE |
1270 | 1270 |
1271 default: | 1271 default: |
1272 return NULL; | 1272 return NULL; |
1273 } | 1273 } |
1274 } | 1274 } |
1275 | 1275 |
1276 | 1276 |
1277 template <class Config> | 1277 template <class Config> |
1278 void TypeImpl<Config>::BitsetType::Print(std::ostream& os, // NOLINT | 1278 void TypeImpl<Config>::BitsetType::Print(std::ostream& os, // NOLINT |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 | 1400 |
1401 template TypeImpl<ZoneTypeConfig>::TypeHandle | 1401 template TypeImpl<ZoneTypeConfig>::TypeHandle |
1402 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 1402 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
1403 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 1403 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
1404 template TypeImpl<HeapTypeConfig>::TypeHandle | 1404 template TypeImpl<HeapTypeConfig>::TypeHandle |
1405 TypeImpl<HeapTypeConfig>::Convert<Type>( | 1405 TypeImpl<HeapTypeConfig>::Convert<Type>( |
1406 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 1406 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
1407 | 1407 |
1408 } // namespace internal | 1408 } // namespace internal |
1409 } // namespace v8 | 1409 } // namespace v8 |
OLD | NEW |