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 #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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 DCHECK(this->Is(Number())); | 75 DCHECK(this->Is(Number())); |
| 76 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); | 76 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); |
| 77 if (this->IsUnion()) { | 77 if (this->IsUnion()) { |
| 78 double min = +V8_INFINITY; | 78 double min = +V8_INFINITY; |
| 79 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 79 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 80 min = std::min(min, this->AsUnion()->Get(i)->Min()); | 80 min = std::min(min, this->AsUnion()->Get(i)->Min()); |
| 81 } | 81 } |
| 82 return min; | 82 return min; |
| 83 } | 83 } |
| 84 if (this->IsRange()) return this->AsRange()->Min(); | 84 if (this->IsRange()) return this->AsRange()->Min(); |
| 85 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 85 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
|
Jarin
2016/10/04 13:14:55
Remove this line, please (Constants should be only
mvstanton
2016/10/05 13:51:10
Done.
| |
| 86 if (this->IsOtherNumberConstant()) | |
| 87 return this->AsOtherNumberConstant()->Value(); | |
| 86 UNREACHABLE(); | 88 UNREACHABLE(); |
| 87 return 0; | 89 return 0; |
| 88 } | 90 } |
| 89 | 91 |
| 90 double Type::Max() { | 92 double Type::Max() { |
| 91 DCHECK(this->Is(Number())); | 93 DCHECK(this->Is(Number())); |
| 92 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); | 94 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); |
| 93 if (this->IsUnion()) { | 95 if (this->IsUnion()) { |
| 94 double max = -V8_INFINITY; | 96 double max = -V8_INFINITY; |
| 95 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 97 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 96 max = std::max(max, this->AsUnion()->Get(i)->Max()); | 98 max = std::max(max, this->AsUnion()->Get(i)->Max()); |
| 97 } | 99 } |
| 98 return max; | 100 return max; |
| 99 } | 101 } |
| 100 if (this->IsRange()) return this->AsRange()->Max(); | 102 if (this->IsRange()) return this->AsRange()->Max(); |
| 101 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 103 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
|
Jarin
2016/10/04 13:14:55
Remove.
mvstanton
2016/10/05 13:51:10
Done.
| |
| 104 if (this->IsOtherNumberConstant()) | |
| 105 return this->AsOtherNumberConstant()->Value(); | |
| 102 UNREACHABLE(); | 106 UNREACHABLE(); |
| 103 return 0; | 107 return 0; |
| 104 } | 108 } |
| 105 | 109 |
| 106 // ----------------------------------------------------------------------------- | 110 // ----------------------------------------------------------------------------- |
| 107 // Glb and lub computation. | 111 // Glb and lub computation. |
| 108 | 112 |
| 109 // The largest bitset subsumed by this type. | 113 // The largest bitset subsumed by this type. |
| 110 Type::bitset BitsetType::Glb(Type* type) { | 114 Type::bitset BitsetType::Glb(Type* type) { |
| 111 DisallowHeapAllocation no_allocation; | 115 DisallowHeapAllocation no_allocation; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 133 // Take the representation from the first element, which is always | 137 // Take the representation from the first element, which is always |
| 134 // a bitset. | 138 // a bitset. |
| 135 int bitset = type->AsUnion()->Get(0)->BitsetLub(); | 139 int bitset = type->AsUnion()->Get(0)->BitsetLub(); |
| 136 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 140 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
| 137 // Other elements only contribute their semantic part. | 141 // Other elements only contribute their semantic part. |
| 138 bitset |= type->AsUnion()->Get(i)->BitsetLub(); | 142 bitset |= type->AsUnion()->Get(i)->BitsetLub(); |
| 139 } | 143 } |
| 140 return bitset; | 144 return bitset; |
| 141 } | 145 } |
| 142 if (type->IsConstant()) return type->AsConstant()->Lub(); | 146 if (type->IsConstant()) return type->AsConstant()->Lub(); |
| 147 if (type->IsOtherNumberConstant()) | |
| 148 return type->AsOtherNumberConstant()->Lub(); | |
| 143 if (type->IsRange()) return type->AsRange()->Lub(); | 149 if (type->IsRange()) return type->AsRange()->Lub(); |
| 144 if (type->IsTuple()) return kOtherInternal; | 150 if (type->IsTuple()) return kOtherInternal; |
| 145 UNREACHABLE(); | 151 UNREACHABLE(); |
| 146 return kNone; | 152 return kNone; |
| 147 } | 153 } |
| 148 | 154 |
| 149 Type::bitset BitsetType::Lub(i::Map* map) { | 155 Type::bitset BitsetType::Lub(i::Map* map) { |
| 150 DisallowHeapAllocation no_allocation; | 156 DisallowHeapAllocation no_allocation; |
| 151 switch (map->instance_type()) { | 157 switch (map->instance_type()) { |
| 152 case STRING_TYPE: | 158 case STRING_TYPE: |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 | 398 |
| 393 // ----------------------------------------------------------------------------- | 399 // ----------------------------------------------------------------------------- |
| 394 // Predicates. | 400 // Predicates. |
| 395 | 401 |
| 396 bool Type::SimplyEquals(Type* that) { | 402 bool Type::SimplyEquals(Type* that) { |
| 397 DisallowHeapAllocation no_allocation; | 403 DisallowHeapAllocation no_allocation; |
| 398 if (this->IsConstant()) { | 404 if (this->IsConstant()) { |
| 399 return that->IsConstant() && | 405 return that->IsConstant() && |
| 400 *this->AsConstant()->Value() == *that->AsConstant()->Value(); | 406 *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
| 401 } | 407 } |
| 408 if (this->IsOtherNumberConstant()) { | |
| 409 return that->IsOtherNumberConstant() && | |
| 410 this->AsOtherNumberConstant()->Value() == | |
| 411 that->AsOtherNumberConstant()->Value(); | |
| 412 } | |
| 413 if (this->IsRange()) { | |
| 414 if (that->IsOtherNumberConstant()) return false; | |
| 415 } | |
| 402 if (this->IsTuple()) { | 416 if (this->IsTuple()) { |
| 403 if (!that->IsTuple()) return false; | 417 if (!that->IsTuple()) return false; |
| 404 TupleType* this_tuple = this->AsTuple(); | 418 TupleType* this_tuple = this->AsTuple(); |
| 405 TupleType* that_tuple = that->AsTuple(); | 419 TupleType* that_tuple = that->AsTuple(); |
| 406 if (this_tuple->Arity() != that_tuple->Arity()) { | 420 if (this_tuple->Arity() != that_tuple->Arity()) { |
| 407 return false; | 421 return false; |
| 408 } | 422 } |
| 409 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { | 423 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { |
| 410 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; | 424 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; |
| 411 } | 425 } |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 736 | 750 |
| 737 if (bitset_min < range_min) { | 751 if (bitset_min < range_min) { |
| 738 range_min = bitset_min; | 752 range_min = bitset_min; |
| 739 } | 753 } |
| 740 if (bitset_max > range_max) { | 754 if (bitset_max > range_max) { |
| 741 range_max = bitset_max; | 755 range_max = bitset_max; |
| 742 } | 756 } |
| 743 return RangeType::New(range_min, range_max, zone); | 757 return RangeType::New(range_min, range_max, zone); |
| 744 } | 758 } |
| 745 | 759 |
| 760 Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) { | |
| 761 if (IsInteger(*value)) { | |
| 762 double v = value->IsSmi() ? Smi::cast(*value)->value() | |
| 763 : HeapNumber::cast(*value)->value(); | |
| 764 return Range(v, v, zone); | |
| 765 } else if (value->IsHeapNumber()) { | |
| 766 double v = HeapNumber::cast(*value)->value(); | |
| 767 if (i::IsMinusZero(v)) { | |
| 768 return Type::MinusZero(); | |
| 769 } else if (std::isnan(v)) { | |
| 770 return Type::NaN(); | |
| 771 } else if (OtherNumberConstantType::IsOtherNumberConstant(v)) { | |
| 772 return OtherNumberConstant(v, zone); | |
| 773 } | |
| 774 } | |
| 775 return Constant(value, zone); | |
| 776 } | |
| 777 | |
| 746 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { | 778 Type* Type::Union(Type* type1, Type* type2, Zone* zone) { |
| 747 // Fast case: bit sets. | 779 // Fast case: bit sets. |
| 748 if (type1->IsBitset() && type2->IsBitset()) { | 780 if (type1->IsBitset() && type2->IsBitset()) { |
| 749 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); | 781 return BitsetType::New(type1->AsBitset() | type2->AsBitset()); |
| 750 } | 782 } |
| 751 | 783 |
| 752 // Fast case: top or bottom types. | 784 // Fast case: top or bottom types. |
| 753 if (type1->IsAny() || type2->IsNone()) return type1; | 785 if (type1->IsAny() || type2->IsNone()) return type1; |
| 754 if (type2->IsAny() || type1->IsNone()) return type2; | 786 if (type2->IsAny() || type1->IsNone()) return type2; |
| 755 | 787 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 if (unioned->Get(1)->IsRange()) { | 858 if (unioned->Get(1)->IsRange()) { |
| 827 return RangeType::New(unioned->Get(1)->AsRange()->Min(), | 859 return RangeType::New(unioned->Get(1)->AsRange()->Min(), |
| 828 unioned->Get(1)->AsRange()->Max(), zone); | 860 unioned->Get(1)->AsRange()->Max(), zone); |
| 829 } | 861 } |
| 830 } | 862 } |
| 831 unioned->Shrink(size); | 863 unioned->Shrink(size); |
| 832 SLOW_DCHECK(unioned->Wellformed()); | 864 SLOW_DCHECK(unioned->Wellformed()); |
| 833 return union_type; | 865 return union_type; |
| 834 } | 866 } |
| 835 | 867 |
| 836 // ----------------------------------------------------------------------------- | |
| 837 // Iteration. | |
| 838 | |
| 839 int Type::NumConstants() { | 868 int Type::NumConstants() { |
| 840 DisallowHeapAllocation no_allocation; | 869 DisallowHeapAllocation no_allocation; |
| 841 if (this->IsConstant()) { | 870 if (this->IsConstant() || this->IsOtherNumberConstant()) { |
| 842 return 1; | 871 return 1; |
| 843 } else if (this->IsUnion()) { | 872 } else if (this->IsUnion()) { |
| 844 int result = 0; | 873 int result = 0; |
| 845 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 874 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 846 if (this->AsUnion()->Get(i)->IsConstant()) ++result; | 875 if (this->AsUnion()->Get(i)->IsConstant()) ++result; |
| 847 } | 876 } |
| 848 return result; | 877 return result; |
| 849 } else { | 878 } else { |
| 850 return 0; | 879 return 0; |
| 851 } | 880 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 900 DCHECK(bits == 0); | 929 DCHECK(bits == 0); |
| 901 os << ")"; | 930 os << ")"; |
| 902 } | 931 } |
| 903 | 932 |
| 904 void Type::PrintTo(std::ostream& os) { | 933 void Type::PrintTo(std::ostream& os) { |
| 905 DisallowHeapAllocation no_allocation; | 934 DisallowHeapAllocation no_allocation; |
| 906 if (this->IsBitset()) { | 935 if (this->IsBitset()) { |
| 907 BitsetType::Print(os, this->AsBitset()); | 936 BitsetType::Print(os, this->AsBitset()); |
| 908 } else if (this->IsConstant()) { | 937 } else if (this->IsConstant()) { |
| 909 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; | 938 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; |
| 939 } else if (this->IsOtherNumberConstant()) { | |
| 940 os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value() | |
| 941 << ")"; | |
| 910 } else if (this->IsRange()) { | 942 } else if (this->IsRange()) { |
| 911 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); | 943 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); |
| 912 std::streamsize saved_precision = os.precision(0); | 944 std::streamsize saved_precision = os.precision(0); |
| 913 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() | 945 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() |
| 914 << ")"; | 946 << ")"; |
| 915 os.flags(saved_flags); | 947 os.flags(saved_flags); |
| 916 os.precision(saved_precision); | 948 os.precision(saved_precision); |
| 917 } else if (this->IsUnion()) { | 949 } else if (this->IsUnion()) { |
| 918 os << "("; | 950 os << "("; |
| 919 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 951 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; | 984 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; |
| 953 } | 985 } |
| 954 | 986 |
| 955 BitsetType::bitset BitsetType::UnsignedSmall() { | 987 BitsetType::bitset BitsetType::UnsignedSmall() { |
| 956 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; | 988 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; |
| 957 } | 989 } |
| 958 | 990 |
| 959 } // namespace compiler | 991 } // namespace compiler |
| 960 } // namespace internal | 992 } // namespace internal |
| 961 } // namespace v8 | 993 } // namespace v8 |
| OLD | NEW |