| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "src/hydrogen-types.h" | 7 #include "src/hydrogen-types.h" |
| 8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
| 9 #include "src/types.h" | 9 #include "src/types.h" |
| 10 #include "test/cctest/cctest.h" | 10 #include "test/cctest/cctest.h" |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 this->AsBitset(union12)); | 227 this->AsBitset(union12)); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 | 231 |
| 232 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None) | 232 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None) |
| 233 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 233 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 234 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 234 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 235 TypeHandle type1 = *it1; | 235 TypeHandle type1 = *it1; |
| 236 TypeHandle type2 = *it2; | 236 TypeHandle type2 = *it2; |
| 237 TypeHandle intersect12 = T.Intersect(type1, type2); | |
| 238 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 237 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 238 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 239 bitset bits = this->AsBitset(type1) & this->AsBitset(type2); | 239 bitset bits = this->AsBitset(type1) & this->AsBitset(type2); |
| 240 CHECK( | 240 CHECK(bits == this->AsBitset(intersect12)); |
| 241 (Rep::BitsetType::IsInhabited(bits) ? bits : 0) == | |
| 242 this->AsBitset(intersect12)); | |
| 243 } | 241 } |
| 244 } | 242 } |
| 245 } | 243 } |
| 246 } | 244 } |
| 247 | 245 |
| 246 void PointwiseRepresentation() { |
| 247 // Check we can decompose type into semantics and representation and |
| 248 // then compose it back to get an equivalent type. |
| 249 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 250 TypeHandle type1 = *it1; |
| 251 TypeHandle representation = T.ProjectRepresentation(type1); |
| 252 TypeHandle semantic = T.ProjectSemantic(type1); |
| 253 TypeHandle composed = T.Union(representation, semantic); |
| 254 CHECK(type1->Equals(composed)); |
| 255 } |
| 256 |
| 257 // Pointwiseness of Union. |
| 258 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 259 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 260 TypeHandle type1 = *it1; |
| 261 TypeHandle type2 = *it2; |
| 262 TypeHandle representation1 = T.ProjectRepresentation(type1); |
| 263 TypeHandle semantic1 = T.ProjectSemantic(type1); |
| 264 TypeHandle representation2 = T.ProjectRepresentation(type2); |
| 265 TypeHandle semantic2 = T.ProjectSemantic(type2); |
| 266 TypeHandle direct_union = T.Union(type1, type2); |
| 267 TypeHandle representation_union = |
| 268 T.Union(representation1, representation2); |
| 269 TypeHandle semantic_union = T.Union(semantic1, semantic2); |
| 270 TypeHandle composed_union = |
| 271 T.Union(representation_union, semantic_union); |
| 272 CHECK(direct_union->Equals(composed_union)); |
| 273 } |
| 274 } |
| 275 |
| 276 // Pointwiseness of Intersect. |
| 277 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 278 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 279 TypeHandle type1 = *it1; |
| 280 TypeHandle type2 = *it2; |
| 281 TypeHandle representation1 = T.ProjectRepresentation(type1); |
| 282 TypeHandle semantic1 = T.ProjectSemantic(type1); |
| 283 TypeHandle representation2 = T.ProjectRepresentation(type2); |
| 284 TypeHandle semantic2 = T.ProjectSemantic(type2); |
| 285 TypeHandle direct_intersection = T.Intersect(type1, type2); |
| 286 TypeHandle representation_intersection = |
| 287 T.Intersect(representation1, representation2); |
| 288 TypeHandle semantic_intersection = T.Intersect(semantic1, semantic2); |
| 289 TypeHandle composed_intersection = |
| 290 T.Union(representation_intersection, semantic_intersection); |
| 291 CHECK(direct_intersection->Equals(composed_intersection)); |
| 292 } |
| 293 } |
| 294 |
| 295 // Pointwiseness of Is. |
| 296 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 297 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 298 TypeHandle type1 = *it1; |
| 299 TypeHandle type2 = *it2; |
| 300 TypeHandle representation1 = T.ProjectRepresentation(type1); |
| 301 TypeHandle semantic1 = T.ProjectSemantic(type1); |
| 302 TypeHandle representation2 = T.ProjectRepresentation(type2); |
| 303 TypeHandle semantic2 = T.ProjectSemantic(type2); |
| 304 bool representation_is = representation1->Is(representation2); |
| 305 bool semantic_is = semantic1->Is(semantic2); |
| 306 bool direct_is = type1->Is(type2); |
| 307 CHECK(direct_is == (semantic_is && representation_is)); |
| 308 } |
| 309 } |
| 310 } |
| 311 |
| 248 void Class() { | 312 void Class() { |
| 249 // Constructor | 313 // Constructor |
| 250 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 314 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 251 Handle<i::Map> map = *mt; | 315 Handle<i::Map> map = *mt; |
| 252 TypeHandle type = T.Class(map); | 316 TypeHandle type = T.Class(map); |
| 253 CHECK(type->IsClass()); | 317 CHECK(type->IsClass()); |
| 254 } | 318 } |
| 255 | 319 |
| 256 // Map attribute | 320 // Map attribute |
| 257 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 321 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 TypeHandle lub = Rep::BitsetType::New( | 718 TypeHandle lub = Rep::BitsetType::New( |
| 655 Rep::BitsetType::Lub(type), T.region()); | 719 Rep::BitsetType::Lub(type), T.region()); |
| 656 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); | 720 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); |
| 657 } | 721 } |
| 658 } | 722 } |
| 659 | 723 |
| 660 // Rangification: If T->Is(Range(-inf,+inf)) and !T->Is(None), then | 724 // Rangification: If T->Is(Range(-inf,+inf)) and !T->Is(None), then |
| 661 // T->Is(Range(T->Min(), T->Max())). | 725 // T->Is(Range(T->Min(), T->Max())). |
| 662 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 726 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 663 TypeHandle type = *it; | 727 TypeHandle type = *it; |
| 664 CHECK(!(type->Is(T.Integer) && !type->Is(T.None)) || | 728 CHECK(!type->Is(T.Integer) || !type->IsInhabited() || |
| 665 type->Is(T.Range(type->Min(), type->Max()))); | 729 type->Is(T.Range(type->Min(), type->Max()))); |
| 666 } | 730 } |
| 667 } | 731 } |
| 668 | 732 |
| 669 void BitsetGlb() { | 733 void BitsetGlb() { |
| 670 // Lower: (T->BitsetGlb())->Is(T) | 734 // Lower: (T->BitsetGlb())->Is(T) |
| 671 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 735 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 672 TypeHandle type = *it; | 736 TypeHandle type = *it; |
| 673 TypeHandle glb = | 737 TypeHandle glb = |
| 674 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); | 738 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 CHECK(!type1->Is(type2) || this->IsBitset(type2) || | 858 CHECK(!type1->Is(type2) || this->IsBitset(type2) || |
| 795 this->IsUnion(type2) || this->IsUnion(type1) || | 859 this->IsUnion(type2) || this->IsUnion(type1) || |
| 796 (type1->IsClass() && type2->IsClass()) || | 860 (type1->IsClass() && type2->IsClass()) || |
| 797 (type1->IsConstant() && type2->IsConstant()) || | 861 (type1->IsConstant() && type2->IsConstant()) || |
| 798 (type1->IsConstant() && type2->IsRange()) || | 862 (type1->IsConstant() && type2->IsRange()) || |
| 799 (this->IsBitset(type1) && type2->IsRange()) || | 863 (this->IsBitset(type1) && type2->IsRange()) || |
| 800 (type1->IsRange() && type2->IsRange()) || | 864 (type1->IsRange() && type2->IsRange()) || |
| 801 (type1->IsContext() && type2->IsContext()) || | 865 (type1->IsContext() && type2->IsContext()) || |
| 802 (type1->IsArray() && type2->IsArray()) || | 866 (type1->IsArray() && type2->IsArray()) || |
| 803 (type1->IsFunction() && type2->IsFunction()) || | 867 (type1->IsFunction() && type2->IsFunction()) || |
| 804 type1->Equals(T.None)); | 868 !type1->IsInhabited()); |
| 805 } | 869 } |
| 806 } | 870 } |
| 807 } | 871 } |
| 808 | 872 |
| 809 void Is2() { | 873 void Is2() { |
| 810 // Class(M1)->Is(Class(M2)) iff M1 = M2 | 874 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
| 811 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 875 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 812 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 876 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 813 Handle<i::Map> map1 = *mt1; | 877 Handle<i::Map> map1 = *mt1; |
| 814 Handle<i::Map> map2 = *mt2; | 878 Handle<i::Map> map2 = *mt2; |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 CheckOverlap(T.NumberArray, T.Array); | 1362 CheckOverlap(T.NumberArray, T.Array); |
| 1299 CheckDisjoint(T.NumberArray, T.AnyArray); | 1363 CheckDisjoint(T.NumberArray, T.AnyArray); |
| 1300 CheckDisjoint(T.NumberArray, T.StringArray); | 1364 CheckDisjoint(T.NumberArray, T.StringArray); |
| 1301 CheckOverlap(T.MethodFunction, T.Object); | 1365 CheckOverlap(T.MethodFunction, T.Object); |
| 1302 CheckDisjoint(T.SignedFunction1, T.NumberFunction1); | 1366 CheckDisjoint(T.SignedFunction1, T.NumberFunction1); |
| 1303 CheckDisjoint(T.SignedFunction1, T.NumberFunction2); | 1367 CheckDisjoint(T.SignedFunction1, T.NumberFunction2); |
| 1304 CheckDisjoint(T.NumberFunction1, T.NumberFunction2); | 1368 CheckDisjoint(T.NumberFunction1, T.NumberFunction2); |
| 1305 CheckDisjoint(T.SignedFunction1, T.MethodFunction); | 1369 CheckDisjoint(T.SignedFunction1, T.MethodFunction); |
| 1306 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!! | 1370 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!! |
| 1307 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!! | 1371 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!! |
| 1308 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Untagged)); // !!! | 1372 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged)); // !!! |
| 1309 } | 1373 } |
| 1310 | 1374 |
| 1311 void Union1() { | 1375 void Union1() { |
| 1312 // Identity: Union(T, None) = T | 1376 // Identity: Union(T, None) = T |
| 1313 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1377 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1314 TypeHandle type = *it; | 1378 TypeHandle type = *it; |
| 1315 TypeHandle union_type = T.Union(type, T.None); | 1379 TypeHandle union_type = T.Union(type, T.None); |
| 1316 CheckEqual(union_type, type); | 1380 CheckEqual(union_type, type); |
| 1317 } | 1381 } |
| 1318 | 1382 |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 TypeHandle type3 = *it3; | 1751 TypeHandle type3 = *it3; |
| 1688 TypeHandle intersect23 = T.Intersect(type2, type3); | 1752 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1689 CHECK(!(type1->Is(type2) && type1->Is(type3)) || | 1753 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1690 type1->Is(intersect23)); | 1754 type1->Is(intersect23)); |
| 1691 } | 1755 } |
| 1692 } | 1756 } |
| 1693 } | 1757 } |
| 1694 | 1758 |
| 1695 // Bitset-class | 1759 // Bitset-class |
| 1696 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1760 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
| 1697 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); | 1761 CHECK(!T.Intersect(T.ObjectClass, T.Array)->IsInhabited()); |
| 1698 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); | 1762 CHECK(!T.Intersect(T.ObjectClass, T.Number)->IsInhabited()); |
| 1699 | 1763 |
| 1700 // Bitset-array | 1764 // Bitset-array |
| 1701 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); | 1765 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); |
| 1702 CheckEqual(T.Intersect(T.AnyArray, T.Proxy), T.None); | 1766 CHECK(!T.Intersect(T.AnyArray, T.Proxy)->IsInhabited()); |
| 1703 | 1767 |
| 1704 // Bitset-function | 1768 // Bitset-function |
| 1705 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); | 1769 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); |
| 1706 CheckEqual(T.Intersect(T.NumberFunction1, T.Proxy), T.None); | 1770 CHECK(!T.Intersect(T.NumberFunction1, T.Proxy)->IsInhabited()); |
| 1707 | 1771 |
| 1708 // Bitset-union | 1772 // Bitset-union |
| 1709 CheckEqual( | 1773 CheckEqual( |
| 1710 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1774 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
| 1711 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1775 T.Union(T.ObjectConstant1, T.ObjectClass)); |
| 1712 CHECK( | 1776 CHECK( |
| 1713 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number) | 1777 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number) |
| 1714 ->IsInhabited()); | 1778 ->IsInhabited()); |
| 1715 | 1779 |
| 1716 // Class-constant | 1780 // Class-constant |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; | 1958 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; |
| 1895 | 1959 |
| 1896 | 1960 |
| 1897 TEST(IsSomeType) { | 1961 TEST(IsSomeType) { |
| 1898 CcTest::InitializeVM(); | 1962 CcTest::InitializeVM(); |
| 1899 ZoneTests().IsSomeType(); | 1963 ZoneTests().IsSomeType(); |
| 1900 HeapTests().IsSomeType(); | 1964 HeapTests().IsSomeType(); |
| 1901 } | 1965 } |
| 1902 | 1966 |
| 1903 | 1967 |
| 1968 TEST(PointwiseRepresentation) { |
| 1969 CcTest::InitializeVM(); |
| 1970 ZoneTests().PointwiseRepresentation(); |
| 1971 HeapTests().PointwiseRepresentation(); |
| 1972 } |
| 1973 |
| 1974 |
| 1904 TEST(BitsetType) { | 1975 TEST(BitsetType) { |
| 1905 CcTest::InitializeVM(); | 1976 CcTest::InitializeVM(); |
| 1906 ZoneTests().Bitset(); | 1977 ZoneTests().Bitset(); |
| 1907 HeapTests().Bitset(); | 1978 HeapTests().Bitset(); |
| 1908 } | 1979 } |
| 1909 | 1980 |
| 1910 | 1981 |
| 1911 TEST(ClassType) { | 1982 TEST(ClassType) { |
| 1912 CcTest::InitializeVM(); | 1983 CcTest::InitializeVM(); |
| 1913 ZoneTests().Class(); | 1984 ZoneTests().Class(); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 2147 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
| 2077 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 2148 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
| 2078 } | 2149 } |
| 2079 | 2150 |
| 2080 | 2151 |
| 2081 TEST(HTypeFromType) { | 2152 TEST(HTypeFromType) { |
| 2082 CcTest::InitializeVM(); | 2153 CcTest::InitializeVM(); |
| 2083 ZoneTests().HTypeFromType(); | 2154 ZoneTests().HTypeFromType(); |
| 2084 HeapTests().HTypeFromType(); | 2155 HeapTests().HTypeFromType(); |
| 2085 } | 2156 } |
| OLD | NEW |