Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/types.cc

Issue 2309753002: [turbofan] Nuke class types. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/types.h ('k') | test/cctest/ast-types-fuzz.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/types.h" 7 #include "src/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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 if (type->IsUnion()) { 137 if (type->IsUnion()) {
138 // Take the representation from the first element, which is always 138 // Take the representation from the first element, which is always
139 // a bitset. 139 // a bitset.
140 int bitset = type->AsUnion()->Get(0)->BitsetLub(); 140 int bitset = type->AsUnion()->Get(0)->BitsetLub();
141 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { 141 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
142 // Other elements only contribute their semantic part. 142 // Other elements only contribute their semantic part.
143 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub()); 143 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub());
144 } 144 }
145 return bitset; 145 return bitset;
146 } 146 }
147 if (type->IsClass()) return type->AsClass()->Lub();
148 if (type->IsConstant()) return type->AsConstant()->Lub(); 147 if (type->IsConstant()) return type->AsConstant()->Lub();
149 if (type->IsRange()) return type->AsRange()->Lub(); 148 if (type->IsRange()) return type->AsRange()->Lub();
150 if (type->IsContext()) return kOtherInternal & kTaggedPointer; 149 if (type->IsContext()) return kOtherInternal & kTaggedPointer;
151 if (type->IsArray()) return kOtherObject; 150 if (type->IsArray()) return kOtherObject;
152 if (type->IsFunction()) return kFunction; 151 if (type->IsFunction()) return kFunction;
153 if (type->IsTuple()) return kOtherInternal; 152 if (type->IsTuple()) return kOtherInternal;
154 UNREACHABLE(); 153 UNREACHABLE();
155 return kNone; 154 return kNone;
156 } 155 }
157 156
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (mz) return 0; 401 if (mz) return 0;
403 return std::numeric_limits<double>::quiet_NaN(); 402 return std::numeric_limits<double>::quiet_NaN();
404 } 403 }
405 404
406 405
407 // ----------------------------------------------------------------------------- 406 // -----------------------------------------------------------------------------
408 // Predicates. 407 // Predicates.
409 408
410 bool Type::SimplyEquals(Type* that) { 409 bool Type::SimplyEquals(Type* that) {
411 DisallowHeapAllocation no_allocation; 410 DisallowHeapAllocation no_allocation;
412 if (this->IsClass()) {
413 return that->IsClass()
414 && *this->AsClass()->Map() == *that->AsClass()->Map();
415 }
416 if (this->IsConstant()) { 411 if (this->IsConstant()) {
417 return that->IsConstant() 412 return that->IsConstant()
418 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); 413 && *this->AsConstant()->Value() == *that->AsConstant()->Value();
419 } 414 }
420 if (this->IsContext()) { 415 if (this->IsContext()) {
421 return that->IsContext() 416 return that->IsContext()
422 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer()); 417 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer());
423 } 418 }
424 if (this->IsArray()) { 419 if (this->IsArray()) {
425 return that->IsArray() 420 return that->IsArray()
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if (that->IsRange()) { 512 if (that->IsRange()) {
518 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || 513 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) ||
519 (this->IsConstant() && 514 (this->IsConstant() &&
520 Contains(that->AsRange(), this->AsConstant())); 515 Contains(that->AsRange(), this->AsConstant()));
521 } 516 }
522 if (this->IsRange()) return false; 517 if (this->IsRange()) return false;
523 518
524 return this->SimplyEquals(that); 519 return this->SimplyEquals(that);
525 } 520 }
526 521
527 // Most precise _current_ type of a value (usually its class).
528 Type* Type::NowOf(i::Object* value, Zone* zone) {
529 if (value->IsSmi() ||
530 i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
531 return Of(value, zone);
532 }
533 return Class(i::handle(i::HeapObject::cast(value)->map()), zone);
534 }
535
536 bool Type::NowContains(i::Object* value) {
537 DisallowHeapAllocation no_allocation;
538 if (this->IsAny()) return true;
539 if (value->IsHeapObject()) {
540 i::Map* map = i::HeapObject::cast(value)->map();
541 for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
542 if (*it.Current() == map) return true;
543 }
544 }
545 return this->Contains(value);
546 }
547
548 bool Type::NowIs(Type* that) {
549 DisallowHeapAllocation no_allocation;
550
551 // TODO(rossberg): this is incorrect for
552 // Union(Constant(V), T)->NowIs(Class(M))
553 // but fuzzing does not cover that!
554 if (this->IsConstant()) {
555 i::Object* object = *this->AsConstant()->Value();
556 if (object->IsHeapObject()) {
557 i::Map* map = i::HeapObject::cast(object)->map();
558 for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
559 if (*it.Current() == map) return true;
560 }
561 }
562 }
563 return this->Is(that);
564 }
565
566
567 // Check if [this] contains only (currently) stable classes.
568 bool Type::NowStable() {
569 DisallowHeapAllocation no_allocation;
570 return !this->IsClass() || this->AsClass()->Map()->is_stable();
571 }
572
573 522
574 // Check if [this] and [that] overlap. 523 // Check if [this] and [that] overlap.
575 bool Type::Maybe(Type* that) { 524 bool Type::Maybe(Type* that) {
576 DisallowHeapAllocation no_allocation; 525 DisallowHeapAllocation no_allocation;
577 526
578 // Take care of the representation part (and also approximate 527 // Take care of the representation part (and also approximate
579 // the semantic part). 528 // the semantic part).
580 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) 529 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
581 return false; 530 return false;
582 531
(...skipping 17 matching lines...) Expand all
600 if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true; 549 if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true;
601 } 550 }
602 return false; 551 return false;
603 } 552 }
604 553
605 if (!BitsetType::SemanticIsInhabited(this->BitsetLub() & that->BitsetLub())) 554 if (!BitsetType::SemanticIsInhabited(this->BitsetLub() & that->BitsetLub()))
606 return false; 555 return false;
607 556
608 if (this->IsBitset() && that->IsBitset()) return true; 557 if (this->IsBitset() && that->IsBitset()) return true;
609 558
610 if (this->IsClass() != that->IsClass()) return true;
611
612 if (this->IsRange()) { 559 if (this->IsRange()) {
613 if (that->IsConstant()) { 560 if (that->IsConstant()) {
614 return Contains(this->AsRange(), that->AsConstant()); 561 return Contains(this->AsRange(), that->AsConstant());
615 } 562 }
616 if (that->IsRange()) { 563 if (that->IsRange()) {
617 return Overlap(this->AsRange(), that->AsRange()); 564 return Overlap(this->AsRange(), that->AsRange());
618 } 565 }
619 if (that->IsBitset()) { 566 if (that->IsBitset()) {
620 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); 567 bitset number_bits = BitsetType::NumberBits(that->AsBitset());
621 if (number_bits == BitsetType::kNone) { 568 if (number_bits == BitsetType::kNone) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 770
824 if (lhs->IsRange()) { 771 if (lhs->IsRange()) {
825 if (rhs->IsBitset()) { 772 if (rhs->IsBitset()) {
826 RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone); 773 RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
827 774
828 if (!lim.IsEmpty()) { 775 if (!lim.IsEmpty()) {
829 *lims = RangeType::Limits::Union(lim, *lims); 776 *lims = RangeType::Limits::Union(lim, *lims);
830 } 777 }
831 return size; 778 return size;
832 } 779 }
833 if (rhs->IsClass()) {
834 *lims =
835 RangeType::Limits::Union(RangeType::Limits(lhs->AsRange()), *lims);
836 }
837 if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) { 780 if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
838 return AddToUnion(rhs, result, size, zone); 781 return AddToUnion(rhs, result, size, zone);
839 } 782 }
840 if (rhs->IsRange()) { 783 if (rhs->IsRange()) {
841 RangeType::Limits lim = RangeType::Limits::Intersect( 784 RangeType::Limits lim = RangeType::Limits::Intersect(
842 RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange())); 785 RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
843 if (!lim.IsEmpty()) { 786 if (!lim.IsEmpty()) {
844 *lims = RangeType::Limits::Union(lim, *lims); 787 *lims = RangeType::Limits::Union(lim, *lims);
845 } 788 }
846 } 789 }
847 return size; 790 return size;
848 } 791 }
849 if (rhs->IsRange()) { 792 if (rhs->IsRange()) {
850 // This case is handled symmetrically above. 793 // This case is handled symmetrically above.
851 return IntersectAux(rhs, lhs, result, size, lims, zone); 794 return IntersectAux(rhs, lhs, result, size, lims, zone);
852 } 795 }
853 if (lhs->IsBitset() || rhs->IsBitset()) { 796 if (lhs->IsBitset() || rhs->IsBitset()) {
854 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone); 797 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
855 } 798 }
856 if (lhs->IsClass() != rhs->IsClass()) {
857 return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, zone);
858 }
859 if (lhs->SimplyEquals(rhs)) { 799 if (lhs->SimplyEquals(rhs)) {
860 return AddToUnion(lhs, result, size, zone); 800 return AddToUnion(lhs, result, size, zone);
861 } 801 }
862 return size; 802 return size;
863 } 803 }
864 804
865 805
866 // Make sure that we produce a well-formed range and bitset: 806 // Make sure that we produce a well-formed range and bitset:
867 // If the range is non-empty, the number bits in the bitset should be 807 // If the range is non-empty, the number bits in the bitset should be
868 // clear. Moreover, if we have a canonical range (such as Signed32), 808 // clear. Moreover, if we have a canonical range (such as Signed32),
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 964
1025 // static 965 // static
1026 Type* Type::Semantic(Type* t, Zone* zone) { 966 Type* Type::Semantic(Type* t, Zone* zone) {
1027 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); 967 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone);
1028 } 968 }
1029 969
1030 970
1031 // ----------------------------------------------------------------------------- 971 // -----------------------------------------------------------------------------
1032 // Iteration. 972 // Iteration.
1033 973
1034 int Type::NumClasses() {
1035 DisallowHeapAllocation no_allocation;
1036 if (this->IsClass()) {
1037 return 1;
1038 } else if (this->IsUnion()) {
1039 int result = 0;
1040 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1041 if (this->AsUnion()->Get(i)->IsClass()) ++result;
1042 }
1043 return result;
1044 } else {
1045 return 0;
1046 }
1047 }
1048
1049 int Type::NumConstants() { 974 int Type::NumConstants() {
1050 DisallowHeapAllocation no_allocation; 975 DisallowHeapAllocation no_allocation;
1051 if (this->IsConstant()) { 976 if (this->IsConstant()) {
1052 return 1; 977 return 1;
1053 } else if (this->IsUnion()) { 978 } else if (this->IsUnion()) {
1054 int result = 0; 979 int result = 0;
1055 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 980 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1056 if (this->AsUnion()->Get(i)->IsConstant()) ++result; 981 if (this->AsUnion()->Get(i)->IsConstant()) ++result;
1057 } 982 }
1058 return result; 983 return result;
(...skipping 11 matching lines...) Expand all
1070 995
1071 // C++ cannot specialise nested templates, so we have to go through this 996 // C++ cannot specialise nested templates, so we have to go through this
1072 // contortion with an auxiliary template to simulate it. 997 // contortion with an auxiliary template to simulate it.
1073 template <class T> 998 template <class T>
1074 struct TypeImplIteratorAux { 999 struct TypeImplIteratorAux {
1075 static bool matches(Type* type); 1000 static bool matches(Type* type);
1076 static i::Handle<T> current(Type* type); 1001 static i::Handle<T> current(Type* type);
1077 }; 1002 };
1078 1003
1079 template <> 1004 template <>
1080 struct TypeImplIteratorAux<i::Map> {
1081 static bool matches(Type* type) { return type->IsClass(); }
1082 static i::Handle<i::Map> current(Type* type) {
1083 return type->AsClass()->Map();
1084 }
1085 };
1086
1087 template <>
1088 struct TypeImplIteratorAux<i::Object> { 1005 struct TypeImplIteratorAux<i::Object> {
1089 static bool matches(Type* type) { return type->IsConstant(); } 1006 static bool matches(Type* type) { return type->IsConstant(); }
1090 static i::Handle<i::Object> current(Type* type) { 1007 static i::Handle<i::Object> current(Type* type) {
1091 return type->AsConstant()->Value(); 1008 return type->AsConstant()->Value();
1092 } 1009 }
1093 }; 1010 };
1094 1011
1095 template <class T> 1012 template <class T>
1096 bool Type::Iterator<T>::matches(Type* type) { 1013 bool Type::Iterator<T>::matches(Type* type) {
1097 return TypeImplIteratorAux<T>::matches(type); 1014 return TypeImplIteratorAux<T>::matches(type);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 } 1091 }
1175 DCHECK(bits == 0); 1092 DCHECK(bits == 0);
1176 os << ")"; 1093 os << ")";
1177 } 1094 }
1178 1095
1179 void Type::PrintTo(std::ostream& os, PrintDimension dim) { 1096 void Type::PrintTo(std::ostream& os, PrintDimension dim) {
1180 DisallowHeapAllocation no_allocation; 1097 DisallowHeapAllocation no_allocation;
1181 if (dim != REPRESENTATION_DIM) { 1098 if (dim != REPRESENTATION_DIM) {
1182 if (this->IsBitset()) { 1099 if (this->IsBitset()) {
1183 BitsetType::Print(os, SEMANTIC(this->AsBitset())); 1100 BitsetType::Print(os, SEMANTIC(this->AsBitset()));
1184 } else if (this->IsClass()) {
1185 os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < ";
1186 BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
1187 os << ")";
1188 } else if (this->IsConstant()) { 1101 } else if (this->IsConstant()) {
1189 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; 1102 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
1190 } else if (this->IsRange()) { 1103 } else if (this->IsRange()) {
1191 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); 1104 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1192 std::streamsize saved_precision = os.precision(0); 1105 std::streamsize saved_precision = os.precision(0);
1193 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() 1106 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1194 << ")"; 1107 << ")";
1195 os.flags(saved_flags); 1108 os.flags(saved_flags);
1196 os.precision(saved_precision); 1109 os.precision(saved_precision);
1197 } else if (this->IsContext()) { 1110 } else if (this->IsContext()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 #endif 1168 #endif
1256 1169
1257 BitsetType::bitset BitsetType::SignedSmall() { 1170 BitsetType::bitset BitsetType::SignedSmall() {
1258 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; 1171 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1259 } 1172 }
1260 1173
1261 BitsetType::bitset BitsetType::UnsignedSmall() { 1174 BitsetType::bitset BitsetType::UnsignedSmall() {
1262 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; 1175 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1263 } 1176 }
1264 1177
1265 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
1266 Type* Type::Name(Isolate* isolate, Zone* zone) { \
1267 return Class(i::handle(isolate->heap()->name##_map()), zone); \
1268 }
1269 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
1270 #undef CONSTRUCT_SIMD_TYPE
1271
1272 // ----------------------------------------------------------------------------- 1178 // -----------------------------------------------------------------------------
1273 // Instantiations. 1179 // Instantiations.
1274 1180
1275 template class Type::Iterator<i::Map>;
1276 template class Type::Iterator<i::Object>; 1181 template class Type::Iterator<i::Object>;
1277 1182
1278 } // namespace internal 1183 } // namespace internal
1279 } // namespace v8 1184 } // namespace v8
OLDNEW
« no previous file with comments | « src/types.h ('k') | test/cctest/ast-types-fuzz.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698