OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 }; | 70 }; |
71 | 71 |
72 | 72 |
73 struct HeapRep { | 73 struct HeapRep { |
74 typedef FixedArray Struct; | 74 typedef FixedArray Struct; |
75 | 75 |
76 static bool IsStruct(Handle<HeapType> t, int tag) { | 76 static bool IsStruct(Handle<HeapType> t, int tag) { |
77 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; | 77 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; |
78 } | 78 } |
79 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } | 79 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } |
80 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } | 80 static bool IsClass(Handle<HeapType> t) { |
81 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } | 81 return t->IsMap() || IsStruct(t, 0); |
| 82 } |
| 83 static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); } |
82 static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 2); } | 84 static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 2); } |
83 static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 3); } | 85 static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 3); } |
84 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 4); } | 86 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 4); } |
85 | 87 |
86 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } | 88 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } |
87 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } | 89 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } |
88 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } | 90 static Map* AsClass(Handle<HeapType> t) { |
89 static Object* AsConstant(Handle<HeapType> t) { | 91 return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2)); |
90 return Box::cast(*t)->value(); | |
91 } | 92 } |
| 93 static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); } |
92 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } | 94 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } |
93 static int Length(Struct* structured) { return structured->length() - 1; } | 95 static int Length(Struct* structured) { return structured->length() - 1; } |
94 | 96 |
95 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | 97 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } |
96 }; | 98 }; |
97 | 99 |
98 | 100 |
99 template<class Type, class TypeHandle, class Region> | 101 template<class Type, class TypeHandle, class Region> |
100 class Types { | 102 class Types { |
101 public: | 103 public: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 147 |
146 FloatArray = Type::Array(Float, region); | 148 FloatArray = Type::Array(Float, region); |
147 StringArray = Type::Array(String, region); | 149 StringArray = Type::Array(String, region); |
148 AnyArray = Type::Array(Any, region); | 150 AnyArray = Type::Array(Any, region); |
149 | 151 |
150 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region); | 152 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region); |
151 NumberFunction1 = Type::Function(Number, Number, region); | 153 NumberFunction1 = Type::Function(Number, Number, region); |
152 NumberFunction2 = Type::Function(Number, Number, Number, region); | 154 NumberFunction2 = Type::Function(Number, Number, Number, region); |
153 MethodFunction = Type::Function(String, Object, 0, region); | 155 MethodFunction = Type::Function(String, Object, 0, region); |
154 | 156 |
155 for (int i = 0; i < 50; ++i) { | 157 for (int i = 0; i < 500; ++i) { |
156 types.push_back(Fuzz()); | 158 types.push_back(Fuzz()); |
157 } | 159 } |
158 } | 160 } |
159 | 161 |
160 Handle<i::Map> object_map; | 162 Handle<i::Map> object_map; |
161 Handle<i::Map> array_map; | 163 Handle<i::Map> array_map; |
162 Handle<i::Map> uninitialized_map; | 164 Handle<i::Map> uninitialized_map; |
163 | 165 |
164 Handle<i::Smi> smi; | 166 Handle<i::Smi> smi; |
165 Handle<i::HeapNumber> signed32; | 167 Handle<i::HeapNumber> signed32; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 zone(isolate), | 327 zone(isolate), |
326 T(Rep::ToRegion(&zone, isolate), isolate) { | 328 T(Rep::ToRegion(&zone, isolate), isolate) { |
327 } | 329 } |
328 | 330 |
329 bool Equal(TypeHandle type1, TypeHandle type2) { | 331 bool Equal(TypeHandle type1, TypeHandle type2) { |
330 return | 332 return |
331 type1->Is(type2) && type2->Is(type1) && | 333 type1->Is(type2) && type2->Is(type1) && |
332 Rep::IsBitset(type1) == Rep::IsBitset(type2) && | 334 Rep::IsBitset(type1) == Rep::IsBitset(type2) && |
333 Rep::IsClass(type1) == Rep::IsClass(type2) && | 335 Rep::IsClass(type1) == Rep::IsClass(type2) && |
334 Rep::IsConstant(type1) == Rep::IsConstant(type2) && | 336 Rep::IsConstant(type1) == Rep::IsConstant(type2) && |
| 337 Rep::IsArray(type1) == Rep::IsArray(type2) && |
| 338 Rep::IsFunction(type1) == Rep::IsFunction(type2) && |
335 Rep::IsUnion(type1) == Rep::IsUnion(type2) && | 339 Rep::IsUnion(type1) == Rep::IsUnion(type2) && |
336 type1->NumClasses() == type2->NumClasses() && | 340 type1->NumClasses() == type2->NumClasses() && |
337 type1->NumConstants() == type2->NumConstants() && | 341 type1->NumConstants() == type2->NumConstants() && |
338 (!Rep::IsBitset(type1) || | 342 (!Rep::IsBitset(type1) || |
339 Rep::AsBitset(type1) == Rep::AsBitset(type2)) && | 343 Rep::AsBitset(type1) == Rep::AsBitset(type2)) && |
340 (!Rep::IsClass(type1) || | 344 (!Rep::IsClass(type1) || |
341 Rep::AsClass(type1) == Rep::AsClass(type2)) && | 345 Rep::AsClass(type1) == Rep::AsClass(type2)) && |
342 (!Rep::IsConstant(type1) || | 346 (!Rep::IsConstant(type1) || |
343 Rep::AsConstant(type1) == Rep::AsConstant(type2)) && | 347 Rep::AsConstant(type1) == Rep::AsConstant(type2)) && |
344 (!Rep::IsUnion(type1) || | 348 // TODO(rossberg): Check details of arrays, functions, bounds. |
| 349 (!Rep::IsUnion(type1) || |
345 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); | 350 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); |
346 } | 351 } |
347 | 352 |
348 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 353 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
349 CHECK(Equal(type1, type2)); | 354 CHECK(Equal(type1, type2)); |
350 } | 355 } |
351 | 356 |
352 void CheckSub(TypeHandle type1, TypeHandle type2) { | 357 void CheckSub(TypeHandle type1, TypeHandle type2) { |
353 CHECK(type1->Is(type2)); | 358 CHECK(type1->Is(type2)); |
354 CHECK(!type2->Is(type1)); | 359 CHECK(!type2->Is(type1)); |
(...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation); | 1533 CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation); |
1529 | 1534 |
1530 // Bitset-function | 1535 // Bitset-function |
1531 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); | 1536 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); |
1532 CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation); | 1537 CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation); |
1533 | 1538 |
1534 // Bitset-union | 1539 // Bitset-union |
1535 CheckEqual( | 1540 CheckEqual( |
1536 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1541 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1537 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1542 T.Union(T.ObjectConstant1, T.ObjectClass)); |
1538 CheckEqual( | 1543 CHECK( |
1539 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | 1544 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number) |
1540 T.None); | 1545 ->IsInhabited()); |
1541 | 1546 |
1542 // Class-constant | 1547 // Class-constant |
1543 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); | 1548 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); |
1544 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); | 1549 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); |
1545 | 1550 |
1546 // Array-union | 1551 // Array-union |
1547 CheckEqual( | 1552 CheckEqual( |
1548 T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)), | 1553 T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)), |
1549 T.FloatArray); | 1554 T.FloatArray); |
1550 CheckEqual( | 1555 CheckEqual( |
1551 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), | 1556 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), |
1552 T.AnyArray); | 1557 T.AnyArray); |
1553 CheckEqual( | 1558 CHECK( |
1554 T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray), | 1559 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray) |
1555 T.None); | 1560 ->IsInhabited()); |
1556 | 1561 |
1557 // Function-union | 1562 // Function-union |
1558 CheckEqual( | 1563 CheckEqual( |
1559 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), | 1564 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), |
1560 T.MethodFunction); | 1565 T.MethodFunction); |
1561 CheckEqual( | 1566 CheckEqual( |
1562 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), | 1567 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), |
1563 T.NumberFunction1); | 1568 T.NumberFunction1); |
1564 CheckEqual( | 1569 CHECK( |
1565 T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2), | 1570 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) |
1566 T.None); | 1571 ->IsInhabited()); |
1567 | 1572 |
1568 // Class-union | 1573 // Class-union |
1569 CheckEqual( | 1574 CheckEqual( |
1570 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1575 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
1571 T.ArrayClass); | 1576 T.ArrayClass); |
1572 CheckEqual( | 1577 CheckEqual( |
1573 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1578 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
1574 T.ArrayClass); | 1579 T.ArrayClass); |
1575 CheckEqual( | 1580 CHECK( |
1576 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), | 1581 !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) |
1577 T.None); | 1582 ->IsInhabited()); |
1578 | 1583 |
1579 // Constant-union | 1584 // Constant-union |
1580 CheckEqual( | 1585 CheckEqual( |
1581 T.Intersect( | 1586 T.Intersect( |
1582 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1587 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1583 T.ObjectConstant1); | 1588 T.ObjectConstant1); |
1584 CheckEqual( | 1589 CheckEqual( |
1585 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | 1590 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
1586 T.SmiConstant); | 1591 T.SmiConstant); |
1587 CheckEqual( | 1592 CHECK( |
1588 T.Intersect( | 1593 !T.Intersect( |
1589 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), | 1594 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) |
1590 T.None); | 1595 ->IsInhabited()); |
1591 | 1596 |
1592 // Union-union | 1597 // Union-union |
1593 CheckEqual( | 1598 CheckEqual( |
1594 T.Intersect( | 1599 T.Intersect( |
1595 T.Union(T.Number, T.ArrayClass), | 1600 T.Union(T.Number, T.ArrayClass), |
1596 T.Union(T.SignedSmall, T.Array)), | 1601 T.Union(T.SignedSmall, T.Array)), |
1597 T.Union(T.SignedSmall, T.ArrayClass)); | 1602 T.Union(T.SignedSmall, T.ArrayClass)); |
1598 CheckEqual( | 1603 CheckEqual( |
1599 T.Intersect( | 1604 T.Intersect( |
1600 T.Union(T.Number, T.ObjectClass), | 1605 T.Union(T.Number, T.ObjectClass), |
1601 T.Union(T.Signed32, T.Array)), | 1606 T.Union(T.Signed32, T.Array)), |
1602 T.Signed32); | 1607 T.Signed32); |
1603 CheckEqual( | 1608 CheckEqual( |
1604 T.Intersect( | 1609 T.Intersect( |
1605 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1610 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
1606 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1611 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1607 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1612 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1608 CheckEqual( | 1613 CheckEqual( |
1609 T.Intersect( | 1614 T.Intersect( |
1610 T.Union( | 1615 T.Union( |
1611 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), | 1616 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), |
1612 T.Union( | 1617 T.Union( |
1613 T.ObjectConstant1, | 1618 T.ObjectConstant1, |
1614 T.Union(T.ArrayConstant, T.ObjectConstant2))), | 1619 T.Union(T.ArrayConstant, T.ObjectConstant2))), |
1615 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1620 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1616 } | 1621 } |
1617 | 1622 |
| 1623 void Distributivity() { |
| 1624 // Distributivity: |
| 1625 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) |
| 1626 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1627 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1628 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1629 TypeHandle type1 = *it1; |
| 1630 TypeHandle type2 = *it2; |
| 1631 TypeHandle type3 = *it3; |
| 1632 TypeHandle union12 = T.Union(type1, type2); |
| 1633 TypeHandle union13 = T.Union(type1, type3); |
| 1634 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1635 TypeHandle union1_23 = T.Union(type1, intersect23); |
| 1636 TypeHandle intersect12_13 = T.Intersect(union12, union13); |
| 1637 CHECK(Equal(union1_23, intersect12_13)); |
| 1638 } |
| 1639 } |
| 1640 } |
| 1641 |
| 1642 // Distributivity: |
| 1643 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) |
| 1644 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1645 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1646 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1647 TypeHandle type1 = *it1; |
| 1648 TypeHandle type2 = *it2; |
| 1649 TypeHandle type3 = *it3; |
| 1650 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1651 TypeHandle intersect13 = T.Intersect(type1, type3); |
| 1652 TypeHandle union23 = T.Union(type2, type3); |
| 1653 TypeHandle intersect1_23 = T.Intersect(type1, union23); |
| 1654 TypeHandle union12_13 = T.Union(intersect12, intersect13); |
| 1655 CHECK(Equal(intersect1_23, union12_13)); |
| 1656 } |
| 1657 } |
| 1658 } |
| 1659 } |
| 1660 |
1618 template<class Type2, class TypeHandle2, class Region2, class Rep2> | 1661 template<class Type2, class TypeHandle2, class Region2, class Rep2> |
1619 void Convert() { | 1662 void Convert() { |
1620 Types<Type2, TypeHandle2, Region2> T2( | 1663 Types<Type2, TypeHandle2, Region2> T2( |
1621 Rep2::ToRegion(&zone, isolate), isolate); | 1664 Rep2::ToRegion(&zone, isolate), isolate); |
1622 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1665 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1623 TypeHandle type1 = *it; | 1666 TypeHandle type1 = *it; |
1624 TypeHandle2 type2 = T2.template Convert<Type>(type1); | 1667 TypeHandle2 type2 = T2.template Convert<Type>(type1); |
1625 TypeHandle type3 = T.template Convert<Type2>(type2); | 1668 TypeHandle type3 = T.template Convert<Type2>(type2); |
1626 CheckEqual(type1, type3); | 1669 CheckEqual(type1, type3); |
1627 } | 1670 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 } | 1780 } |
1738 | 1781 |
1739 | 1782 |
1740 TEST(Intersect2) { | 1783 TEST(Intersect2) { |
1741 CcTest::InitializeVM(); | 1784 CcTest::InitializeVM(); |
1742 ZoneTests().Intersect2(); | 1785 ZoneTests().Intersect2(); |
1743 HeapTests().Intersect2(); | 1786 HeapTests().Intersect2(); |
1744 } | 1787 } |
1745 | 1788 |
1746 | 1789 |
| 1790 TEST(Distributivity) { |
| 1791 CcTest::InitializeVM(); |
| 1792 ZoneTests().Distributivity(); |
| 1793 HeapTests().Distributivity(); |
| 1794 } |
| 1795 |
| 1796 |
1747 TEST(Convert) { | 1797 TEST(Convert) { |
1748 CcTest::InitializeVM(); | 1798 CcTest::InitializeVM(); |
1749 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1799 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
1750 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1800 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
1751 } | 1801 } |
OLD | NEW |