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 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #ifndef Heap_h | 31 #ifndef Heap_h |
32 #define Heap_h | 32 #define Heap_h |
33 | 33 |
34 #include "platform/PlatformExport.h" | 34 #include "platform/PlatformExport.h" |
35 #include "platform/heap/AddressSanitizer.h" | 35 #include "platform/heap/AddressSanitizer.h" |
36 #include "platform/heap/ThreadState.h" | 36 #include "platform/heap/ThreadState.h" |
37 #include "platform/heap/Visitor.h" | 37 #include "platform/heap/Visitor.h" |
38 | 38 |
39 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
| 40 #include "wtf/LinkedHashSet.h" |
40 #include "wtf/OwnPtr.h" | 41 #include "wtf/OwnPtr.h" |
41 #include "wtf/PassRefPtr.h" | 42 #include "wtf/PassRefPtr.h" |
42 | 43 |
43 #include <stdint.h> | 44 #include <stdint.h> |
44 | 45 |
45 namespace WebCore { | 46 namespace WebCore { |
46 | 47 |
47 const size_t blinkPageSizeLog2 = 17; | 48 const size_t blinkPageSizeLog2 = 17; |
48 const size_t blinkPageSize = 1 << blinkPageSizeLog2; | 49 const size_t blinkPageSize = 1 << blinkPageSizeLog2; |
49 const size_t blinkPageOffsetMask = blinkPageSize - 1; | 50 const size_t blinkPageOffsetMask = blinkPageSize - 1; |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 } | 1295 } |
1295 | 1296 |
1296 static void markNoTracing(Visitor* visitor, const void* t) | 1297 static void markNoTracing(Visitor* visitor, const void* t) |
1297 { | 1298 { |
1298 visitor->mark(t, reinterpret_cast<TraceCallback>(0)); | 1299 visitor->mark(t, reinterpret_cast<TraceCallback>(0)); |
1299 } | 1300 } |
1300 | 1301 |
1301 template<typename T, typename Traits> | 1302 template<typename T, typename Traits> |
1302 static void trace(Visitor* visitor, T& t) | 1303 static void trace(Visitor* visitor, T& t) |
1303 { | 1304 { |
1304 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, false, T, Traits>::mark(visitor, t); | 1305 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, WeakPointersActWeak, T, Traits>::mark(visitor, t); |
1305 } | 1306 } |
1306 | 1307 |
1307 template<typename T> | 1308 template<typename T> |
1308 static bool hasDeadMember(Visitor*, const T&) | 1309 static bool hasDeadMember(Visitor*, const T&) |
1309 { | 1310 { |
1310 return false; | 1311 return false; |
1311 } | 1312 } |
1312 | 1313 |
1313 template<typename T> | 1314 template<typename T> |
1314 static bool hasDeadMember(Visitor* visitor, const Member<T>& t) | 1315 static bool hasDeadMember(Visitor* visitor, const Member<T>& t) |
1315 { | 1316 { |
1316 ASSERT(visitor->isAlive(t)); | 1317 ASSERT(visitor->isAlive(t)); |
1317 return false; | 1318 return false; |
1318 } | 1319 } |
1319 | 1320 |
1320 template<typename T> | 1321 template<typename T> |
1321 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t) | 1322 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t) |
1322 { | 1323 { |
1323 return !visitor->isAlive(t); | 1324 return !visitor->isAlive(t); |
1324 } | 1325 } |
1325 | 1326 |
1326 template<typename T, typename U> | 1327 template<typename T, typename U> |
1327 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t
) | 1328 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t
) |
1328 { | 1329 { |
1329 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value); | 1330 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value); |
1330 } | 1331 } |
1331 | 1332 |
| 1333 template<typename T> |
| 1334 static bool hasDeadMember(Visitor*, const WTF::LinkedHashSetNode<T>&); |
| 1335 |
1332 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1336 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
1333 { | 1337 { |
1334 visitor->registerWeakMembers(closure, object, callback); | 1338 visitor->registerWeakMembers(closure, object, callback); |
1335 } | 1339 } |
1336 | 1340 |
1337 template<typename T> | 1341 template<typename T> |
1338 struct ResultType { | 1342 struct ResultType { |
1339 typedef T* Type; | 1343 typedef T* Type; |
1340 }; | 1344 }; |
1341 | 1345 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 typename KeyTraitsArg = HashTraits<KeyArg>, | 1393 typename KeyTraitsArg = HashTraits<KeyArg>, |
1390 typename MappedTraitsArg = HashTraits<MappedArg> > | 1394 typename MappedTraitsArg = HashTraits<MappedArg> > |
1391 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map
pedTraitsArg, HeapAllocator> { }; | 1395 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map
pedTraitsArg, HeapAllocator> { }; |
1392 | 1396 |
1393 template< | 1397 template< |
1394 typename ValueArg, | 1398 typename ValueArg, |
1395 typename HashArg = typename DefaultHash<ValueArg>::Hash, | 1399 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
1396 typename TraitsArg = HashTraits<ValueArg> > | 1400 typename TraitsArg = HashTraits<ValueArg> > |
1397 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator>
{ }; | 1401 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator>
{ }; |
1398 | 1402 |
| 1403 template< |
| 1404 typename ValueArg, |
| 1405 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
| 1406 typename TraitsArg = HashTraits<ValueArg> > |
| 1407 class HeapLinkedHashSet : public LinkedHashSet<ValueArg, HashArg, TraitsArg, Hea
pAllocator> { }; |
| 1408 |
1399 template<typename T, size_t inlineCapacity = 0> | 1409 template<typename T, size_t inlineCapacity = 0> |
1400 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { | 1410 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { |
1401 public: | 1411 public: |
1402 HeapVector() { } | 1412 HeapVector() { } |
1403 | 1413 |
1404 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(
size) | 1414 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(
size) |
1405 { | 1415 { |
1406 } | 1416 } |
1407 | 1417 |
1408 HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAlloca
tor>(size, val) | 1418 HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAlloca
tor>(size, val) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 } | 1473 } |
1464 | 1474 |
1465 template<typename U> | 1475 template<typename U> |
1466 void append(const U& other) | 1476 void append(const U& other) |
1467 { | 1477 { |
1468 Deque<T, inlineCapacity, HeapAllocator>::append(other); | 1478 Deque<T, inlineCapacity, HeapAllocator>::append(other); |
1469 } | 1479 } |
1470 }; | 1480 }; |
1471 | 1481 |
1472 template<typename T> | 1482 template<typename T> |
| 1483 bool HeapAllocator::hasDeadMember(Visitor* visitor, const WTF::LinkedHashSetNode
<T>& t) |
| 1484 { |
| 1485 return hasDeadMember(visitor, t.m_value); |
| 1486 } |
| 1487 |
| 1488 template<typename T> |
1473 struct ThreadingTrait<Member<T> > { | 1489 struct ThreadingTrait<Member<T> > { |
1474 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1490 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
1475 }; | 1491 }; |
1476 | 1492 |
1477 template<typename T> | 1493 template<typename T> |
1478 struct ThreadingTrait<WeakMember<T> > { | 1494 struct ThreadingTrait<WeakMember<T> > { |
1479 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1495 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
1480 }; | 1496 }; |
1481 | 1497 |
1482 template<typename Key, typename Value, typename T, typename U, typename V> | 1498 template<typename Key, typename Value, typename T, typename U, typename V> |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 static const GCInfo info; | 1575 static const GCInfo info; |
1560 }; | 1576 }; |
1561 | 1577 |
1562 template<typename T, typename U, typename V> | 1578 template<typename T, typename U, typename V> |
1563 const GCInfo GCInfoTrait<HashSet<T, U, V, HeapAllocator> >::info = { | 1579 const GCInfo GCInfoTrait<HashSet<T, U, V, HeapAllocator> >::info = { |
1564 TraceTrait<HashSet<T, U, V, HeapAllocator> >::trace, | 1580 TraceTrait<HashSet<T, U, V, HeapAllocator> >::trace, |
1565 0, | 1581 0, |
1566 false, // HashSet needs no finalizer. | 1582 false, // HashSet needs no finalizer. |
1567 }; | 1583 }; |
1568 | 1584 |
| 1585 template<typename T, typename U, typename V> |
| 1586 struct GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > { |
| 1587 static const GCInfo* get() { return &info; } |
| 1588 static const GCInfo info; |
| 1589 }; |
| 1590 |
| 1591 template<typename T, typename U, typename V> |
| 1592 const GCInfo GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> >::info = { |
| 1593 TraceTrait<LinkedHashSet<T, U, V, HeapAllocator> >::trace, |
| 1594 LinkedHashSet<T, U, V, HeapAllocator>::finalize, |
| 1595 true, // Needs finalization. The anchor needs to unlink itself from the chai
n. |
| 1596 }; |
| 1597 |
1569 template<typename T> | 1598 template<typename T> |
1570 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > { | 1599 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > { |
1571 static const GCInfo* get() { return &info; } | 1600 static const GCInfo* get() { return &info; } |
1572 static const GCInfo info; | 1601 static const GCInfo info; |
1573 }; | 1602 }; |
1574 | 1603 |
1575 template<typename T> | 1604 template<typename T> |
1576 const GCInfo GCInfoTrait<Vector<T, 0, HeapAllocator> >::info = { | 1605 const GCInfo GCInfoTrait<Vector<T, 0, HeapAllocator> >::info = { |
1577 TraceTrait<Vector<T, 0, HeapAllocator> >::trace, | 1606 TraceTrait<Vector<T, 0, HeapAllocator> >::trace, |
1578 0, | 1607 0, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 static const GCInfo info; | 1676 static const GCInfo info; |
1648 }; | 1677 }; |
1649 | 1678 |
1650 template<typename Table> | 1679 template<typename Table> |
1651 const GCInfo GCInfoTrait<HeapHashTableBacking<Table> >::info = { | 1680 const GCInfo GCInfoTrait<HeapHashTableBacking<Table> >::info = { |
1652 TraceTrait<HeapHashTableBacking<Table> >::trace, | 1681 TraceTrait<HeapHashTableBacking<Table> >::trace, |
1653 HeapHashTableBacking<Table>::finalize, | 1682 HeapHashTableBacking<Table>::finalize, |
1654 Table::ValueTraits::needsDestruction, | 1683 Table::ValueTraits::needsDestruction, |
1655 }; | 1684 }; |
1656 | 1685 |
1657 template<bool markWeakMembersStrongly, typename T, typename Traits> | 1686 template<typename T, typename Traits> |
1658 struct BaseVisitVectorBackingTrait { | 1687 struct BaseVisitVectorBackingTrait { |
1659 static void mark(WebCore::Visitor* visitor, void* self) | 1688 static void mark(WebCore::Visitor* visitor, void* self) |
1660 { | 1689 { |
1661 // The allocator can oversize the allocation a little, according to | 1690 // The allocator can oversize the allocation a little, according to |
1662 // the allocation granularity. The extra size is included in the | 1691 // the allocation granularity. The extra size is included in the |
1663 // payloadSize call below, since there is nowhere to store the | 1692 // payloadSize call below, since there is nowhere to store the |
1664 // originally allocated memory. This assert ensures that visiting the | 1693 // originally allocated memory. This assert ensures that visiting the |
1665 // last bit of memory can't cause trouble. | 1694 // last bit of memory can't cause trouble. |
1666 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); | 1695 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); |
1667 | 1696 |
1668 T* array = reinterpret_cast<T*>(self); | 1697 T* array = reinterpret_cast<T*>(self); |
1669 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 1698 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
1670 // Use the payload size as recorded by the heap to determine how many | 1699 // Use the payload size as recorded by the heap to determine how many |
1671 // elements to mark. | 1700 // elements to mark. |
1672 size_t length = header->payloadSize() / sizeof(T); | 1701 size_t length = header->payloadSize() / sizeof(T); |
1673 for (size_t i = 0; i < length; i++) | 1702 for (size_t i = 0; i < length; i++) |
1674 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, markWeakMembersStrongly, T, Traits>::mark(visitor, array[i]); | 1703 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, T, Traits>::mark(visitor, array[i]); |
1675 } | 1704 } |
1676 }; | 1705 }; |
1677 | 1706 |
1678 template<bool markWeakMembersStrongly, typename Table> | 1707 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
1679 struct BaseVisitHashTableBackingTrait { | 1708 struct BaseVisitHashTableBackingTrait { |
1680 typedef typename Table::ValueType Value; | 1709 typedef typename Table::ValueType Value; |
1681 typedef typename Table::ValueTraits Traits; | 1710 typedef typename Table::ValueTraits Traits; |
1682 static void mark(WebCore::Visitor* visitor, void* self) | 1711 static void mark(WebCore::Visitor* visitor, void* self) |
1683 { | 1712 { |
1684 Value* array = reinterpret_cast<Value*>(self); | 1713 Value* array = reinterpret_cast<Value*>(self); |
1685 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 1714 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
1686 size_t length = header->payloadSize() / sizeof(Value); | 1715 size_t length = header->payloadSize() / sizeof(Value); |
1687 for (size_t i = 0; i < length; i++) { | 1716 for (size_t i = 0; i < length; i++) { |
1688 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | 1717 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) |
1689 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::isWeak, markWeakMembersStrongly, Value, Traits>::mark(visitor, array[i])
; | 1718 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::isWeak, strongify, Value, Traits>::mark(visitor, array[i]); |
1690 } | 1719 } |
1691 } | 1720 } |
1692 }; | 1721 }; |
1693 | 1722 |
1694 template<bool markWeakMembersStrongly, typename Key, typename Value, typename Tr
aits> | 1723 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
1695 struct BaseVisitKeyValuePairTrait { | 1724 struct BaseVisitKeyValuePairTrait { |
1696 static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& s
elf) | 1725 static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& s
elf) |
1697 { | 1726 { |
1698 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && markWeak
MembersStrongly)); | 1727 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); |
1699 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::isWeak, markWeakMembersStrongly, Key, typename Tr
aits::KeyTraits>::mark(visitor, self.key); | 1728 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::isWeak, strongify, Key, typename Traits::KeyTrait
s>::mark(visitor, self.key); |
1700 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::isWeak, markWeakMembersStrongly, Value, typen
ame Traits::ValueTraits>::mark(visitor, self.value); | 1729 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::isWeak, strongify, Value, typename Traits::Va
lueTraits>::mark(visitor, self.value); |
1701 } | 1730 } |
1702 }; | 1731 }; |
1703 | 1732 |
1704 // FFX - Things that don't need marking and have no weak pointers. | 1733 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Traits> |
1705 template<bool markWeakMembersStrongly, typename T, typename U> | 1734 struct BaseVisitLinkedNodeTrait { |
1706 struct CollectionBackingTraceTrait<false, false, markWeakMembersStrongly, T, U>
{ | 1735 static void mark(WebCore::Visitor* visitor, WTF::LinkedHashSetNode<Value>& s
elf) |
| 1736 { |
| 1737 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); |
| 1738 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, strongify, Value, Traits>::mark(visitor, self.m_value); |
| 1739 } |
| 1740 }; |
| 1741 |
| 1742 // Catch-all for things that don't need marking and have no weak pointers. We |
| 1743 // do nothing, even if WeakPointersActStrong. |
| 1744 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U> |
| 1745 struct CollectionBackingTraceTrait<false, false, strongify, T, U> { |
1707 static void mark(Visitor*, const T&) { } | 1746 static void mark(Visitor*, const T&) { } |
1708 static void mark(Visitor*, const void*) { } | 1747 static void mark(Visitor*, const void*) { } |
1709 }; | 1748 }; |
1710 | 1749 |
1711 // FTF - Things that don't need marking. They have weak pointers, but we are | 1750 // Catch-all for things that don't need marking. They have weak pointers, but |
1712 // not marking weak pointers in this object in this GC. | 1751 // we are not marking weak pointers in this object in this GC. |
1713 template<typename T, typename U> | 1752 template<typename T, typename U> |
1714 struct CollectionBackingTraceTrait<false, true, false, T, U> { | 1753 struct CollectionBackingTraceTrait<false, true, WeakPointersActWeak, T, U> { |
1715 static void mark(Visitor*, const T&) { } | 1754 static void mark(Visitor*, const T&) { } |
1716 static void mark(Visitor*, const void*) { } | 1755 static void mark(Visitor*, const void*) { } |
1717 }; | 1756 }; |
1718 | 1757 |
1719 // For each type that we understand we have the FTT case and the TXX case. The | 1758 // For each type that we understand we have the strongified case and the |
1720 // FTT case is where we would not normally need to mark it, but it has weak | 1759 // needsMarking case. The strongified case is where we would not normally need |
1721 // pointers, and we are marking them as strong. The TXX case is the regular | 1760 // to mark it, but it has weak pointers, and we are marking them as strong |
1722 // case for things that need marking. | 1761 // because there is a live iterator that would be disturbed if the collection |
| 1762 // were subject to weak processing right now. The needsMarking case is the |
| 1763 // case for things that need marking, which may also be strongified (eg. for |
| 1764 // a map pair that has a key that is weak and a value that needs marking). |
1723 | 1765 |
1724 // FTT (vector) | 1766 // The body is the same for most objects, but there are two template |
1725 template<typename T, typename Traits> | 1767 // specializations because there is no way to express needsMarking || (isWeak |
1726 struct CollectionBackingTraceTrait<false, true, true, HeapVectorBacking<T, Trait
s>, void> : public BaseVisitVectorBackingTrait<true, T, Traits> { | 1768 // && WeakPointersActStrong) in a single specialization. |
| 1769 |
| 1770 // Hash table that would not normally need marking, but strongified. |
| 1771 template<typename Table> |
| 1772 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, HeapHashT
ableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<WeakPointersAc
tStrong, Table> { |
1727 }; | 1773 }; |
1728 | 1774 |
1729 // TXX (vector) | 1775 // Hash table that needs marking, optionally also strongified. |
1730 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits> | 1776 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Tab
le> |
1731 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapVe
ctorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<markWeakMembe
rsStrongly, T, Traits> { | 1777 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapHashTableBacking
<Table>, void> : public BaseVisitHashTableBackingTrait<strongify, Table> { |
1732 }; | 1778 }; |
1733 | 1779 |
1734 // FTT (hash table) | 1780 // Key-value pair that would not normally need marking, but strongified. |
1735 template<typename Table> | 1781 template<typename Key, typename Value, typename Traits> |
1736 struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Table
>, void> : public BaseVisitHashTableBackingTrait<true, Table> { | 1782 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::KeyV
aluePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<WeakPointersAc
tStrong, Key, Value, Traits> { |
1737 }; | 1783 }; |
1738 | 1784 |
1739 // TXX (hash table) | 1785 // Key value pair that needs marking, optionally also strongified. |
1740 template<bool isWeak, bool markWeakMembersStrongly, typename Table> | 1786 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Key
, typename Value, typename Traits> |
1741 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapHa
shTableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<markWeakMem
bersStrongly, Table> { | 1787 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::KeyValuePair<Ke
y, Value>, Traits> : public BaseVisitKeyValuePairTrait<strongify, Key, Value, Tr
aits> { |
1742 }; | 1788 }; |
1743 | 1789 |
1744 // FTT (key value pair) | 1790 // List hash set node that would not normally need marking, but strongified. |
1745 template<typename Key, typename Value, typename Traits> | 1791 template<typename Value, typename Traits> |
1746 struct CollectionBackingTraceTrait<false, true, true, WTF::KeyValuePair<Key, Val
ue>, Traits> : public BaseVisitKeyValuePairTrait<true, Key, Value, Traits> { | 1792 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::Link
edHashSetNode<Value>, Traits> : public BaseVisitLinkedNodeTrait<WeakPointersActS
trong, Value, Traits> { |
1747 }; | 1793 }; |
1748 | 1794 |
1749 // TXX (key value pair) | 1795 // List hash set node that needs marking, optionally also strongified. |
1750 template<bool isWeak, bool markWeakMembersStrongly, typename Key, typename Value
, typename Traits> | 1796 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Val
ue, typename Traits> |
1751 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, WTF::K
eyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<markWeakMem
bersStrongly, Key, Value, Traits> { | 1797 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::LinkedHashSetNo
de<Value>, Traits> : public BaseVisitLinkedNodeTrait<strongify, Value, Traits> { |
1752 }; | 1798 }; |
1753 | 1799 |
1754 // TFX (member) | 1800 // Vector backing that needs marking. We don't support weak members in vectors, |
1755 template<bool markWeakMembersStrongly, typename T, typename Traits> | 1801 // so we don't need a strongified variant here. |
1756 struct CollectionBackingTraceTrait<true, false, markWeakMembersStrongly, Member<
T>, Traits> { | 1802 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> |
| 1803 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapVectorBacking<T,
Traits>, void> : public BaseVisitVectorBackingTrait<T, Traits> { |
| 1804 }; |
| 1805 |
| 1806 // Member always needs marking, never weak. |
| 1807 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 1808 struct CollectionBackingTraceTrait<true, false, strongify, Member<T>, Traits> { |
1757 static void mark(WebCore::Visitor* visitor, Member<T> self) | 1809 static void mark(WebCore::Visitor* visitor, Member<T> self) |
1758 { | 1810 { |
1759 visitor->mark(self.get()); | 1811 visitor->mark(self.get()); |
1760 } | 1812 } |
1761 }; | 1813 }; |
1762 | 1814 |
1763 // FTT (weak member) | 1815 // Weak member never has needsMarking, always weak, strongified case. |
1764 template<typename T, typename Traits> | 1816 template<typename T, typename Traits> |
1765 struct CollectionBackingTraceTrait<false, true, true, WeakMember<T>, Traits> { | 1817 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WeakMembe
r<T>, Traits> { |
1766 static void mark(WebCore::Visitor* visitor, WeakMember<T> self) | 1818 static void mark(WebCore::Visitor* visitor, WeakMember<T> self) |
1767 { | 1819 { |
1768 // This can mark weak members as if they were strong. The reason we | 1820 // This can mark weak members as if they were strong. The reason we |
1769 // need this is that we don't do weak processing unless we reach the | 1821 // need this is that we don't do weak processing unless we reach the |
1770 // backing only through the hash table. Reaching it in any other way | 1822 // backing only through the hash table. Reaching it in any other way |
1771 // makes it impossible to update the size and deleted slot count of the | 1823 // makes it impossible to update the size and deleted slot count of the |
1772 // table, and exposes us to weak processing during iteration issues. | 1824 // table, and exposes us to weak processing during iteration issues. |
1773 visitor->mark(self.get()); | 1825 visitor->mark(self.get()); |
1774 } | 1826 } |
1775 }; | 1827 }; |
1776 | 1828 |
1777 // Catch-all for things that have a way to trace. For things that contain weak | 1829 // Catch-all for things that have a way to trace. For things that contain weak |
1778 // pointers they will generally be visited weakly even if | 1830 // pointers they will generally be visited weakly even if |
1779 // markWeakMembersStrongly is true. This is what you want. | 1831 // WeakPointersActStrong. This is a deliberate choice: We currently don't |
1780 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits> | 1832 // strongify weak members that are embedded in larger structures, they are just |
1781 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, T, Tra
its> { | 1833 // zeroed during weak processing without the whole structure being |
| 1834 // removed from the collection. |
| 1835 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> |
| 1836 struct CollectionBackingTraceTrait<true, isWeak, strongify, T, Traits> { |
1782 static void mark(WebCore::Visitor* visitor, T& t) | 1837 static void mark(WebCore::Visitor* visitor, T& t) |
1783 { | 1838 { |
1784 TraceTrait<T>::trace(visitor, &t); | 1839 TraceTrait<T>::trace(visitor, &t); |
1785 } | 1840 } |
1786 }; | 1841 }; |
1787 | 1842 |
1788 template<typename T, typename Traits> | 1843 template<typename T, typename Traits> |
1789 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 1844 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
1790 typedef HeapVectorBacking<T, Traits> Backing; | 1845 typedef HeapVectorBacking<T, Traits> Backing; |
1791 static void trace(WebCore::Visitor* visitor, void* self) | 1846 static void trace(WebCore::Visitor* visitor, void* self) |
1792 { | 1847 { |
1793 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectorsOrDequ
es); | 1848 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectorsOrDequ
es); |
1794 if (WTF::ShouldBeTraced<Traits>::value) | 1849 if (WTF::ShouldBeTraced<Traits>::value) |
1795 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals
e, false, HeapVectorBacking<T, Traits>, void>::mark(visitor, self); | 1850 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals
e, WeakPointersActWeak, HeapVectorBacking<T, Traits>, void>::mark(visitor, self)
; |
1796 } | 1851 } |
1797 static void mark(Visitor* visitor, const Backing* backing) | 1852 static void mark(Visitor* visitor, const Backing* backing) |
1798 { | 1853 { |
1799 visitor->mark(backing, &trace); | 1854 visitor->mark(backing, &trace); |
1800 } | 1855 } |
1801 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 1856 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
1802 { | 1857 { |
1803 #ifndef NDEBUG | 1858 #ifndef NDEBUG |
1804 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 1859 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
1805 #endif | 1860 #endif |
1806 } | 1861 } |
1807 }; | 1862 }; |
1808 | 1863 |
1809 // The trace trait for the heap hashtable backing is used when we find a | 1864 // The trace trait for the heap hashtable backing is used when we find a |
1810 // direct pointer to the backing from the conservative stack scanner. This | 1865 // direct pointer to the backing from the conservative stack scanner. This |
1811 // normally indicates that there is an ongoing iteration over the table, and so | 1866 // normally indicates that there is an ongoing iteration over the table, and so |
1812 // we disable weak processing of table entries. When the backing is found | 1867 // we disable weak processing of table entries. When the backing is found |
1813 // through the owning hash table we mark differently, in order to do weak | 1868 // through the owning hash table we mark differently, in order to do weak |
1814 // processing. | 1869 // processing. |
1815 template<typename Table> | 1870 template<typename Table> |
1816 struct TraceTrait<HeapHashTableBacking<Table> > { | 1871 struct TraceTrait<HeapHashTableBacking<Table> > { |
1817 typedef HeapHashTableBacking<Table> Backing; | 1872 typedef HeapHashTableBacking<Table> Backing; |
1818 typedef typename Table::ValueTraits Traits; | 1873 typedef typename Table::ValueTraits Traits; |
1819 static void trace(WebCore::Visitor* visitor, void* self) | 1874 static void trace(WebCore::Visitor* visitor, void* self) |
1820 { | 1875 { |
1821 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 1876 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) |
1822 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, true, Backing, void>::mark(visitor, self); | 1877 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, Backing, void>::mark(visitor, self); |
1823 } | 1878 } |
1824 static void mark(Visitor* visitor, const Backing* backing) | 1879 static void mark(Visitor* visitor, const Backing* backing) |
1825 { | 1880 { |
1826 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 1881 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) |
1827 visitor->mark(backing, &trace); | 1882 visitor->mark(backing, &trace); |
1828 else | 1883 else |
1829 visitor->mark(backing, 0); | 1884 visitor->mark(backing, 0); |
1830 } | 1885 } |
1831 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 1886 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
1832 { | 1887 { |
(...skipping 16 matching lines...) Expand all Loading... |
1849 for (unsigned i = 0; i < length; i++) { | 1904 for (unsigned i = 0; i < length; i++) { |
1850 if (!Table::isEmptyOrDeletedBucket(table[i])) | 1905 if (!Table::isEmptyOrDeletedBucket(table[i])) |
1851 table[i].~Value(); | 1906 table[i].~Value(); |
1852 } | 1907 } |
1853 } | 1908 } |
1854 | 1909 |
1855 template<typename T, typename U, typename V, typename W, typename X> | 1910 template<typename T, typename U, typename V, typename W, typename X> |
1856 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; | 1911 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; |
1857 template<typename T, typename U, typename V> | 1912 template<typename T, typename U, typename V> |
1858 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; | 1913 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; |
| 1914 template<typename T, typename U, typename V> |
| 1915 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashS
et<T, U, V, HeapAllocator> > { }; |
1859 template<typename T, size_t inlineCapacity> | 1916 template<typename T, size_t inlineCapacity> |
1860 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; | 1917 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; |
1861 template<typename T, size_t inlineCapacity> | 1918 template<typename T, size_t inlineCapacity> |
1862 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T,
inlineCapacity, HeapAllocator> > { }; | 1919 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T,
inlineCapacity, HeapAllocator> > { }; |
1863 | 1920 |
1864 template<typename T> | 1921 template<typename T> |
1865 struct IfWeakMember; | 1922 struct IfWeakMember; |
1866 | 1923 |
1867 template<typename T> | 1924 template<typename T> |
1868 struct IfWeakMember { | 1925 struct IfWeakMember { |
(...skipping 11 matching lines...) Expand all Loading... |
1880 // to export. This forces it to export all the methods from ThreadHeap. | 1937 // to export. This forces it to export all the methods from ThreadHeap. |
1881 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); | 1938 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); |
1882 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 1939 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); |
1883 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 1940 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; |
1884 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; | 1941 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; |
1885 #endif | 1942 #endif |
1886 | 1943 |
1887 } | 1944 } |
1888 | 1945 |
1889 #endif // Heap_h | 1946 #endif // Heap_h |
OLD | NEW |