| 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 |