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); | 286 // TODO(mvstanton): if it's a smi can I make this SignedSmall()? |
Jarin
2016/09/22 15:27:39
No need to, Lub will take care of this.
mvstanton
2016/09/22 18:16:31
Acknowledged.
| |
287 } | 287 } |
288 return Lub(i::HeapObject::cast(value)->map()); | 288 return Lub(i::HeapObject::cast(value)->map()); |
289 } | 289 } |
290 | 290 |
291 Type::bitset BitsetType::Lub(double value) { | 291 Type::bitset BitsetType::Lub(double value) { |
292 DisallowHeapAllocation no_allocation; | 292 DisallowHeapAllocation no_allocation; |
293 if (i::IsMinusZero(value)) return kMinusZero; | 293 if (i::IsMinusZero(value)) return kMinusZero; |
294 if (std::isnan(value)) return kNaN; | 294 if (std::isnan(value)) return kNaN; |
295 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); | 295 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); |
296 return kOtherNumber; | 296 return kOtherNumber; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 } | 412 } |
413 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { | 413 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { |
414 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; | 414 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; |
415 } | 415 } |
416 return true; | 416 return true; |
417 } | 417 } |
418 UNREACHABLE(); | 418 UNREACHABLE(); |
419 return false; | 419 return false; |
420 } | 420 } |
421 | 421 |
422 Type::bitset Type::Representation() { | |
423 return REPRESENTATION(this->BitsetLub()); | |
424 } | |
425 | |
426 // Check if [this] <= [that]. | 422 // Check if [this] <= [that]. |
427 bool Type::SlowIs(Type* that) { | 423 bool Type::SlowIs(Type* that) { |
428 DisallowHeapAllocation no_allocation; | 424 DisallowHeapAllocation no_allocation; |
429 | 425 |
430 // Fast bitset cases | 426 // Fast bitset cases |
431 if (that->IsBitset()) { | 427 if (that->IsBitset()) { |
432 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); | 428 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); |
433 } | 429 } |
434 | 430 |
435 if (this->IsBitset()) { | 431 if (this->IsBitset()) { |
436 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | 432 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); |
437 } | 433 } |
438 | 434 |
439 // Check the representations. | |
440 if (!BitsetType::Is(Representation(), that->Representation())) { | |
441 return false; | |
442 } | |
443 | |
444 // Check the semantic part. | 435 // Check the semantic part. |
445 return SemanticIs(that); | 436 return SemanticIs(that); |
446 } | 437 } |
447 | 438 |
448 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method | 439 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method |
449 // should be independent of the representation axis of the types. | 440 // should be independent of the representation axis of the types. |
450 bool Type::SemanticIs(Type* that) { | 441 bool Type::SemanticIs(Type* that) { |
451 DisallowHeapAllocation no_allocation; | 442 DisallowHeapAllocation no_allocation; |
452 | 443 |
453 if (this == that) return true; | 444 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. | 606 // Fast case: top or bottom types. |
616 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. | 607 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. |
617 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. | 608 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. |
618 | 609 |
619 // Semi-fast case. | 610 // Semi-fast case. |
620 if (type1->Is(type2)) return type1; | 611 if (type1->Is(type2)) return type1; |
621 if (type2->Is(type1)) return type2; | 612 if (type2->Is(type1)) return type2; |
622 | 613 |
623 // Slow case: create union. | 614 // Slow case: create union. |
624 | 615 |
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 | 616 // Semantic subtyping check - this is needed for consistency with the |
633 // semi-fast case above - we should behave the same way regardless of | 617 // semi-fast case above. |
634 // representations. Intersection with a universal bitset should only update | |
635 // the representations. | |
636 if (type1->SemanticIs(type2)) { | 618 if (type1->SemanticIs(type2)) { |
637 type2 = Any(); | 619 type2 = Any(); |
638 } else if (type2->SemanticIs(type1)) { | 620 } else if (type2->SemanticIs(type1)) { |
639 type1 = Any(); | 621 type1 = Any(); |
640 } | 622 } |
641 | 623 |
642 bitset bits = | 624 bitset bits = SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()); |
643 SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation; | |
644 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 625 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
645 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 626 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
646 if (!AddIsSafe(size1, size2)) return Any(); | 627 if (!AddIsSafe(size1, size2)) return Any(); |
647 int size = size1 + size2; | 628 int size = size1 + size2; |
648 if (!AddIsSafe(size, 2)) return Any(); | 629 if (!AddIsSafe(size, 2)) return Any(); |
649 size += 2; | 630 size += 2; |
650 Type* result_type = UnionType::New(size, zone); | 631 Type* result_type = UnionType::New(size, zone); |
651 UnionType* result = result_type->AsUnion(); | 632 UnionType* result = result_type->AsUnion(); |
652 size = 0; | 633 size = 0; |
653 | 634 |
654 // Deal with bitsets. | 635 // Deal with bitsets. |
655 result->Set(size++, BitsetType::New(bits)); | 636 result->Set(size++, BitsetType::New(bits)); |
656 | 637 |
657 RangeType::Limits lims = RangeType::Limits::Empty(); | 638 RangeType::Limits lims = RangeType::Limits::Empty(); |
658 size = IntersectAux(type1, type2, result, size, &lims, zone); | 639 size = IntersectAux(type1, type2, result, size, &lims, zone); |
659 | 640 |
660 // If the range is not empty, then insert it into the union and | 641 // If the range is not empty, then insert it into the union and |
661 // remove the number bits from the bitset. | 642 // remove the number bits from the bitset. |
662 if (!lims.IsEmpty()) { | 643 if (!lims.IsEmpty()) { |
663 size = UpdateRange(RangeType::New(lims, representation, zone), result, size, | 644 size = UpdateRange(RangeType::New(lims, zone), result, size, zone); |
664 zone); | |
665 | 645 |
666 // Remove the number bits. | 646 // Remove the number bits. |
667 bitset number_bits = BitsetType::NumberBits(bits); | 647 bitset number_bits = BitsetType::NumberBits(bits); |
668 bits &= ~number_bits; | 648 bits &= ~number_bits; |
669 result->Set(0, BitsetType::New(bits)); | 649 result->Set(0, BitsetType::New(bits)); |
670 } | 650 } |
671 return NormalizeUnion(result_type, size, zone); | 651 return NormalizeUnion(result_type, size, zone); |
672 } | 652 } |
673 | 653 |
674 int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) { | 654 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. | 779 // Bitset is contained within the range, just return the range. |
800 return range; | 780 return range; |
801 } | 781 } |
802 | 782 |
803 if (bitset_min < range_min) { | 783 if (bitset_min < range_min) { |
804 range_min = bitset_min; | 784 range_min = bitset_min; |
805 } | 785 } |
806 if (bitset_max > range_max) { | 786 if (bitset_max > range_max) { |
807 range_max = bitset_max; | 787 range_max = bitset_max; |
808 } | 788 } |
809 return RangeType::New(range_min, range_max, BitsetType::kNone, zone); | 789 return RangeType::New(range_min, range_max, zone); |
810 } | 790 } |
811 | 791 |
812 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { | 792 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { |
813 // Fast case: bit sets. | 793 // Fast case: bit sets. |
814 if (type1->IsBitset() && type2->IsBitset()) { | 794 if (type1->IsBitset() && type2->IsBitset()) { |
815 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); | 795 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); |
816 } | 796 } |
817 | 797 |
818 // Fast case: top or bottom types. | 798 // Fast case: top or bottom types. |
819 if (type1->IsAny() || type2->IsNone()) return type1; | 799 if (type1->IsAny() || type2->IsNone()) return type1; |
820 if (type2->IsAny() || type1->IsNone()) return type2; | 800 if (type2->IsAny() || type1->IsNone()) return type2; |
821 | 801 |
822 // Semi-fast case. | 802 // Semi-fast case. |
823 if (type1->Is(type2)) return type2; | 803 if (type1->Is(type2)) return type2; |
824 if (type2->Is(type1)) return type1; | 804 if (type2->Is(type1)) return type1; |
825 | 805 |
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. | 806 // Slow case: create union. |
834 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 807 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
835 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 808 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
836 if (!AddIsSafe(size1, size2)) return Any(); | 809 if (!AddIsSafe(size1, size2)) return Any(); |
837 int size = size1 + size2; | 810 int size = size1 + size2; |
838 if (!AddIsSafe(size, 2)) return Any(); | 811 if (!AddIsSafe(size, 2)) return Any(); |
839 size += 2; | 812 size += 2; |
840 Type* result_type = UnionType::New(size, zone); | 813 Type* result_type = UnionType::New(size, zone); |
841 UnionType* result = result_type->AsUnion(); | 814 UnionType* result = result_type->AsUnion(); |
842 size = 0; | 815 size = 0; |
843 | 816 |
844 // Compute the new bitset. | 817 // Compute the new bitset. |
845 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); | 818 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); |
846 | 819 |
847 // Deal with ranges. | 820 // Deal with ranges. |
848 Type* range = None(); | 821 Type* range = None(); |
849 Type* range1 = type1->GetRange(); | 822 Type* range1 = type1->GetRange(); |
850 Type* range2 = type2->GetRange(); | 823 Type* range2 = type2->GetRange(); |
851 if (range1 != NULL && range2 != NULL) { | 824 if (range1 != NULL && range2 != NULL) { |
852 RangeType::Limits lims = | 825 RangeType::Limits lims = |
853 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), | 826 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), |
854 RangeType::Limits(range2->AsRange())); | 827 RangeType::Limits(range2->AsRange())); |
855 Type* union_range = RangeType::New(lims, representation, zone); | 828 Type* union_range = RangeType::New(lims, zone); |
856 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); | 829 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); |
857 } else if (range1 != NULL) { | 830 } else if (range1 != NULL) { |
858 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); | 831 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); |
859 } else if (range2 != NULL) { | 832 } else if (range2 != NULL) { |
860 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); | 833 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); |
861 } | 834 } |
862 new_bitset = SEMANTIC(new_bitset) | representation; | 835 new_bitset = SEMANTIC(new_bitset); |
863 Type* bits = BitsetType::New(new_bitset); | 836 Type* bits = BitsetType::New(new_bitset); |
864 result->Set(size++, bits); | 837 result->Set(size++, bits); |
865 if (!range->IsNone()) result->Set(size++, range); | 838 if (!range->IsNone()) result->Set(size++, range); |
866 | 839 |
867 size = AddToUnion(type1, result, size, zone); | 840 size = AddToUnion(type1, result, size, zone); |
868 size = AddToUnion(type2, result, size, zone); | 841 size = AddToUnion(type2, result, size, zone); |
869 return NormalizeUnion(result_type, size, zone); | 842 return NormalizeUnion(result_type, size, zone); |
870 } | 843 } |
871 | 844 |
872 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. | 845 // 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(); | 863 UnionType* unioned = union_type->AsUnion(); |
891 DCHECK(size >= 1); | 864 DCHECK(size >= 1); |
892 DCHECK(unioned->Get(0)->IsBitset()); | 865 DCHECK(unioned->Get(0)->IsBitset()); |
893 // If the union has just one element, return it. | 866 // If the union has just one element, return it. |
894 if (size == 1) { | 867 if (size == 1) { |
895 return unioned->Get(0); | 868 return unioned->Get(0); |
896 } | 869 } |
897 bitset bits = unioned->Get(0)->AsBitset(); | 870 bitset bits = unioned->Get(0)->AsBitset(); |
898 // If the union only consists of a range, we can get rid of the union. | 871 // If the union only consists of a range, we can get rid of the union. |
899 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) { | 872 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()) { | 873 if (unioned->Get(1)->IsRange()) { |
905 return RangeType::New(unioned->Get(1)->AsRange()->Min(), | 874 return RangeType::New(unioned->Get(1)->AsRange()->Min(), |
906 unioned->Get(1)->AsRange()->Max(), | 875 unioned->Get(1)->AsRange()->Max(), zone); |
907 unioned->Get(0)->AsBitset(), zone); | |
908 } | 876 } |
909 } | 877 } |
910 unioned->Shrink(size); | 878 unioned->Shrink(size); |
911 SLOW_DCHECK(unioned->Wellformed()); | 879 SLOW_DCHECK(unioned->Wellformed()); |
912 return union_type; | 880 return union_type; |
913 } | 881 } |
914 | 882 |
915 // ----------------------------------------------------------------------------- | 883 // ----------------------------------------------------------------------------- |
916 // Component extraction | 884 // Component extraction |
917 | 885 |
918 // static | 886 // 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) { | 887 Type* Type::Semantic(Type* t, Zone* zone) { |
925 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); | 888 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); |
926 } | 889 } |
927 | 890 |
928 // ----------------------------------------------------------------------------- | 891 // ----------------------------------------------------------------------------- |
929 // Iteration. | 892 // Iteration. |
930 | 893 |
931 int Type::NumConstants() { | 894 int Type::NumConstants() { |
932 DisallowHeapAllocation no_allocation; | 895 DisallowHeapAllocation no_allocation; |
933 if (this->IsConstant()) { | 896 if (this->IsConstant()) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
987 return; | 950 return; |
988 } | 951 } |
989 index_ = -1; | 952 index_ = -1; |
990 } | 953 } |
991 | 954 |
992 // ----------------------------------------------------------------------------- | 955 // ----------------------------------------------------------------------------- |
993 // Printing. | 956 // Printing. |
994 | 957 |
995 const char* BitsetType::Name(bitset bits) { | 958 const char* BitsetType::Name(bitset bits) { |
996 switch (bits) { | 959 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) \ | 960 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
1006 case SEMANTIC(k##type): \ | 961 case SEMANTIC(k##type): \ |
1007 return #type; | 962 return #type; |
1008 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 963 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
1009 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 964 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
1010 #undef RETURN_NAMED_SEMANTIC_TYPE | 965 #undef RETURN_NAMED_SEMANTIC_TYPE |
1011 | 966 |
1012 default: | 967 default: |
1013 return NULL; | 968 return NULL; |
1014 } | 969 } |
1015 } | 970 } |
1016 | 971 |
1017 void BitsetType::Print(std::ostream& os, // NOLINT | 972 void BitsetType::Print(std::ostream& os, // NOLINT |
1018 bitset bits) { | 973 bitset bits) { |
1019 DisallowHeapAllocation no_allocation; | 974 DisallowHeapAllocation no_allocation; |
1020 const char* name = Name(bits); | 975 const char* name = Name(bits); |
1021 if (name != NULL) { | 976 if (name != NULL) { |
1022 os << name; | 977 os << name; |
1023 return; | 978 return; |
1024 } | 979 } |
1025 | 980 |
1026 // clang-format off | 981 // clang-format off |
1027 static const bitset named_bitsets[] = { | 982 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), | 983 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), |
1033 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) | 984 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) |
1034 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 985 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) |
1035 #undef BITSET_CONSTANT | 986 #undef BITSET_CONSTANT |
1036 }; | 987 }; |
1037 // clang-format on | 988 // clang-format on |
1038 | 989 |
1039 bool is_first = true; | 990 bool is_first = true; |
1040 os << "("; | 991 os << "("; |
1041 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { | 992 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { |
1042 bitset subset = named_bitsets[i]; | 993 bitset subset = named_bitsets[i]; |
1043 if ((bits & subset) == subset) { | 994 if ((bits & subset) == subset) { |
1044 if (!is_first) os << " | "; | 995 if (!is_first) os << " | "; |
1045 is_first = false; | 996 is_first = false; |
1046 os << Name(subset); | 997 os << Name(subset); |
1047 bits -= subset; | 998 bits -= subset; |
1048 } | 999 } |
1049 } | 1000 } |
1050 DCHECK(bits == 0); | 1001 DCHECK(bits == 0); |
1051 os << ")"; | 1002 os << ")"; |
1052 } | 1003 } |
1053 | 1004 |
1054 void Type::PrintTo(std::ostream& os, PrintDimension dim) { | 1005 void Type::PrintTo(std::ostream& os) { |
1055 DisallowHeapAllocation no_allocation; | 1006 DisallowHeapAllocation no_allocation; |
1056 if (dim != REPRESENTATION_DIM) { | 1007 if (this->IsBitset()) { |
1057 if (this->IsBitset()) { | 1008 BitsetType::Print(os, SEMANTIC(this->AsBitset())); |
1058 BitsetType::Print(os, SEMANTIC(this->AsBitset())); | 1009 } else if (this->IsConstant()) { |
1059 } else if (this->IsConstant()) { | 1010 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; |
1060 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; | 1011 } else if (this->IsRange()) { |
1061 } else if (this->IsRange()) { | 1012 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); |
1062 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); | 1013 std::streamsize saved_precision = os.precision(0); |
1063 std::streamsize saved_precision = os.precision(0); | 1014 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() |
1064 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() | 1015 << ")"; |
1065 << ")"; | 1016 os.flags(saved_flags); |
1066 os.flags(saved_flags); | 1017 os.precision(saved_precision); |
1067 os.precision(saved_precision); | 1018 } else if (this->IsUnion()) { |
1068 } else if (this->IsUnion()) { | 1019 os << "("; |
1069 os << "("; | 1020 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
1070 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 1021 Type* type_i = this->AsUnion()->Get(i); |
1071 Type* type_i = this->AsUnion()->Get(i); | 1022 if (i > 0) os << " | "; |
1072 if (i > 0) os << " | "; | 1023 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 } | 1024 } |
1087 } | 1025 os << ")"; |
1088 if (dim == BOTH_DIMS) os << "/"; | 1026 } else if (this->IsTuple()) { |
1089 if (dim != SEMANTIC_DIM) { | 1027 os << "<"; |
1090 BitsetType::Print(os, REPRESENTATION(this->BitsetLub())); | 1028 for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) { |
1029 Type* type_i = this->AsTuple()->Element(i); | |
1030 if (i > 0) os << ", "; | |
1031 type_i->PrintTo(os); | |
1032 } | |
1033 os << ">"; | |
1034 } else { | |
1035 UNREACHABLE(); | |
1091 } | 1036 } |
1092 } | 1037 } |
1093 | 1038 |
1094 #ifdef DEBUG | 1039 #ifdef DEBUG |
1095 void Type::Print() { | 1040 void Type::Print() { |
1096 OFStream os(stdout); | 1041 OFStream os(stdout); |
1097 PrintTo(os); | 1042 PrintTo(os); |
1098 os << std::endl; | 1043 os << std::endl; |
1099 } | 1044 } |
1100 void BitsetType::Print(bitset bits) { | 1045 void BitsetType::Print(bitset bits) { |
(...skipping 12 matching lines...) Expand all Loading... | |
1113 } | 1058 } |
1114 | 1059 |
1115 // ----------------------------------------------------------------------------- | 1060 // ----------------------------------------------------------------------------- |
1116 // Instantiations. | 1061 // Instantiations. |
1117 | 1062 |
1118 template class Type::Iterator<i::Object>; | 1063 template class Type::Iterator<i::Object>; |
1119 | 1064 |
1120 } // namespace compiler | 1065 } // namespace compiler |
1121 } // namespace internal | 1066 } // namespace internal |
1122 } // namespace v8 | 1067 } // namespace v8 |
OLD | NEW |