| 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 |