| 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 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 // Return the range in [this], or [NULL]. | 509 // Return the range in [this], or [NULL]. |
| 510 Type* Type::GetRange() { | 510 Type* Type::GetRange() { |
| 511 DisallowHeapAllocation no_allocation; | 511 DisallowHeapAllocation no_allocation; |
| 512 if (this->IsRange()) return this; | 512 if (this->IsRange()) return this; |
| 513 if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) { | 513 if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) { |
| 514 return this->AsUnion()->Get(1); | 514 return this->AsUnion()->Get(1); |
| 515 } | 515 } |
| 516 return NULL; | 516 return NULL; |
| 517 } | 517 } |
| 518 | 518 |
| 519 bool Type::Contains(i::Object* value) { | |
| 520 DisallowHeapAllocation no_allocation; | |
| 521 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { | |
| 522 if (*it.Current() == value) return true; | |
| 523 } | |
| 524 if (IsInteger(value)) { | |
| 525 Type* range = this->GetRange(); | |
| 526 if (range != NULL && Contains(range->AsRange(), value)) return true; | |
| 527 } | |
| 528 return BitsetType::New(BitsetType::Lub(value))->Is(this); | |
| 529 } | |
| 530 | |
| 531 bool UnionType::Wellformed() { | 519 bool UnionType::Wellformed() { |
| 532 DisallowHeapAllocation no_allocation; | 520 DisallowHeapAllocation no_allocation; |
| 533 // This checks the invariants of the union representation: | 521 // This checks the invariants of the union representation: |
| 534 // 1. There are at least two elements. | 522 // 1. There are at least two elements. |
| 535 // 2. The first element is a bitset, no other element is a bitset. | 523 // 2. The first element is a bitset, no other element is a bitset. |
| 536 // 3. At most one element is a range, and it must be the second one. | 524 // 3. At most one element is a range, and it must be the second one. |
| 537 // 4. No element is itself a union. | 525 // 4. No element is itself a union. |
| 538 // 5. No element (except the bitset) is a subtype of any other. | 526 // 5. No element (except the bitset) is a subtype of any other. |
| 539 // 6. If there is a range, then the bitset type does not contain | 527 // 6. If there is a range, then the bitset type does not contain |
| 540 // plain number bits. | 528 // plain number bits. |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 int result = 0; | 844 int result = 0; |
| 857 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 845 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 858 if (this->AsUnion()->Get(i)->IsConstant()) ++result; | 846 if (this->AsUnion()->Get(i)->IsConstant()) ++result; |
| 859 } | 847 } |
| 860 return result; | 848 return result; |
| 861 } else { | 849 } else { |
| 862 return 0; | 850 return 0; |
| 863 } | 851 } |
| 864 } | 852 } |
| 865 | 853 |
| 866 template <class T> | |
| 867 Type* Type::Iterator<T>::get_type() { | |
| 868 DCHECK(!Done()); | |
| 869 return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_; | |
| 870 } | |
| 871 | |
| 872 // C++ cannot specialise nested templates, so we have to go through this | |
| 873 // contortion with an auxiliary template to simulate it. | |
| 874 template <class T> | |
| 875 struct TypeImplIteratorAux { | |
| 876 static bool matches(Type* type); | |
| 877 static i::Handle<T> current(Type* type); | |
| 878 }; | |
| 879 | |
| 880 template <> | |
| 881 struct TypeImplIteratorAux<i::Object> { | |
| 882 static bool matches(Type* type) { return type->IsConstant(); } | |
| 883 static i::Handle<i::Object> current(Type* type) { | |
| 884 return type->AsConstant()->Value(); | |
| 885 } | |
| 886 }; | |
| 887 | |
| 888 template <class T> | |
| 889 bool Type::Iterator<T>::matches(Type* type) { | |
| 890 return TypeImplIteratorAux<T>::matches(type); | |
| 891 } | |
| 892 | |
| 893 template <class T> | |
| 894 i::Handle<T> Type::Iterator<T>::Current() { | |
| 895 return TypeImplIteratorAux<T>::current(get_type()); | |
| 896 } | |
| 897 | |
| 898 template <class T> | |
| 899 void Type::Iterator<T>::Advance() { | |
| 900 DisallowHeapAllocation no_allocation; | |
| 901 ++index_; | |
| 902 if (type_->IsUnion()) { | |
| 903 for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) { | |
| 904 if (matches(type_->AsUnion()->Get(index_))) return; | |
| 905 } | |
| 906 } else if (index_ == 0 && matches(type_)) { | |
| 907 return; | |
| 908 } | |
| 909 index_ = -1; | |
| 910 } | |
| 911 | |
| 912 // ----------------------------------------------------------------------------- | 854 // ----------------------------------------------------------------------------- |
| 913 // Printing. | 855 // Printing. |
| 914 | 856 |
| 915 const char* BitsetType::Name(bitset bits) { | 857 const char* BitsetType::Name(bitset bits) { |
| 916 switch (bits) { | 858 switch (bits) { |
| 917 #define RETURN_NAMED_TYPE(type, value) \ | 859 #define RETURN_NAMED_TYPE(type, value) \ |
| 918 case k##type: \ | 860 case k##type: \ |
| 919 return #type; | 861 return #type; |
| 920 PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE) | 862 PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE) |
| 921 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE) | 863 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE) |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 #endif | 949 #endif |
| 1008 | 950 |
| 1009 BitsetType::bitset BitsetType::SignedSmall() { | 951 BitsetType::bitset BitsetType::SignedSmall() { |
| 1010 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; | 952 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; |
| 1011 } | 953 } |
| 1012 | 954 |
| 1013 BitsetType::bitset BitsetType::UnsignedSmall() { | 955 BitsetType::bitset BitsetType::UnsignedSmall() { |
| 1014 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; | 956 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; |
| 1015 } | 957 } |
| 1016 | 958 |
| 1017 // ----------------------------------------------------------------------------- | |
| 1018 // Instantiations. | |
| 1019 | |
| 1020 template class Type::Iterator<i::Object>; | |
| 1021 | |
| 1022 } // namespace compiler | 959 } // namespace compiler |
| 1023 } // namespace internal | 960 } // namespace internal |
| 1024 } // namespace v8 | 961 } // namespace v8 |
| OLD | NEW |