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 |