| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 private: | 1145 private: |
| 1146 void enter() const | 1146 void enter() const |
| 1147 { | 1147 { |
| 1148 if (m_active) | 1148 if (m_active) |
| 1149 ThreadStateFor<Affinity>::state()->enterNoAllocationScope(); | 1149 ThreadStateFor<Affinity>::state()->enterNoAllocationScope(); |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 bool m_active; | 1152 bool m_active; |
| 1153 }; | 1153 }; |
| 1154 | 1154 |
| 1155 // Base class for objects that are in the Blink garbage-collected heap | |
| 1156 // and are still reference counted. | |
| 1157 // | |
| 1158 // This class should be used sparingly and only to gradually move | |
| 1159 // objects from being reference counted to being managed by the blink | |
| 1160 // garbage collector. | |
| 1161 // | |
| 1162 // While the current reference counting keeps one of these objects | |
| 1163 // alive it will have a Persistent handle to itself allocated so we | |
| 1164 // will not reclaim the memory. When the reference count reaches 0 the | |
| 1165 // persistent handle will be deleted. When the garbage collector | |
| 1166 // determines that there are no other references to the object it will | |
| 1167 // be reclaimed and the destructor of the reclaimed object will be | |
| 1168 // called at that time. | |
| 1169 template<typename T> | |
| 1170 class RefCountedGarbageCollected : public GarbageCollectedFinalized<T> { | |
| 1171 WTF_MAKE_NONCOPYABLE(RefCountedGarbageCollected); | |
| 1172 | |
| 1173 public: | |
| 1174 RefCountedGarbageCollected() | |
| 1175 : m_refCount(1) | |
| 1176 { | |
| 1177 makeKeepAlive(); | |
| 1178 } | |
| 1179 | |
| 1180 // Implement method to increase reference count for use with | |
| 1181 // RefPtrs. | |
| 1182 // | |
| 1183 // In contrast to the normal WTF::RefCounted, the reference count | |
| 1184 // can reach 0 and increase again. This happens in the following | |
| 1185 // scenario: | |
| 1186 // | |
| 1187 // (1) The reference count becomes 0, but members, persistents, or | |
| 1188 // on-stack pointers keep references to the object. | |
| 1189 // | |
| 1190 // (2) The pointer is assigned to a RefPtr again and the reference | |
| 1191 // count becomes 1. | |
| 1192 // | |
| 1193 // In this case, we have to resurrect m_keepAlive. | |
| 1194 void ref() | |
| 1195 { | |
| 1196 if (UNLIKELY(!m_refCount)) { | |
| 1197 ASSERT(ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contain
s(reinterpret_cast<Address>(this))); | |
| 1198 makeKeepAlive(); | |
| 1199 } | |
| 1200 ++m_refCount; | |
| 1201 } | |
| 1202 | |
| 1203 // Implement method to decrease reference count for use with | |
| 1204 // RefPtrs. | |
| 1205 // | |
| 1206 // In contrast to the normal WTF::RefCounted implementation, the | |
| 1207 // object itself is not deleted when the reference count reaches | |
| 1208 // 0. Instead, the keep-alive persistent handle is deallocated so | |
| 1209 // that the object can be reclaimed when the garbage collector | |
| 1210 // determines that there are no other references to the object. | |
| 1211 void deref() | |
| 1212 { | |
| 1213 ASSERT(m_refCount > 0); | |
| 1214 if (!--m_refCount) { | |
| 1215 delete m_keepAlive; | |
| 1216 m_keepAlive = 0; | |
| 1217 } | |
| 1218 } | |
| 1219 | |
| 1220 bool hasOneRef() | |
| 1221 { | |
| 1222 return m_refCount == 1; | |
| 1223 } | |
| 1224 | |
| 1225 protected: | |
| 1226 ~RefCountedGarbageCollected() { } | |
| 1227 | |
| 1228 private: | |
| 1229 void makeKeepAlive() | |
| 1230 { | |
| 1231 ASSERT(!m_keepAlive); | |
| 1232 m_keepAlive = new Persistent<T>(static_cast<T*>(this)); | |
| 1233 } | |
| 1234 | |
| 1235 int m_refCount; | |
| 1236 Persistent<T>* m_keepAlive; | |
| 1237 }; | |
| 1238 | |
| 1239 template<typename T> | |
| 1240 T* adoptRefCountedGarbageCollected(T* ptr) | |
| 1241 { | |
| 1242 ASSERT(ptr->hasOneRef()); | |
| 1243 ptr->deref(); | |
| 1244 WTF::adopted(ptr); | |
| 1245 return ptr; | |
| 1246 } | |
| 1247 | |
| 1248 // Classes that contain heap references but aren't themselves heap | 1155 // Classes that contain heap references but aren't themselves heap |
| 1249 // allocated, have some extra macros available which allows their use | 1156 // allocated, have some extra macros available which allows their use |
| 1250 // to be restricted to cases where the garbage collector is able | 1157 // to be restricted to cases where the garbage collector is able |
| 1251 // to discover their heap references. | 1158 // to discover their heap references. |
| 1252 // | 1159 // |
| 1253 // STACK_ALLOCATED(): Use if the object is only stack allocated. Heap objects | 1160 // STACK_ALLOCATED(): Use if the object is only stack allocated. Heap objects |
| 1254 // should be in Members but you do not need the trace method as they are on | 1161 // should be in Members but you do not need the trace method as they are on |
| 1255 // the stack. (Down the line these might turn in to raw pointers, but for | 1162 // the stack. (Down the line these might turn in to raw pointers, but for |
| 1256 // now Members indicates that we have thought about them and explicitly | 1163 // now Members indicates that we have thought about them and explicitly |
| 1257 // taken care of them.) | 1164 // taken care of them.) |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1520 { | 1427 { |
| 1521 return visitor->weakTableRegistered(closure); | 1428 return visitor->weakTableRegistered(closure); |
| 1522 } | 1429 } |
| 1523 #endif | 1430 #endif |
| 1524 | 1431 |
| 1525 template<typename T> | 1432 template<typename T> |
| 1526 struct ResultType { | 1433 struct ResultType { |
| 1527 typedef T* Type; | 1434 typedef T* Type; |
| 1528 }; | 1435 }; |
| 1529 | 1436 |
| 1530 // The WTF classes use Allocator::VectorBackingHelper in order to find a | |
| 1531 // class to template their backing allocation operation on. For off-heap | |
| 1532 // allocations the VectorBackingHelper is a dummy class, since the class is | |
| 1533 // not used during allocation of backing. For on-heap allocations this | |
| 1534 // typedef ensures that the allocation is done with the correct templated | |
| 1535 // instantiation of the allocation function. This ensures the correct GC | |
| 1536 // map is written when backing allocations take place. | |
| 1537 template<typename T, typename Traits> | |
| 1538 struct VectorBackingHelper { | |
| 1539 typedef HeapVectorBacking<T, Traits> Type; | |
| 1540 }; | |
| 1541 | |
| 1542 // Like the VectorBackingHelper, but this type is used for HashSet and | |
| 1543 // HashMap, both of which are implemented using HashTable. | |
| 1544 template<typename Table> | |
| 1545 struct HashTableBackingHelper { | |
| 1546 typedef HeapHashTableBacking<Table> Type; | |
| 1547 }; | |
| 1548 | |
| 1549 template<typename T> | 1437 template<typename T> |
| 1550 struct OtherType { | 1438 struct OtherType { |
| 1551 typedef T* Type; | 1439 typedef T* Type; |
| 1552 }; | 1440 }; |
| 1553 | 1441 |
| 1554 template<typename T> | 1442 template<typename T> |
| 1555 static T& getOther(T* other) | 1443 static T& getOther(T* other) |
| 1556 { | 1444 { |
| 1557 return *other; | 1445 return *other; |
| 1558 } | 1446 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 COMPILE_ASSERT(!WTF::IsWeak<ValueArg>::value, WeakPointersInAListHashSet
WillJustResultInNullEntriesInTheSetThatsNotWhatYouWantConsiderUsingLinkedHashSet
Instead); | 1505 COMPILE_ASSERT(!WTF::IsWeak<ValueArg>::value, WeakPointersInAListHashSet
WillJustResultInNullEntriesInTheSetThatsNotWhatYouWantConsiderUsingLinkedHashSet
Instead); |
| 1618 return malloc<void*, Node>(sizeof(Node)); | 1506 return malloc<void*, Node>(sizeof(Node)); |
| 1619 } | 1507 } |
| 1620 | 1508 |
| 1621 static void traceValue(Visitor* visitor, Node* node) | 1509 static void traceValue(Visitor* visitor, Node* node) |
| 1622 { | 1510 { |
| 1623 traceListHashSetValue(visitor, node->m_value); | 1511 traceListHashSetValue(visitor, node->m_value); |
| 1624 } | 1512 } |
| 1625 }; | 1513 }; |
| 1626 | 1514 |
| 1627 // FIXME: These should just be template aliases: | |
| 1628 // | |
| 1629 // template<typename T, size_t inlineCapacity = 0> | |
| 1630 // using HeapVector = Vector<T, inlineCapacity, HeapAllocator>; | |
| 1631 // | |
| 1632 // as soon as all the compilers we care about support that. | |
| 1633 // MSVC supports it only in MSVC 2013. | |
| 1634 template< | |
| 1635 typename KeyArg, | |
| 1636 typename MappedArg, | |
| 1637 typename HashArg = typename DefaultHash<KeyArg>::Hash, | |
| 1638 typename KeyTraitsArg = HashTraits<KeyArg>, | |
| 1639 typename MappedTraitsArg = HashTraits<MappedArg> > | |
| 1640 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map
pedTraitsArg, HeapAllocator> { }; | |
| 1641 | |
| 1642 template< | |
| 1643 typename ValueArg, | |
| 1644 typename HashArg = typename DefaultHash<ValueArg>::Hash, | |
| 1645 typename TraitsArg = HashTraits<ValueArg> > | |
| 1646 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator>
{ }; | |
| 1647 | |
| 1648 template< | |
| 1649 typename ValueArg, | |
| 1650 typename HashArg = typename DefaultHash<ValueArg>::Hash, | |
| 1651 typename TraitsArg = HashTraits<ValueArg> > | |
| 1652 class HeapLinkedHashSet : public LinkedHashSet<ValueArg, HashArg, TraitsArg, Hea
pAllocator> { }; | |
| 1653 | |
| 1654 template< | |
| 1655 typename ValueArg, | |
| 1656 size_t inlineCapacity = 0, // The inlineCapacity is just a dummy to match Li
stHashSet (off-heap). | |
| 1657 typename HashArg = typename DefaultHash<ValueArg>::Hash> | |
| 1658 class HeapListHashSet : public ListHashSet<ValueArg, inlineCapacity, HashArg, He
apListHashSetAllocator<ValueArg, inlineCapacity> > { }; | |
| 1659 | |
| 1660 template< | |
| 1661 typename Value, | |
| 1662 typename HashFunctions = typename DefaultHash<Value>::Hash, | |
| 1663 typename Traits = HashTraits<Value> > | |
| 1664 class HeapHashCountedSet : public HashCountedSet<Value, HashFunctions, Traits, H
eapAllocator> { }; | |
| 1665 | |
| 1666 template<typename T, size_t inlineCapacity = 0> | |
| 1667 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { | |
| 1668 public: | |
| 1669 HeapVector() { } | |
| 1670 | |
| 1671 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(
size) | |
| 1672 { | |
| 1673 } | |
| 1674 | |
| 1675 HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAlloca
tor>(size, val) | |
| 1676 { | |
| 1677 } | |
| 1678 | |
| 1679 template<size_t otherCapacity> | |
| 1680 HeapVector(const HeapVector<T, otherCapacity>& other) | |
| 1681 : Vector<T, inlineCapacity, HeapAllocator>(other) | |
| 1682 { | |
| 1683 } | |
| 1684 | |
| 1685 template<typename U> | |
| 1686 void append(const U& other) | |
| 1687 { | |
| 1688 Vector<T, inlineCapacity, HeapAllocator>::append(other); | |
| 1689 } | |
| 1690 | |
| 1691 template<typename U, size_t otherCapacity> | |
| 1692 void appendVector(const HeapVector<U, otherCapacity>& other) | |
| 1693 { | |
| 1694 const Vector<U, otherCapacity, HeapAllocator>& otherVector = other; | |
| 1695 Vector<T, inlineCapacity, HeapAllocator>::appendVector(otherVector); | |
| 1696 } | |
| 1697 }; | |
| 1698 | |
| 1699 template<typename T, size_t inlineCapacity = 0> | |
| 1700 class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> { | |
| 1701 public: | |
| 1702 HeapDeque() { } | |
| 1703 | |
| 1704 explicit HeapDeque(size_t size) : Deque<T, inlineCapacity, HeapAllocator>(si
ze) | |
| 1705 { | |
| 1706 } | |
| 1707 | |
| 1708 HeapDeque(size_t size, const T& val) : Deque<T, inlineCapacity, HeapAllocato
r>(size, val) | |
| 1709 { | |
| 1710 } | |
| 1711 | |
| 1712 // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/360572 | |
| 1713 HeapDeque<T, 0>& operator=(const HeapDeque& other) | |
| 1714 { | |
| 1715 HeapDeque<T> copy(other); | |
| 1716 swap(copy); | |
| 1717 return *this; | |
| 1718 } | |
| 1719 | |
| 1720 // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/360572 | |
| 1721 inline void swap(HeapDeque& other) | |
| 1722 { | |
| 1723 Deque<T, inlineCapacity, HeapAllocator>::swap(other); | |
| 1724 } | |
| 1725 | |
| 1726 template<size_t otherCapacity> | |
| 1727 HeapDeque(const HeapDeque<T, otherCapacity>& other) | |
| 1728 : Deque<T, inlineCapacity, HeapAllocator>(other) | |
| 1729 { | |
| 1730 } | |
| 1731 | |
| 1732 template<typename U> | |
| 1733 void append(const U& other) | |
| 1734 { | |
| 1735 Deque<T, inlineCapacity, HeapAllocator>::append(other); | |
| 1736 } | |
| 1737 }; | |
| 1738 | |
| 1739 template<typename T, size_t i> | |
| 1740 inline void swap(HeapVector<T, i>& a, HeapVector<T, i>& b) { a.swap(b); } | |
| 1741 template<typename T, size_t i> | |
| 1742 inline void swap(HeapDeque<T, i>& a, HeapDeque<T, i>& b) { a.swap(b); } | |
| 1743 template<typename T, typename U, typename V> | |
| 1744 inline void swap(HeapHashSet<T, U, V>& a, HeapHashSet<T, U, V>& b) { a.swap(b);
} | |
| 1745 template<typename T, typename U, typename V, typename W, typename X> | |
| 1746 inline void swap(HeapHashMap<T, U, V, W, X>& a, HeapHashMap<T, U, V, W, X>& b) {
a.swap(b); } | |
| 1747 template<typename T, size_t i, typename U> | |
| 1748 inline void swap(HeapListHashSet<T, i, U>& a, HeapListHashSet<T, i, U>& b) { a.s
wap(b); } | |
| 1749 template<typename T, typename U, typename V> | |
| 1750 inline void swap(HeapLinkedHashSet<T, U, V>& a, HeapLinkedHashSet<T, U, V>& b) {
a.swap(b); } | |
| 1751 template<typename T, typename U, typename V> | |
| 1752 inline void swap(HeapHashCountedSet<T, U, V>& a, HeapHashCountedSet<T, U, V>& b)
{ a.swap(b); } | |
| 1753 | |
| 1754 template<typename T> | |
| 1755 struct ThreadingTrait<Member<T> > { | |
| 1756 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1757 }; | |
| 1758 | |
| 1759 template<typename T> | |
| 1760 struct ThreadingTrait<WeakMember<T> > { | |
| 1761 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1762 }; | |
| 1763 | |
| 1764 template<typename Key, typename Value, typename T, typename U, typename V> | |
| 1765 struct ThreadingTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > { | |
| 1766 static const ThreadAffinity Affinity = | |
| 1767 (ThreadingTrait<Key>::Affinity == MainThreadOnly) | |
| 1768 && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly
: AnyThread; | |
| 1769 }; | |
| 1770 | |
| 1771 template<typename First, typename Second> | |
| 1772 struct ThreadingTrait<WTF::KeyValuePair<First, Second> > { | |
| 1773 static const ThreadAffinity Affinity = | |
| 1774 (ThreadingTrait<First>::Affinity == MainThreadOnly) | |
| 1775 && (ThreadingTrait<Second>::Affinity == MainThreadOnly) ? MainThreadOnly
: AnyThread; | |
| 1776 }; | |
| 1777 | |
| 1778 template<typename T, typename U, typename V> | |
| 1779 struct ThreadingTrait<HashSet<T, U, V, HeapAllocator> > { | |
| 1780 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1781 }; | |
| 1782 | |
| 1783 | |
| 1784 template<typename T, size_t inlineCapacity> | |
| 1785 struct ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > { | |
| 1786 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1787 }; | |
| 1788 | |
| 1789 template<typename T, typename Traits> | |
| 1790 struct ThreadingTrait<HeapVectorBacking<T, Traits> > { | |
| 1791 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1792 }; | |
| 1793 | |
| 1794 template<typename T, size_t inlineCapacity> | |
| 1795 struct ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator> > { | |
| 1796 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1797 }; | |
| 1798 | |
| 1799 template<typename T, typename U, typename V> | |
| 1800 struct ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator> > { | |
| 1801 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | |
| 1802 }; | |
| 1803 | |
| 1804 template<typename Table> | |
| 1805 struct ThreadingTrait<HeapHashTableBacking<Table> > { | |
| 1806 typedef typename Table::KeyType Key; | |
| 1807 typedef typename Table::ValueType Value; | |
| 1808 static const ThreadAffinity Affinity = | |
| 1809 (ThreadingTrait<Key>::Affinity == MainThreadOnly) | |
| 1810 && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly
: AnyThread; | |
| 1811 }; | |
| 1812 | |
| 1813 template<typename T, typename U, typename V, typename W, typename X> | |
| 1814 struct ThreadingTrait<HeapHashMap<T, U, V, W, X> > : public ThreadingTrait<HashM
ap<T, U, V, W, X, HeapAllocator> > { }; | |
| 1815 | |
| 1816 template<typename T, typename U, typename V> | |
| 1817 struct ThreadingTrait<HeapHashSet<T, U, V> > : public ThreadingTrait<HashSet<T,
U, V, HeapAllocator> > { }; | |
| 1818 | |
| 1819 template<typename T, size_t inlineCapacity> | |
| 1820 struct ThreadingTrait<HeapVector<T, inlineCapacity> > : public ThreadingTrait<Ve
ctor<T, inlineCapacity, HeapAllocator> > { }; | |
| 1821 | |
| 1822 template<typename T, size_t inlineCapacity> | |
| 1823 struct ThreadingTrait<HeapDeque<T, inlineCapacity> > : public ThreadingTrait<Deq
ue<T, inlineCapacity, HeapAllocator> > { }; | |
| 1824 | |
| 1825 template<typename T, typename U, typename V> | |
| 1826 struct ThreadingTrait<HeapHashCountedSet<T, U, V> > : public ThreadingTrait<Hash
CountedSet<T, U, V, HeapAllocator> > { }; | |
| 1827 | |
| 1828 // The standard implementation of GCInfoTrait<T>::get() just returns a static | |
| 1829 // from the class T, but we can't do that for HashMap, HashSet, Vector, etc. | |
| 1830 // because they are in WTF and know nothing of GCInfos. Instead we have a | |
| 1831 // specialization of GCInfoTrait for these four classes here. | |
| 1832 | |
| 1833 template<typename Key, typename Value, typename T, typename U, typename V> | |
| 1834 struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > { | |
| 1835 static const GCInfo* get() | |
| 1836 { | |
| 1837 typedef HashMap<Key, Value, T, U, V, HeapAllocator> TargetType; | |
| 1838 static const GCInfo info = { | |
| 1839 TraceTrait<TargetType>::trace, | |
| 1840 0, | |
| 1841 false, // HashMap needs no finalizer. | |
| 1842 WTF::IsPolymorphic<TargetType>::value, | |
| 1843 #if ENABLE(GC_PROFILING) | |
| 1844 TypenameStringTrait<TargetType>::get() | |
| 1845 #endif | |
| 1846 }; | |
| 1847 return &info; | |
| 1848 } | |
| 1849 }; | |
| 1850 | |
| 1851 template<typename T, typename U, typename V> | |
| 1852 struct GCInfoTrait<HashSet<T, U, V, HeapAllocator> > { | |
| 1853 static const GCInfo* get() | |
| 1854 { | |
| 1855 typedef HashSet<T, U, V, HeapAllocator> TargetType; | |
| 1856 static const GCInfo info = { | |
| 1857 TraceTrait<TargetType>::trace, | |
| 1858 0, | |
| 1859 false, // HashSet needs no finalizer. | |
| 1860 WTF::IsPolymorphic<TargetType>::value, | |
| 1861 #if ENABLE(GC_PROFILING) | |
| 1862 TypenameStringTrait<TargetType>::get() | |
| 1863 #endif | |
| 1864 }; | |
| 1865 return &info; | |
| 1866 } | |
| 1867 }; | |
| 1868 | |
| 1869 template<typename T, typename U, typename V> | |
| 1870 struct GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > { | |
| 1871 static const GCInfo* get() | |
| 1872 { | |
| 1873 typedef LinkedHashSet<T, U, V, HeapAllocator> TargetType; | |
| 1874 static const GCInfo info = { | |
| 1875 TraceTrait<TargetType>::trace, | |
| 1876 LinkedHashSet<T, U, V, HeapAllocator>::finalize, | |
| 1877 true, // Needs finalization. The anchor needs to unlink itself from
the chain. | |
| 1878 WTF::IsPolymorphic<TargetType>::value, | |
| 1879 #if ENABLE(GC_PROFILING) | |
| 1880 TypenameStringTrait<TargetType>::get() | |
| 1881 #endif | |
| 1882 }; | |
| 1883 return &info; | |
| 1884 } | |
| 1885 }; | |
| 1886 | |
| 1887 template<typename ValueArg, size_t inlineCapacity, typename U> | |
| 1888 struct GCInfoTrait<ListHashSet<ValueArg, inlineCapacity, U, HeapListHashSetAlloc
ator<ValueArg, inlineCapacity> > > { | |
| 1889 static const GCInfo* get() | |
| 1890 { | |
| 1891 typedef WTF::ListHashSet<ValueArg, inlineCapacity, U, HeapListHashSetAll
ocator<ValueArg, inlineCapacity> > TargetType; | |
| 1892 static const GCInfo info = { | |
| 1893 TraceTrait<TargetType>::trace, | |
| 1894 0, | |
| 1895 false, // ListHashSet needs no finalization though its backing might
. | |
| 1896 false, // no vtable. | |
| 1897 #if ENABLE(GC_PROFILING) | |
| 1898 TypenameStringTrait<TargetType>::get() | |
| 1899 #endif | |
| 1900 }; | |
| 1901 return &info; | |
| 1902 } | |
| 1903 }; | |
| 1904 | |
| 1905 template<typename T, typename Allocator> | |
| 1906 struct GCInfoTrait<WTF::ListHashSetNode<T, Allocator> > { | |
| 1907 static const GCInfo* get() | |
| 1908 { | |
| 1909 typedef WTF::ListHashSetNode<T, Allocator> TargetType; | |
| 1910 static const GCInfo info = { | |
| 1911 TraceTrait<TargetType>::trace, | |
| 1912 TargetType::finalize, | |
| 1913 WTF::HashTraits<T>::needsDestruction, // The node needs destruction
if its data does. | |
| 1914 false, // no vtable. | |
| 1915 #if ENABLE(GC_PROFILING) | |
| 1916 TypenameStringTrait<TargetType>::get() | |
| 1917 #endif | |
| 1918 }; | |
| 1919 return &info; | |
| 1920 } | |
| 1921 }; | |
| 1922 | |
| 1923 template<typename T> | |
| 1924 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > { | |
| 1925 static const GCInfo* get() | |
| 1926 { | |
| 1927 #if ENABLE(GC_PROFILING) | |
| 1928 typedef Vector<T, 0, HeapAllocator> TargetType; | |
| 1929 #endif | |
| 1930 static const GCInfo info = { | |
| 1931 TraceTrait<Vector<T, 0, HeapAllocator> >::trace, | |
| 1932 0, | |
| 1933 false, // Vector needs no finalizer if it has no inline capacity. | |
| 1934 WTF::IsPolymorphic<Vector<T, 0, HeapAllocator> >::value, | |
| 1935 #if ENABLE(GC_PROFILING) | |
| 1936 TypenameStringTrait<TargetType>::get() | |
| 1937 #endif | |
| 1938 }; | |
| 1939 return &info; | |
| 1940 } | |
| 1941 }; | |
| 1942 | |
| 1943 template<typename T, size_t inlineCapacity> | |
| 1944 struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator> > : public Finali
zerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>, true> { }; | |
| 1945 | |
| 1946 template<typename T, size_t inlineCapacity> | |
| 1947 struct GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > { | |
| 1948 static const GCInfo* get() | |
| 1949 { | |
| 1950 typedef Vector<T, inlineCapacity, HeapAllocator> TargetType; | |
| 1951 static const GCInfo info = { | |
| 1952 TraceTrait<TargetType>::trace, | |
| 1953 FinalizerTrait<TargetType>::finalize, | |
| 1954 // Finalizer is needed to destruct things stored in the inline capac
ity. | |
| 1955 inlineCapacity && VectorTraits<T>::needsDestruction, | |
| 1956 WTF::IsPolymorphic<TargetType>::value, | |
| 1957 #if ENABLE(GC_PROFILING) | |
| 1958 TypenameStringTrait<TargetType>::get() | |
| 1959 #endif | |
| 1960 }; | |
| 1961 return &info; | |
| 1962 } | |
| 1963 }; | |
| 1964 | |
| 1965 template<typename T> | |
| 1966 struct GCInfoTrait<Deque<T, 0, HeapAllocator> > { | |
| 1967 static const GCInfo* get() | |
| 1968 { | |
| 1969 typedef Deque<T, 0, HeapAllocator> TargetType; | |
| 1970 static const GCInfo info = { | |
| 1971 TraceTrait<TargetType>::trace, | |
| 1972 0, | |
| 1973 false, // Deque needs no finalizer if it has no inline capacity. | |
| 1974 WTF::IsPolymorphic<TargetType>::value, | |
| 1975 #if ENABLE(GC_PROFILING) | |
| 1976 TypenameStringTrait<TargetType>::get() | |
| 1977 #endif | |
| 1978 }; | |
| 1979 return &info; | |
| 1980 } | |
| 1981 static const GCInfo info; | |
| 1982 }; | |
| 1983 | |
| 1984 template<typename T, typename U, typename V> | |
| 1985 struct GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator> > { | |
| 1986 static const GCInfo* get() | |
| 1987 { | |
| 1988 typedef HashCountedSet<T, U, V, HeapAllocator> TargetType; | |
| 1989 static const GCInfo info = { | |
| 1990 TraceTrait<TargetType>::trace, | |
| 1991 0, | |
| 1992 false, // HashCountedSet is just a HashTable, and needs no finalizer
. | |
| 1993 WTF::IsPolymorphic<TargetType>::value, | |
| 1994 #if ENABLE(GC_PROFILING) | |
| 1995 TypenameStringTrait<TargetType>::get() | |
| 1996 #endif | |
| 1997 }; | |
| 1998 return &info; | |
| 1999 } | |
| 2000 static const GCInfo info; | |
| 2001 }; | |
| 2002 | |
| 2003 template<typename T, size_t inlineCapacity> | |
| 2004 struct FinalizerTrait<Deque<T, inlineCapacity, HeapAllocator> > : public Finaliz
erTraitImpl<Deque<T, inlineCapacity, HeapAllocator>, true> { }; | |
| 2005 | |
| 2006 template<typename T, size_t inlineCapacity> | |
| 2007 struct GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator> > { | |
| 2008 static const GCInfo* get() | |
| 2009 { | |
| 2010 typedef Deque<T, inlineCapacity, HeapAllocator> TargetType; | |
| 2011 static const GCInfo info = { | |
| 2012 TraceTrait<TargetType>::trace, | |
| 2013 FinalizerTrait<TargetType>::finalize, | |
| 2014 // Finalizer is needed to destruct things stored in the inline capac
ity. | |
| 2015 inlineCapacity && VectorTraits<T>::needsDestruction, | |
| 2016 WTF::IsPolymorphic<TargetType>::value, | |
| 2017 #if ENABLE(GC_PROFILING) | |
| 2018 TypenameStringTrait<TargetType>::get() | |
| 2019 #endif | |
| 2020 }; | |
| 2021 return &info; | |
| 2022 } | |
| 2023 static const GCInfo info; | |
| 2024 }; | |
| 2025 | |
| 2026 template<typename T, typename Traits> | |
| 2027 struct GCInfoTrait<HeapVectorBacking<T, Traits> > { | |
| 2028 static const GCInfo* get() | |
| 2029 { | |
| 2030 typedef HeapVectorBacking<T, Traits> TargetType; | |
| 2031 static const GCInfo info = { | |
| 2032 TraceTrait<TargetType>::trace, | |
| 2033 FinalizerTrait<TargetType>::finalize, | |
| 2034 Traits::needsDestruction, | |
| 2035 false, // We don't support embedded objects in HeapVectors with vtab
les. | |
| 2036 #if ENABLE(GC_PROFILING) | |
| 2037 TypenameStringTrait<TargetType>::get() | |
| 2038 #endif | |
| 2039 }; | |
| 2040 return &info; | |
| 2041 } | |
| 2042 }; | |
| 2043 | |
| 2044 template<typename Table> | |
| 2045 struct GCInfoTrait<HeapHashTableBacking<Table> > { | |
| 2046 static const GCInfo* get() | |
| 2047 { | |
| 2048 typedef HeapHashTableBacking<Table> TargetType; | |
| 2049 static const GCInfo info = { | |
| 2050 TraceTrait<TargetType>::trace, | |
| 2051 HeapHashTableBacking<Table>::finalize, | |
| 2052 Table::ValueTraits::needsDestruction, | |
| 2053 WTF::IsPolymorphic<TargetType>::value, | |
| 2054 #if ENABLE(GC_PROFILING) | |
| 2055 TypenameStringTrait<TargetType>::get() | |
| 2056 #endif | |
| 2057 }; | |
| 2058 return &info; | |
| 2059 } | |
| 2060 }; | |
| 2061 | |
| 2062 } // namespace blink | |
| 2063 | |
| 2064 namespace WTF { | |
| 2065 | |
| 2066 // Catch-all for types that have a way to trace that don't have special | |
| 2067 // handling for weakness in collections. This means that if this type | |
| 2068 // contains WeakMember fields, they will simply be zeroed, but the entry | |
| 2069 // will not be removed from the collection. This always happens for | |
| 2070 // things in vectors, which don't currently support special handling of | |
| 2071 // weak elements. | |
| 2072 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | |
| 2073 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ | |
| 2074 static bool trace(blink::Visitor* visitor, T& t) | |
| 2075 { | |
| 2076 return false; | |
| 2077 } | |
| 2078 }; | |
| 2079 | |
| 2080 // Catch-all for things that have HashTrait support for tracing with weakness. | |
| 2081 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | |
| 2082 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { | |
| 2083 static bool trace(blink::Visitor* visitor, T& t) | |
| 2084 { | |
| 2085 return false; | |
| 2086 } | |
| 2087 }; | |
| 2088 | |
| 2089 // Vector backing that needs marking. We don't support weak members in vectors. | |
| 2090 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | |
| 2091 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { | |
| 2092 static bool trace(blink::Visitor* visitor, void* self) | |
| 2093 { | |
| 2094 return false; | |
| 2095 } | |
| 2096 }; | |
| 2097 | |
| 2098 // Almost all hash table backings are visited with this specialization. | |
| 2099 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | |
| 2100 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { | |
| 2101 typedef typename Table::ValueType Value; | |
| 2102 typedef typename Table::ValueTraits Traits; | |
| 2103 static bool trace(blink::Visitor* visitor, void* self) | |
| 2104 { | |
| 2105 return false; | |
| 2106 } | |
| 2107 }; | |
| 2108 | |
| 2109 // This specialization of TraceInCollectionTrait is for the backing of | |
| 2110 // HeapListHashSet. This is for the case that we find a reference to the | |
| 2111 // backing from the stack. That probably means we have a GC while we are in a | |
| 2112 // ListHashSet method since normal API use does not put pointers to the backing | |
| 2113 // on the stack. | |
| 2114 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> | |
| 2115 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity> >*, U, V, W, X, Y, blink::HeapAllocator> >, void> { | |
| 2116 typedef ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T, inl
ineCapacity> > Node; | |
| 2117 typedef HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator> Table; | |
| 2118 static bool trace(blink::Visitor* visitor, void* self) | |
| 2119 { | |
| 2120 return false; | |
| 2121 } | |
| 2122 }; | |
| 2123 | |
| 2124 // Key value pairs, as used in HashMap. To disambiguate template choice we have | |
| 2125 // to have two versions, first the one with no special weak handling, then the | |
| 2126 // one with weak handling. | |
| 2127 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | |
| 2128 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { | |
| 2129 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | |
| 2130 { | |
| 2131 return false; | |
| 2132 } | |
| 2133 }; | |
| 2134 | |
| 2135 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | |
| 2136 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { | |
| 2137 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | |
| 2138 { | |
| 2139 return false; | |
| 2140 } | |
| 2141 }; | |
| 2142 | |
| 2143 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the | |
| 2144 // template. | |
| 2145 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | |
| 2146 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { | |
| 2147 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | |
| 2148 { | |
| 2149 return false; | |
| 2150 } | |
| 2151 }; | |
| 2152 | |
| 2153 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | |
| 2154 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { | |
| 2155 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | |
| 2156 { | |
| 2157 return false; | |
| 2158 } | |
| 2159 }; | |
| 2160 | |
| 2161 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the
se pointers). | |
| 2162 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> | |
| 2163 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits>
{ | |
| 2164 typedef ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, inline
Capacity> > Node; | |
| 2165 static bool trace(blink::Visitor* visitor, Node* node) | |
| 2166 { | |
| 2167 return false; | |
| 2168 } | |
| 2169 }; | |
| 2170 | |
| 2171 } // namespace WTF | |
| 2172 | |
| 2173 namespace blink { | |
| 2174 | |
| 2175 // CollectionBackingTraceTrait. Do nothing for things in collections that don't | 1515 // CollectionBackingTraceTrait. Do nothing for things in collections that don't |
| 2176 // need tracing, or call TraceInCollectionTrait for those that do. | 1516 // need tracing, or call TraceInCollectionTrait for those that do. |
| 2177 | 1517 |
| 2178 // Specialization for things that don't need marking and have no weak pointers.
We | 1518 // Specialization for things that don't need marking and have no weak pointers.
We |
| 2179 // do nothing, even if WTF::WeakPointersActStrong. | 1519 // do nothing, even if WTF::WeakPointersActStrong. |
| 2180 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> | 1520 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> |
| 2181 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { | 1521 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { |
| 2182 static bool trace(Visitor*, T&) { return false; } | 1522 static bool trace(Visitor*, T&) { return false; } |
| 2183 }; | 1523 }; |
| 2184 | 1524 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2222 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 1562 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
| 2223 typedef HeapVectorBacking<T, Traits> Backing; | 1563 typedef HeapVectorBacking<T, Traits> Backing; |
| 2224 static void trace(Visitor* visitor, void* self) | 1564 static void trace(Visitor* visitor, void* self) |
| 2225 { | 1565 { |
| 2226 } | 1566 } |
| 2227 static void mark(Visitor* visitor, const Backing* backing) | 1567 static void mark(Visitor* visitor, const Backing* backing) |
| 2228 { | 1568 { |
| 2229 } | 1569 } |
| 2230 }; | 1570 }; |
| 2231 | 1571 |
| 2232 // The trace trait for the heap hashtable backing is used when we find a | |
| 2233 // direct pointer to the backing from the conservative stack scanner. This | |
| 2234 // normally indicates that there is an ongoing iteration over the table, and so | |
| 2235 // we disable weak processing of table entries. When the backing is found | |
| 2236 // through the owning hash table we mark differently, in order to do weak | |
| 2237 // processing. | |
| 2238 template<typename Table> | |
| 2239 struct TraceTrait<HeapHashTableBacking<Table> > { | |
| 2240 typedef HeapHashTableBacking<Table> Backing; | |
| 2241 typedef typename Table::ValueTraits Traits; | |
| 2242 static void trace(Visitor* visitor, void* self) | |
| 2243 { | |
| 2244 } | |
| 2245 static void mark(Visitor* visitor, const Backing* backing) | |
| 2246 { | |
| 2247 } | |
| 2248 }; | |
| 2249 | |
| 2250 template<typename Table> | |
| 2251 void HeapHashTableBacking<Table>::finalize(void* pointer) | |
| 2252 { | |
| 2253 } | |
| 2254 | |
| 2255 template<typename T, typename U, typename V, typename W, typename X> | |
| 2256 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; | |
| 2257 template<typename T, typename U, typename V> | |
| 2258 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; | |
| 2259 template<typename T, typename U, typename V> | |
| 2260 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashS
et<T, U, V, HeapAllocator> > { }; | |
| 2261 template<typename T, size_t inlineCapacity, typename U> | |
| 2262 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U> > : public GCInfoTrait<
ListHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity> >
> { }; | |
| 2263 template<typename T, size_t inlineCapacity> | |
| 2264 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; | |
| 2265 template<typename T, size_t inlineCapacity> | |
| 2266 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T,
inlineCapacity, HeapAllocator> > { }; | |
| 2267 template<typename T, typename U, typename V> | |
| 2268 struct GCInfoTrait<HeapHashCountedSet<T, U, V> > : public GCInfoTrait<HashCounte
dSet<T, U, V, HeapAllocator> > { }; | |
| 2269 | |
| 2270 template<typename T> | 1572 template<typename T> |
| 2271 struct IfWeakMember; | 1573 struct IfWeakMember; |
| 2272 | 1574 |
| 2273 template<typename T> | 1575 template<typename T> |
| 2274 struct IfWeakMember { | 1576 struct IfWeakMember { |
| 2275 template<typename U> | 1577 template<typename U> |
| 2276 static bool isDead(Visitor*, const U&) { return false; } | 1578 static bool isDead(Visitor*, const U&) { return false; } |
| 2277 }; | 1579 }; |
| 2278 | 1580 |
| 2279 template<typename T> | 1581 template<typename T> |
| 2280 struct IfWeakMember<WeakMember<T> > { | 1582 struct IfWeakMember<WeakMember<T> > { |
| 2281 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } | 1583 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } |
| 2282 }; | 1584 }; |
| 2283 | 1585 |
| 2284 } | 1586 } |
| 2285 | 1587 |
| 2286 #endif // Heap_h | 1588 #endif // Heap_h |
| OLD | NEW |