| 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/compiler/types.h" | 7 #include "src/compiler/types.h" |
| 8 | 8 |
| 9 #include "src/handles-inl.h" | 9 #include "src/handles-inl.h" |
| 10 #include "src/ostreams.h" | 10 #include "src/ostreams.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 // Fast case. | 112 // Fast case. |
| 113 if (IsBitset(type)) { | 113 if (IsBitset(type)) { |
| 114 return type->AsBitset(); | 114 return type->AsBitset(); |
| 115 } else if (type->IsUnion()) { | 115 } else if (type->IsUnion()) { |
| 116 SLOW_DCHECK(type->AsUnion()->Wellformed()); | 116 SLOW_DCHECK(type->AsUnion()->Wellformed()); |
| 117 return type->AsUnion()->Get(0)->BitsetGlb() | | 117 return type->AsUnion()->Get(0)->BitsetGlb() | |
| 118 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. | 118 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. |
| 119 } else if (type->IsRange()) { | 119 } else if (type->IsRange()) { |
| 120 bitset glb = SEMANTIC( | 120 bitset glb = SEMANTIC( |
| 121 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); | 121 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); |
| 122 return glb | REPRESENTATION(type->BitsetLub()); | 122 return glb; |
| 123 } else { | 123 } else { |
| 124 return type->Representation(); | 124 return kNone; |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 // The smallest bitset subsuming this type, possibly not a proper one. | 128 // The smallest bitset subsuming this type, possibly not a proper one. |
| 129 Type::bitset BitsetType::Lub(Type* type) { | 129 Type::bitset BitsetType::Lub(Type* type) { |
| 130 DisallowHeapAllocation no_allocation; | 130 DisallowHeapAllocation no_allocation; |
| 131 if (IsBitset(type)) return type->AsBitset(); | 131 if (IsBitset(type)) return type->AsBitset(); |
| 132 if (type->IsUnion()) { | 132 if (type->IsUnion()) { |
| 133 // Take the representation from the first element, which is always | 133 // Take the representation from the first element, which is always |
| 134 // a bitset. | 134 // a bitset. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 if (map == heap->undefined_map()) return kUndefined; | 178 if (map == heap->undefined_map()) return kUndefined; |
| 179 if (map == heap->null_map()) return kNull; | 179 if (map == heap->null_map()) return kNull; |
| 180 if (map == heap->boolean_map()) return kBoolean; | 180 if (map == heap->boolean_map()) return kBoolean; |
| 181 if (map == heap->the_hole_map()) return kHole; | 181 if (map == heap->the_hole_map()) return kHole; |
| 182 DCHECK(map == heap->uninitialized_map() || | 182 DCHECK(map == heap->uninitialized_map() || |
| 183 map == heap->no_interceptor_result_sentinel_map() || | 183 map == heap->no_interceptor_result_sentinel_map() || |
| 184 map == heap->termination_exception_map() || | 184 map == heap->termination_exception_map() || |
| 185 map == heap->arguments_marker_map() || | 185 map == heap->arguments_marker_map() || |
| 186 map == heap->optimized_out_map() || | 186 map == heap->optimized_out_map() || |
| 187 map == heap->stale_register_map()); | 187 map == heap->stale_register_map()); |
| 188 return kOtherInternal & kTaggedPointer; | 188 return kOtherInternal; |
| 189 } | 189 } |
| 190 case HEAP_NUMBER_TYPE: | 190 case HEAP_NUMBER_TYPE: |
| 191 return kNumber & kTaggedPointer; | 191 return kNumber; |
| 192 case SIMD128_VALUE_TYPE: | 192 case SIMD128_VALUE_TYPE: |
| 193 return kSimd; | 193 return kSimd; |
| 194 case JS_OBJECT_TYPE: | 194 case JS_OBJECT_TYPE: |
| 195 case JS_ARGUMENTS_TYPE: | 195 case JS_ARGUMENTS_TYPE: |
| 196 case JS_ERROR_TYPE: | 196 case JS_ERROR_TYPE: |
| 197 case JS_GLOBAL_OBJECT_TYPE: | 197 case JS_GLOBAL_OBJECT_TYPE: |
| 198 case JS_GLOBAL_PROXY_TYPE: | 198 case JS_GLOBAL_PROXY_TYPE: |
| 199 case JS_API_OBJECT_TYPE: | 199 case JS_API_OBJECT_TYPE: |
| 200 case JS_SPECIAL_API_OBJECT_TYPE: | 200 case JS_SPECIAL_API_OBJECT_TYPE: |
| 201 if (map->is_undetectable()) return kOtherUndetectable; | 201 if (map->is_undetectable()) return kOtherUndetectable; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 case FIXED_ARRAY_TYPE: | 235 case FIXED_ARRAY_TYPE: |
| 236 case FIXED_DOUBLE_ARRAY_TYPE: | 236 case FIXED_DOUBLE_ARRAY_TYPE: |
| 237 case BYTE_ARRAY_TYPE: | 237 case BYTE_ARRAY_TYPE: |
| 238 case BYTECODE_ARRAY_TYPE: | 238 case BYTECODE_ARRAY_TYPE: |
| 239 case TRANSITION_ARRAY_TYPE: | 239 case TRANSITION_ARRAY_TYPE: |
| 240 case FOREIGN_TYPE: | 240 case FOREIGN_TYPE: |
| 241 case SCRIPT_TYPE: | 241 case SCRIPT_TYPE: |
| 242 case CODE_TYPE: | 242 case CODE_TYPE: |
| 243 case PROPERTY_CELL_TYPE: | 243 case PROPERTY_CELL_TYPE: |
| 244 case MODULE_TYPE: | 244 case MODULE_TYPE: |
| 245 return kOtherInternal & kTaggedPointer; | 245 return kOtherInternal; |
| 246 | 246 |
| 247 // Remaining instance types are unsupported for now. If any of them do | 247 // Remaining instance types are unsupported for now. If any of them do |
| 248 // require bit set types, they should get kOtherInternal & kTaggedPointer. | 248 // require bit set types, they should get kOtherInternal. |
| 249 case MUTABLE_HEAP_NUMBER_TYPE: | 249 case MUTABLE_HEAP_NUMBER_TYPE: |
| 250 case FREE_SPACE_TYPE: | 250 case FREE_SPACE_TYPE: |
| 251 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 251 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 252 case FIXED_##TYPE##_ARRAY_TYPE: | 252 case FIXED_##TYPE##_ARRAY_TYPE: |
| 253 | 253 |
| 254 TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE) | 254 TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE) |
| 255 #undef FIXED_TYPED_ARRAY_CASE | 255 #undef FIXED_TYPED_ARRAY_CASE |
| 256 case FILLER_TYPE: | 256 case FILLER_TYPE: |
| 257 case ACCESS_CHECK_INFO_TYPE: | 257 case ACCESS_CHECK_INFO_TYPE: |
| 258 case INTERCEPTOR_INFO_TYPE: | 258 case INTERCEPTOR_INFO_TYPE: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 275 UNREACHABLE(); | 275 UNREACHABLE(); |
| 276 return kNone; | 276 return kNone; |
| 277 } | 277 } |
| 278 UNREACHABLE(); | 278 UNREACHABLE(); |
| 279 return kNone; | 279 return kNone; |
| 280 } | 280 } |
| 281 | 281 |
| 282 Type::bitset BitsetType::Lub(i::Object* value) { | 282 Type::bitset BitsetType::Lub(i::Object* value) { |
| 283 DisallowHeapAllocation no_allocation; | 283 DisallowHeapAllocation no_allocation; |
| 284 if (value->IsNumber()) { | 284 if (value->IsNumber()) { |
| 285 return Lub(value->Number()) & | 285 return Lub(value->Number()); |
| 286 (value->IsSmi() ? kTaggedSigned : kTaggedPointer); | |
| 287 } | 286 } |
| 288 return Lub(i::HeapObject::cast(value)->map()); | 287 return Lub(i::HeapObject::cast(value)->map()); |
| 289 } | 288 } |
| 290 | 289 |
| 291 Type::bitset BitsetType::Lub(double value) { | 290 Type::bitset BitsetType::Lub(double value) { |
| 292 DisallowHeapAllocation no_allocation; | 291 DisallowHeapAllocation no_allocation; |
| 293 if (i::IsMinusZero(value)) return kMinusZero; | 292 if (i::IsMinusZero(value)) return kMinusZero; |
| 294 if (std::isnan(value)) return kNaN; | 293 if (std::isnan(value)) return kNaN; |
| 295 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); | 294 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); |
| 296 return kOtherNumber; | 295 return kOtherNumber; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 } | 411 } |
| 413 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { | 412 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { |
| 414 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; | 413 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; |
| 415 } | 414 } |
| 416 return true; | 415 return true; |
| 417 } | 416 } |
| 418 UNREACHABLE(); | 417 UNREACHABLE(); |
| 419 return false; | 418 return false; |
| 420 } | 419 } |
| 421 | 420 |
| 422 Type::bitset Type::Representation() { | |
| 423 return REPRESENTATION(this->BitsetLub()); | |
| 424 } | |
| 425 | |
| 426 // Check if [this] <= [that]. | 421 // Check if [this] <= [that]. |
| 427 bool Type::SlowIs(Type* that) { | 422 bool Type::SlowIs(Type* that) { |
| 428 DisallowHeapAllocation no_allocation; | 423 DisallowHeapAllocation no_allocation; |
| 429 | 424 |
| 430 // Fast bitset cases | 425 // Fast bitset cases |
| 431 if (that->IsBitset()) { | 426 if (that->IsBitset()) { |
| 432 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); | 427 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); |
| 433 } | 428 } |
| 434 | 429 |
| 435 if (this->IsBitset()) { | 430 if (this->IsBitset()) { |
| 436 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | 431 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); |
| 437 } | 432 } |
| 438 | 433 |
| 439 // Check the representations. | |
| 440 if (!BitsetType::Is(Representation(), that->Representation())) { | |
| 441 return false; | |
| 442 } | |
| 443 | |
| 444 // Check the semantic part. | 434 // Check the semantic part. |
| 445 return SemanticIs(that); | 435 return SemanticIs(that); |
| 446 } | 436 } |
| 447 | 437 |
| 448 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method | 438 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method |
| 449 // should be independent of the representation axis of the types. | 439 // should be independent of the representation axis of the types. |
| 450 bool Type::SemanticIs(Type* that) { | 440 bool Type::SemanticIs(Type* that) { |
| 451 DisallowHeapAllocation no_allocation; | 441 DisallowHeapAllocation no_allocation; |
| 452 | 442 |
| 453 if (this == that) return true; | 443 if (this == that) return true; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 // Fast case: top or bottom types. | 605 // Fast case: top or bottom types. |
| 616 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. | 606 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. |
| 617 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. | 607 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. |
| 618 | 608 |
| 619 // Semi-fast case. | 609 // Semi-fast case. |
| 620 if (type1->Is(type2)) return type1; | 610 if (type1->Is(type2)) return type1; |
| 621 if (type2->Is(type1)) return type2; | 611 if (type2->Is(type1)) return type2; |
| 622 | 612 |
| 623 // Slow case: create union. | 613 // Slow case: create union. |
| 624 | 614 |
| 625 // Figure out the representation of the result first. | |
| 626 // The rest of the method should not change this representation and | |
| 627 // it should not make any decisions based on representations (i.e., | |
| 628 // it should only use the semantic part of types). | |
| 629 const bitset representation = | |
| 630 type1->Representation() & type2->Representation(); | |
| 631 | |
| 632 // Semantic subtyping check - this is needed for consistency with the | 615 // Semantic subtyping check - this is needed for consistency with the |
| 633 // semi-fast case above - we should behave the same way regardless of | 616 // semi-fast case above. |
| 634 // representations. Intersection with a universal bitset should only update | |
| 635 // the representations. | |
| 636 if (type1->SemanticIs(type2)) { | 617 if (type1->SemanticIs(type2)) { |
| 637 type2 = Any(); | 618 type2 = Any(); |
| 638 } else if (type2->SemanticIs(type1)) { | 619 } else if (type2->SemanticIs(type1)) { |
| 639 type1 = Any(); | 620 type1 = Any(); |
| 640 } | 621 } |
| 641 | 622 |
| 642 bitset bits = | 623 bitset bits = SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()); |
| 643 SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation; | |
| 644 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 624 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
| 645 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 625 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
| 646 if (!AddIsSafe(size1, size2)) return Any(); | 626 if (!AddIsSafe(size1, size2)) return Any(); |
| 647 int size = size1 + size2; | 627 int size = size1 + size2; |
| 648 if (!AddIsSafe(size, 2)) return Any(); | 628 if (!AddIsSafe(size, 2)) return Any(); |
| 649 size += 2; | 629 size += 2; |
| 650 Type* result_type = UnionType::New(size, zone); | 630 Type* result_type = UnionType::New(size, zone); |
| 651 UnionType* result = result_type->AsUnion(); | 631 UnionType* result = result_type->AsUnion(); |
| 652 size = 0; | 632 size = 0; |
| 653 | 633 |
| 654 // Deal with bitsets. | 634 // Deal with bitsets. |
| 655 result->Set(size++, BitsetType::New(bits)); | 635 result->Set(size++, BitsetType::New(bits)); |
| 656 | 636 |
| 657 RangeType::Limits lims = RangeType::Limits::Empty(); | 637 RangeType::Limits lims = RangeType::Limits::Empty(); |
| 658 size = IntersectAux(type1, type2, result, size, &lims, zone); | 638 size = IntersectAux(type1, type2, result, size, &lims, zone); |
| 659 | 639 |
| 660 // If the range is not empty, then insert it into the union and | 640 // If the range is not empty, then insert it into the union and |
| 661 // remove the number bits from the bitset. | 641 // remove the number bits from the bitset. |
| 662 if (!lims.IsEmpty()) { | 642 if (!lims.IsEmpty()) { |
| 663 size = UpdateRange(RangeType::New(lims, representation, zone), result, size, | 643 size = UpdateRange(RangeType::New(lims, zone), result, size, zone); |
| 664 zone); | |
| 665 | 644 |
| 666 // Remove the number bits. | 645 // Remove the number bits. |
| 667 bitset number_bits = BitsetType::NumberBits(bits); | 646 bitset number_bits = BitsetType::NumberBits(bits); |
| 668 bits &= ~number_bits; | 647 bits &= ~number_bits; |
| 669 result->Set(0, BitsetType::New(bits)); | 648 result->Set(0, BitsetType::New(bits)); |
| 670 } | 649 } |
| 671 return NormalizeUnion(result_type, size, zone); | 650 return NormalizeUnion(result_type, size, zone); |
| 672 } | 651 } |
| 673 | 652 |
| 674 int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) { | 653 int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 // Bitset is contained within the range, just return the range. | 778 // Bitset is contained within the range, just return the range. |
| 800 return range; | 779 return range; |
| 801 } | 780 } |
| 802 | 781 |
| 803 if (bitset_min < range_min) { | 782 if (bitset_min < range_min) { |
| 804 range_min = bitset_min; | 783 range_min = bitset_min; |
| 805 } | 784 } |
| 806 if (bitset_max > range_max) { | 785 if (bitset_max > range_max) { |
| 807 range_max = bitset_max; | 786 range_max = bitset_max; |
| 808 } | 787 } |
| 809 return RangeType::New(range_min, range_max, BitsetType::kNone, zone); | 788 return RangeType::New(range_min, range_max, zone); |
| 810 } | 789 } |
| 811 | 790 |
| 812 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { | 791 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { |
| 813 // Fast case: bit sets. | 792 // Fast case: bit sets. |
| 814 if (type1->IsBitset() && type2->IsBitset()) { | 793 if (type1->IsBitset() && type2->IsBitset()) { |
| 815 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); | 794 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); |
| 816 } | 795 } |
| 817 | 796 |
| 818 // Fast case: top or bottom types. | 797 // Fast case: top or bottom types. |
| 819 if (type1->IsAny() || type2->IsNone()) return type1; | 798 if (type1->IsAny() || type2->IsNone()) return type1; |
| 820 if (type2->IsAny() || type1->IsNone()) return type2; | 799 if (type2->IsAny() || type1->IsNone()) return type2; |
| 821 | 800 |
| 822 // Semi-fast case. | 801 // Semi-fast case. |
| 823 if (type1->Is(type2)) return type2; | 802 if (type1->Is(type2)) return type2; |
| 824 if (type2->Is(type1)) return type1; | 803 if (type2->Is(type1)) return type1; |
| 825 | 804 |
| 826 // Figure out the representation of the result. | |
| 827 // The rest of the method should not change this representation and | |
| 828 // it should not make any decisions based on representations (i.e., | |
| 829 // it should only use the semantic part of types). | |
| 830 const bitset representation = | |
| 831 type1->Representation() | type2->Representation(); | |
| 832 | |
| 833 // Slow case: create union. | 805 // Slow case: create union. |
| 834 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 806 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
| 835 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 807 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
| 836 if (!AddIsSafe(size1, size2)) return Any(); | 808 if (!AddIsSafe(size1, size2)) return Any(); |
| 837 int size = size1 + size2; | 809 int size = size1 + size2; |
| 838 if (!AddIsSafe(size, 2)) return Any(); | 810 if (!AddIsSafe(size, 2)) return Any(); |
| 839 size += 2; | 811 size += 2; |
| 840 Type* result_type = UnionType::New(size, zone); | 812 Type* result_type = UnionType::New(size, zone); |
| 841 UnionType* result = result_type->AsUnion(); | 813 UnionType* result = result_type->AsUnion(); |
| 842 size = 0; | 814 size = 0; |
| 843 | 815 |
| 844 // Compute the new bitset. | 816 // Compute the new bitset. |
| 845 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); | 817 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); |
| 846 | 818 |
| 847 // Deal with ranges. | 819 // Deal with ranges. |
| 848 Type* range = None(); | 820 Type* range = None(); |
| 849 Type* range1 = type1->GetRange(); | 821 Type* range1 = type1->GetRange(); |
| 850 Type* range2 = type2->GetRange(); | 822 Type* range2 = type2->GetRange(); |
| 851 if (range1 != NULL && range2 != NULL) { | 823 if (range1 != NULL && range2 != NULL) { |
| 852 RangeType::Limits lims = | 824 RangeType::Limits lims = |
| 853 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), | 825 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), |
| 854 RangeType::Limits(range2->AsRange())); | 826 RangeType::Limits(range2->AsRange())); |
| 855 Type* union_range = RangeType::New(lims, representation, zone); | 827 Type* union_range = RangeType::New(lims, zone); |
| 856 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); | 828 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); |
| 857 } else if (range1 != NULL) { | 829 } else if (range1 != NULL) { |
| 858 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); | 830 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); |
| 859 } else if (range2 != NULL) { | 831 } else if (range2 != NULL) { |
| 860 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); | 832 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); |
| 861 } | 833 } |
| 862 new_bitset = SEMANTIC(new_bitset) | representation; | 834 new_bitset = SEMANTIC(new_bitset); |
| 863 Type* bits = BitsetType::New(new_bitset); | 835 Type* bits = BitsetType::New(new_bitset); |
| 864 result->Set(size++, bits); | 836 result->Set(size++, bits); |
| 865 if (!range->IsNone()) result->Set(size++, range); | 837 if (!range->IsNone()) result->Set(size++, range); |
| 866 | 838 |
| 867 size = AddToUnion(type1, result, size, zone); | 839 size = AddToUnion(type1, result, size, zone); |
| 868 size = AddToUnion(type2, result, size, zone); | 840 size = AddToUnion(type2, result, size, zone); |
| 869 return NormalizeUnion(result_type, size, zone); | 841 return NormalizeUnion(result_type, size, zone); |
| 870 } | 842 } |
| 871 | 843 |
| 872 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. | 844 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 890 UnionType* unioned = union_type->AsUnion(); | 862 UnionType* unioned = union_type->AsUnion(); |
| 891 DCHECK(size >= 1); | 863 DCHECK(size >= 1); |
| 892 DCHECK(unioned->Get(0)->IsBitset()); | 864 DCHECK(unioned->Get(0)->IsBitset()); |
| 893 // If the union has just one element, return it. | 865 // If the union has just one element, return it. |
| 894 if (size == 1) { | 866 if (size == 1) { |
| 895 return unioned->Get(0); | 867 return unioned->Get(0); |
| 896 } | 868 } |
| 897 bitset bits = unioned->Get(0)->AsBitset(); | 869 bitset bits = unioned->Get(0)->AsBitset(); |
| 898 // If the union only consists of a range, we can get rid of the union. | 870 // If the union only consists of a range, we can get rid of the union. |
| 899 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) { | 871 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) { |
| 900 bitset representation = REPRESENTATION(bits); | |
| 901 if (representation == unioned->Get(1)->Representation()) { | |
| 902 return unioned->Get(1); | |
| 903 } | |
| 904 if (unioned->Get(1)->IsRange()) { | 872 if (unioned->Get(1)->IsRange()) { |
| 905 return RangeType::New(unioned->Get(1)->AsRange()->Min(), | 873 return RangeType::New(unioned->Get(1)->AsRange()->Min(), |
| 906 unioned->Get(1)->AsRange()->Max(), | 874 unioned->Get(1)->AsRange()->Max(), zone); |
| 907 unioned->Get(0)->AsBitset(), zone); | |
| 908 } | 875 } |
| 909 } | 876 } |
| 910 unioned->Shrink(size); | 877 unioned->Shrink(size); |
| 911 SLOW_DCHECK(unioned->Wellformed()); | 878 SLOW_DCHECK(unioned->Wellformed()); |
| 912 return union_type; | 879 return union_type; |
| 913 } | 880 } |
| 914 | 881 |
| 915 // ----------------------------------------------------------------------------- | 882 // ----------------------------------------------------------------------------- |
| 916 // Component extraction | 883 // Component extraction |
| 917 | 884 |
| 918 // static | 885 // static |
| 919 Type* Type::Representation(Type* t, Zone* zone) { | |
| 920 return BitsetType::New(t->Representation()); | |
| 921 } | |
| 922 | |
| 923 // static | |
| 924 Type* Type::Semantic(Type* t, Zone* zone) { | 886 Type* Type::Semantic(Type* t, Zone* zone) { |
| 925 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); | 887 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); |
| 926 } | 888 } |
| 927 | 889 |
| 928 // ----------------------------------------------------------------------------- | 890 // ----------------------------------------------------------------------------- |
| 929 // Iteration. | 891 // Iteration. |
| 930 | 892 |
| 931 int Type::NumConstants() { | 893 int Type::NumConstants() { |
| 932 DisallowHeapAllocation no_allocation; | 894 DisallowHeapAllocation no_allocation; |
| 933 if (this->IsConstant()) { | 895 if (this->IsConstant()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 return; | 949 return; |
| 988 } | 950 } |
| 989 index_ = -1; | 951 index_ = -1; |
| 990 } | 952 } |
| 991 | 953 |
| 992 // ----------------------------------------------------------------------------- | 954 // ----------------------------------------------------------------------------- |
| 993 // Printing. | 955 // Printing. |
| 994 | 956 |
| 995 const char* BitsetType::Name(bitset bits) { | 957 const char* BitsetType::Name(bitset bits) { |
| 996 switch (bits) { | 958 switch (bits) { |
| 997 case REPRESENTATION(kAny): | |
| 998 return "Any"; | |
| 999 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ | |
| 1000 case REPRESENTATION(k##type): \ | |
| 1001 return #type; | |
| 1002 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) | |
| 1003 #undef RETURN_NAMED_REPRESENTATION_TYPE | |
| 1004 | |
| 1005 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 959 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
| 1006 case SEMANTIC(k##type): \ | 960 case SEMANTIC(k##type): \ |
| 1007 return #type; | 961 return #type; |
| 1008 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 962 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 1009 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 963 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 1010 #undef RETURN_NAMED_SEMANTIC_TYPE | 964 #undef RETURN_NAMED_SEMANTIC_TYPE |
| 1011 | 965 |
| 1012 default: | 966 default: |
| 1013 return NULL; | 967 return NULL; |
| 1014 } | 968 } |
| 1015 } | 969 } |
| 1016 | 970 |
| 1017 void BitsetType::Print(std::ostream& os, // NOLINT | 971 void BitsetType::Print(std::ostream& os, // NOLINT |
| 1018 bitset bits) { | 972 bitset bits) { |
| 1019 DisallowHeapAllocation no_allocation; | 973 DisallowHeapAllocation no_allocation; |
| 1020 const char* name = Name(bits); | 974 const char* name = Name(bits); |
| 1021 if (name != NULL) { | 975 if (name != NULL) { |
| 1022 os << name; | 976 os << name; |
| 1023 return; | 977 return; |
| 1024 } | 978 } |
| 1025 | 979 |
| 1026 // clang-format off | 980 // clang-format off |
| 1027 static const bitset named_bitsets[] = { | 981 static const bitset named_bitsets[] = { |
| 1028 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), | |
| 1029 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) | |
| 1030 #undef BITSET_CONSTANT | |
| 1031 | |
| 1032 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), | 982 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), |
| 1033 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) | 983 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 1034 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 984 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 1035 #undef BITSET_CONSTANT | 985 #undef BITSET_CONSTANT |
| 1036 }; | 986 }; |
| 1037 // clang-format on | 987 // clang-format on |
| 1038 | 988 |
| 1039 bool is_first = true; | 989 bool is_first = true; |
| 1040 os << "("; | 990 os << "("; |
| 1041 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { | 991 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { |
| 1042 bitset subset = named_bitsets[i]; | 992 bitset subset = named_bitsets[i]; |
| 1043 if ((bits & subset) == subset) { | 993 if ((bits & subset) == subset) { |
| 1044 if (!is_first) os << " | "; | 994 if (!is_first) os << " | "; |
| 1045 is_first = false; | 995 is_first = false; |
| 1046 os << Name(subset); | 996 os << Name(subset); |
| 1047 bits -= subset; | 997 bits -= subset; |
| 1048 } | 998 } |
| 1049 } | 999 } |
| 1050 DCHECK(bits == 0); | 1000 DCHECK(bits == 0); |
| 1051 os << ")"; | 1001 os << ")"; |
| 1052 } | 1002 } |
| 1053 | 1003 |
| 1054 void Type::PrintTo(std::ostream& os, PrintDimension dim) { | 1004 void Type::PrintTo(std::ostream& os) { |
| 1055 DisallowHeapAllocation no_allocation; | 1005 DisallowHeapAllocation no_allocation; |
| 1056 if (dim != REPRESENTATION_DIM) { | 1006 if (this->IsBitset()) { |
| 1057 if (this->IsBitset()) { | 1007 BitsetType::Print(os, SEMANTIC(this->AsBitset())); |
| 1058 BitsetType::Print(os, SEMANTIC(this->AsBitset())); | 1008 } else if (this->IsConstant()) { |
| 1059 } else if (this->IsConstant()) { | 1009 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; |
| 1060 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; | 1010 } else if (this->IsRange()) { |
| 1061 } else if (this->IsRange()) { | 1011 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); |
| 1062 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); | 1012 std::streamsize saved_precision = os.precision(0); |
| 1063 std::streamsize saved_precision = os.precision(0); | 1013 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() |
| 1064 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() | 1014 << ")"; |
| 1065 << ")"; | 1015 os.flags(saved_flags); |
| 1066 os.flags(saved_flags); | 1016 os.precision(saved_precision); |
| 1067 os.precision(saved_precision); | 1017 } else if (this->IsUnion()) { |
| 1068 } else if (this->IsUnion()) { | 1018 os << "("; |
| 1069 os << "("; | 1019 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 1070 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 1020 Type* type_i = this->AsUnion()->Get(i); |
| 1071 Type* type_i = this->AsUnion()->Get(i); | 1021 if (i > 0) os << " | "; |
| 1072 if (i > 0) os << " | "; | 1022 type_i->PrintTo(os); |
| 1073 type_i->PrintTo(os, dim); | |
| 1074 } | |
| 1075 os << ")"; | |
| 1076 } else if (this->IsTuple()) { | |
| 1077 os << "<"; | |
| 1078 for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) { | |
| 1079 Type* type_i = this->AsTuple()->Element(i); | |
| 1080 if (i > 0) os << ", "; | |
| 1081 type_i->PrintTo(os, dim); | |
| 1082 } | |
| 1083 os << ">"; | |
| 1084 } else { | |
| 1085 UNREACHABLE(); | |
| 1086 } | 1023 } |
| 1087 } | 1024 os << ")"; |
| 1088 if (dim == BOTH_DIMS) os << "/"; | 1025 } else if (this->IsTuple()) { |
| 1089 if (dim != SEMANTIC_DIM) { | 1026 os << "<"; |
| 1090 BitsetType::Print(os, REPRESENTATION(this->BitsetLub())); | 1027 for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) { |
| 1028 Type* type_i = this->AsTuple()->Element(i); |
| 1029 if (i > 0) os << ", "; |
| 1030 type_i->PrintTo(os); |
| 1031 } |
| 1032 os << ">"; |
| 1033 } else { |
| 1034 UNREACHABLE(); |
| 1091 } | 1035 } |
| 1092 } | 1036 } |
| 1093 | 1037 |
| 1094 #ifdef DEBUG | 1038 #ifdef DEBUG |
| 1095 void Type::Print() { | 1039 void Type::Print() { |
| 1096 OFStream os(stdout); | 1040 OFStream os(stdout); |
| 1097 PrintTo(os); | 1041 PrintTo(os); |
| 1098 os << std::endl; | 1042 os << std::endl; |
| 1099 } | 1043 } |
| 1100 void BitsetType::Print(bitset bits) { | 1044 void BitsetType::Print(bitset bits) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1113 } | 1057 } |
| 1114 | 1058 |
| 1115 // ----------------------------------------------------------------------------- | 1059 // ----------------------------------------------------------------------------- |
| 1116 // Instantiations. | 1060 // Instantiations. |
| 1117 | 1061 |
| 1118 template class Type::Iterator<i::Object>; | 1062 template class Type::Iterator<i::Object>; |
| 1119 | 1063 |
| 1120 } // namespace compiler | 1064 } // namespace compiler |
| 1121 } // namespace internal | 1065 } // namespace internal |
| 1122 } // namespace v8 | 1066 } // namespace v8 |
| OLD | NEW |