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 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 static void markUsingGCInfo(Visitor* visitor, const void* buffer) | 1444 static void markUsingGCInfo(Visitor* visitor, const void* buffer) |
1445 { | 1445 { |
1446 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr
aceCallback()); | 1446 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr
aceCallback()); |
1447 } | 1447 } |
1448 | 1448 |
1449 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } | 1449 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } |
1450 | 1450 |
1451 template<typename T, typename Traits> | 1451 template<typename T, typename Traits> |
1452 static void trace(Visitor* visitor, T& t) | 1452 static void trace(Visitor* visitor, T& t) |
1453 { | 1453 { |
1454 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, WeakPointersActWeak, T, Traits>::trace(visitor, t); | 1454 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WeakPointersActWeak, T, Traits>::trace(visitor, t); |
1455 } | 1455 } |
1456 | 1456 |
1457 template<typename T> | |
1458 static bool hasDeadMember(Visitor*, const T&) | |
1459 { | |
1460 return false; | |
1461 } | |
1462 | |
1463 template<typename T> | |
1464 static bool hasDeadMember(Visitor* visitor, const Member<T>& t) | |
1465 { | |
1466 ASSERT(visitor->isAlive(t)); | |
1467 return false; | |
1468 } | |
1469 | |
1470 template<typename T> | |
1471 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t) | |
1472 { | |
1473 return !visitor->isAlive(t); | |
1474 } | |
1475 | |
1476 template<typename T, typename U> | |
1477 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t
) | |
1478 { | |
1479 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value); | |
1480 } | |
1481 | |
1482 template<typename T> | |
1483 static bool hasDeadMember(Visitor*, const WTF::LinkedHashSetNode<T>&); | |
1484 | |
1485 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1457 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
1486 { | 1458 { |
1487 visitor->registerWeakMembers(closure, object, callback); | 1459 visitor->registerWeakMembers(closure, object, callback); |
1488 } | 1460 } |
1489 | 1461 |
1490 template<typename T> | 1462 template<typename T> |
1491 struct ResultType { | 1463 struct ResultType { |
1492 typedef T* Type; | 1464 typedef T* Type; |
1493 }; | 1465 }; |
1494 | 1466 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 | 1504 |
1533 template<typename Value> | 1505 template<typename Value> |
1534 static void traceListHashSetValue(Visitor* visitor, Value& value) | 1506 static void traceListHashSetValue(Visitor* visitor, Value& value) |
1535 { | 1507 { |
1536 // We use the default hash traits for the value in the node, because | 1508 // We use the default hash traits for the value in the node, because |
1537 // ListHashSet does not let you specify any specific ones. | 1509 // ListHashSet does not let you specify any specific ones. |
1538 // We don't allow ListHashSet of WeakMember, so we set that one false | 1510 // We don't allow ListHashSet of WeakMember, so we set that one false |
1539 // (there's an assert elsewhere), but we have to specify some value for the | 1511 // (there's an assert elsewhere), but we have to specify some value for the |
1540 // strongify template argument, so we specify WeakPointersActWeak, | 1512 // strongify template argument, so we specify WeakPointersActWeak, |
1541 // arbitrarily. | 1513 // arbitrarily. |
1542 CollectionBackingTraceTrait<WTF::ShouldBeTraced<WTF::HashTraits<Value> >::va
lue, false, WeakPointersActWeak, Value, WTF::HashTraits<Value> >::trace(visitor,
value); | 1514 CollectionBackingTraceTrait<WTF::ShouldBeTraced<WTF::HashTraits<Value> >::va
lue, WTF::NoWeakHandlingInCollections, WeakPointersActWeak, Value, WTF::HashTrai
ts<Value> >::trace(visitor, value); |
1543 } | 1515 } |
1544 | 1516 |
1545 // The inline capacity is just a dummy template argument to match the off-heap | 1517 // The inline capacity is just a dummy template argument to match the off-heap |
1546 // allocator. | 1518 // allocator. |
1547 // This inherits from the static-only HeapAllocator trait class, but we do | 1519 // This inherits from the static-only HeapAllocator trait class, but we do |
1548 // declare pointers to instances. These pointers are always null, and no | 1520 // declare pointers to instances. These pointers are always null, and no |
1549 // objects are instantiated. | 1521 // objects are instantiated. |
1550 template<typename ValueArg, size_t inlineCapacity> | 1522 template<typename ValueArg, size_t inlineCapacity> |
1551 struct HeapListHashSetAllocator : public HeapAllocator { | 1523 struct HeapListHashSetAllocator : public HeapAllocator { |
1552 typedef HeapAllocator TableAllocator; | 1524 typedef HeapAllocator TableAllocator; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 } | 1662 } |
1691 | 1663 |
1692 template<typename U> | 1664 template<typename U> |
1693 void append(const U& other) | 1665 void append(const U& other) |
1694 { | 1666 { |
1695 Deque<T, inlineCapacity, HeapAllocator>::append(other); | 1667 Deque<T, inlineCapacity, HeapAllocator>::append(other); |
1696 } | 1668 } |
1697 }; | 1669 }; |
1698 | 1670 |
1699 template<typename T> | 1671 template<typename T> |
1700 bool HeapAllocator::hasDeadMember(Visitor* visitor, const WTF::LinkedHashSetNode
<T>& t) | |
1701 { | |
1702 return hasDeadMember(visitor, t.m_value); | |
1703 } | |
1704 | |
1705 template<typename T> | |
1706 struct ThreadingTrait<Member<T> > { | 1672 struct ThreadingTrait<Member<T> > { |
1707 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1673 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
1708 }; | 1674 }; |
1709 | 1675 |
1710 template<typename T> | 1676 template<typename T> |
1711 struct ThreadingTrait<WeakMember<T> > { | 1677 struct ThreadingTrait<WeakMember<T> > { |
1712 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1678 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
1713 }; | 1679 }; |
1714 | 1680 |
1715 template<typename Key, typename Value, typename T, typename U, typename V> | 1681 template<typename Key, typename Value, typename T, typename U, typename V> |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2003 Table::ValueTraits::needsDestruction, | 1969 Table::ValueTraits::needsDestruction, |
2004 WTF::IsPolymorphic<TargetType>::value, | 1970 WTF::IsPolymorphic<TargetType>::value, |
2005 #if ENABLE(GC_TRACING) | 1971 #if ENABLE(GC_TRACING) |
2006 TypenameStringTrait<TargetType>::get() | 1972 TypenameStringTrait<TargetType>::get() |
2007 #endif | 1973 #endif |
2008 }; | 1974 }; |
2009 return &info; | 1975 return &info; |
2010 } | 1976 } |
2011 }; | 1977 }; |
2012 | 1978 |
2013 template<typename T, typename Traits> | 1979 // This is for tracing inside collections that have special support for weak |
2014 struct BaseVisitVectorBackingTrait { | 1980 // pointers. This is normally handled through the HashTraits, but it is not |
2015 static void trace(WebCore::Visitor* visitor, void* self) | 1981 // feasible to add methods for handling tracing to the hash traits of WTF |
| 1982 // classes like KeyValuePair, which is used to implement HashMap. This trait |
| 1983 // lets us add custom handling for such classes. |
| 1984 template<WTF::WeakHandlingFlag weakHandlingFlag, ShouldWeakPointersBeMarkedStron
gly strongify, typename T, typename Traits> |
| 1985 struct TraceInCollectionTrait; |
| 1986 |
| 1987 // Catch-all for types that have a way to trace that don't have special |
| 1988 // handling for weakness in collections. This means that if this type |
| 1989 // contains WeakMember fields, they will simply be zeroed, but the entry |
| 1990 // will not be removed from the collection. This always happens for |
| 1991 // things in vectors, which don't currently support special handling of |
| 1992 // weak elements. |
| 1993 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 1994 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, T, Tr
aits> { |
| 1995 static void trace(Visitor* visitor, T& t) |
| 1996 { |
| 1997 TraceTrait<T>::trace(visitor, &t); |
| 1998 } |
| 1999 }; |
| 2000 |
| 2001 // Catch-all for things that have HashTrait support for tracing with weakness. |
| 2002 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2003 struct TraceInCollectionTrait<WTF::WeakHandlingInCollections, strongify, T, Trai
ts> { |
| 2004 static void trace(Visitor* visitor, T& t) |
| 2005 { |
| 2006 Traits::traceInCollection(visitor, t, strongify); |
| 2007 } |
| 2008 }; |
| 2009 |
| 2010 // Vector backing that needs marking. We don't support weak members in vectors. |
| 2011 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2012 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, HeapV
ectorBacking<T, Traits>, void> { |
| 2013 static void trace(Visitor* visitor, void* self) |
2016 { | 2014 { |
2017 // The allocator can oversize the allocation a little, according to | 2015 // The allocator can oversize the allocation a little, according to |
2018 // the allocation granularity. The extra size is included in the | 2016 // the allocation granularity. The extra size is included in the |
2019 // payloadSize call below, since there is nowhere to store the | 2017 // payloadSize call below, since there is nowhere to store the |
2020 // originally allocated memory. This assert ensures that visiting the | 2018 // originally allocated memory. This assert ensures that visiting the |
2021 // last bit of memory can't cause trouble. | 2019 // last bit of memory can't cause trouble. |
2022 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); | 2020 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); |
2023 | 2021 |
2024 T* array = reinterpret_cast<T*>(self); | 2022 T* array = reinterpret_cast<T*>(self); |
2025 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 2023 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
2026 // Use the payload size as recorded by the heap to determine how many | 2024 // Use the payload size as recorded by the heap to determine how many |
2027 // elements to mark. | 2025 // elements to mark. |
2028 size_t length = header->payloadSize() / sizeof(T); | 2026 size_t length = header->payloadSize() / sizeof(T); |
2029 for (size_t i = 0; i < length; i++) | 2027 for (size_t i = 0; i < length; i++) |
2030 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]); | 2028 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]
); |
2031 } | 2029 } |
2032 }; | 2030 }; |
2033 | 2031 |
2034 // Almost all hash table backings are visited with this specialization. | 2032 // Almost all hash table backings are visited with this specialization. |
2035 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 2033 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
2036 struct BaseVisitHashTableBackingTrait { | 2034 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, HeapH
ashTableBacking<Table>, void> { |
2037 typedef typename Table::ValueType Value; | 2035 typedef typename Table::ValueType Value; |
2038 typedef typename Table::ValueTraits Traits; | 2036 typedef typename Table::ValueTraits Traits; |
2039 static void trace(WebCore::Visitor* visitor, void* self) | 2037 static void trace(Visitor* visitor, void* self) |
2040 { | 2038 { |
2041 Value* array = reinterpret_cast<Value*>(self); | 2039 Value* array = reinterpret_cast<Value*>(self); |
2042 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 2040 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
2043 size_t length = header->payloadSize() / sizeof(Value); | 2041 size_t length = header->payloadSize() / sizeof(Value); |
2044 for (size_t i = 0; i < length; i++) { | 2042 for (size_t i = 0; i < length; i++) { |
2045 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | 2043 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) |
2046 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::isWeak, strongify, Value, Traits>::trace(visitor, array[i]); | 2044 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); |
2047 } | 2045 } |
2048 } | 2046 } |
2049 }; | 2047 }; |
2050 | 2048 |
2051 // This specialization of BaseVisitHashTableBackingTrait is for the backing of | 2049 // This specialization of TraceInCollectionTrait is for the backing of |
2052 // HeapListHashSet. This is for the case that we find a reference to the | 2050 // HeapListHashSet. This is for the case that we find a reference to the |
2053 // backing from the stack. That probably means we have a GC while we are in a | 2051 // backing from the stack. That probably means we have a GC while we are in a |
2054 // ListHashSet method since normal API use does not put pointers to the backing | 2052 // ListHashSet method since normal API use does not put pointers to the backing |
2055 // on the stack. | 2053 // on the stack. |
2056 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> | 2054 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> |
2057 struct BaseVisitHashTableBackingTrait<strongify, WTF::HashTable<WTF::ListHashSet
Node<NodeContents, HeapListHashSetAllocator<T, inlineCapacity> >*, U, V, W, X, Y
, HeapAllocator> > { | 2055 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, HeapH
ashTableBacking<WTF::HashTable<WTF::ListHashSetNode<NodeContents, HeapListHashSe
tAllocator<T, inlineCapacity> >*, U, V, W, X, Y, HeapAllocator> >, void> { |
2058 typedef WTF::ListHashSetNode<NodeContents, HeapListHashSetAllocator<T, inlin
eCapacity> > Node; | 2056 typedef WTF::ListHashSetNode<NodeContents, HeapListHashSetAllocator<T, inlin
eCapacity> > Node; |
2059 typedef WTF::HashTable<Node*, U, V, W, X, Y, HeapAllocator> Table; | 2057 typedef WTF::HashTable<Node*, U, V, W, X, Y, HeapAllocator> Table; |
2060 static void trace(WebCore::Visitor* visitor, void* self) | 2058 static void trace(Visitor* visitor, void* self) |
2061 { | 2059 { |
2062 Node** array = reinterpret_cast<Node**>(self); | 2060 Node** array = reinterpret_cast<Node**>(self); |
2063 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 2061 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
2064 size_t length = header->payloadSize() / sizeof(Node*); | 2062 size_t length = header->payloadSize() / sizeof(Node*); |
2065 for (size_t i = 0; i < length; i++) { | 2063 for (size_t i = 0; i < length; i++) { |
2066 if (!WTF::HashTableHelper<Node*, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { | 2064 if (!WTF::HashTableHelper<Node*, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { |
2067 traceListHashSetValue(visitor, array[i]->m_value); | 2065 traceListHashSetValue(visitor, array[i]->m_value); |
2068 // Just mark the node without tracing because we already traced | 2066 // Just mark the node without tracing because we already traced |
2069 // the contents, and there is no need to trace the next and | 2067 // the contents, and there is no need to trace the next and |
2070 // prev fields since iterating over the hash table backing will | 2068 // prev fields since iterating over the hash table backing will |
2071 // find the whole chain. | 2069 // find the whole chain. |
2072 visitor->markNoTracing(array[i]); | 2070 visitor->markNoTracing(array[i]); |
2073 } | 2071 } |
2074 } | 2072 } |
2075 } | 2073 } |
2076 }; | 2074 }; |
2077 | 2075 |
| 2076 // Key value pairs, as used in HashMap. To disambiguate template choice we have |
| 2077 // to have two versions, first the one with no special weak handling, then the |
| 2078 // one with weak handling. |
| 2079 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 2080 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, WTF::
KeyValuePair<Key, Value>, Traits> { |
| 2081 static void trace(Visitor* visitor, WTF::KeyValuePair<Key, Value>& self) |
| 2082 { |
| 2083 ASSERT(WTF::ShouldBeTraced<Traits>::value); |
| 2084 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, WTF::NoWeakHandlingInCollections, strongify, Key, typename Traits::K
eyTraits>::trace(visitor, self.key); |
| 2085 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, WTF::NoWeakHandlingInCollections, strongify, Value, typename Trait
s::ValueTraits>::trace(visitor, self.value); |
| 2086 } |
| 2087 }; |
| 2088 |
2078 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2089 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
2079 struct BaseVisitKeyValuePairTrait { | 2090 struct TraceInCollectionTrait<WTF::WeakHandlingInCollections, strongify, WTF::Ke
yValuePair<Key, Value>, Traits> { |
2080 static void trace(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>&
self) | 2091 static void trace(Visitor* visitor, WTF::KeyValuePair<Key, Value>& self) |
2081 { | 2092 { |
2082 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); | 2093 ASSERT(WTF::ShouldBeTraced<Traits>::value || strongify == WeakPointersAc
tStrong); |
2083 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::isWeak, strongify, Key, typename Traits::KeyTrait
s>::trace(visitor, self.key); | 2094 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, typename Traits
::KeyTraits>::trace(visitor, self.key); |
2084 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::isWeak, strongify, Value, typename Traits::Va
lueTraits>::trace(visitor, self.value); | 2095 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value, typename
Traits::ValueTraits>::trace(visitor, self.value); |
| 2096 } |
| 2097 }; |
| 2098 |
| 2099 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the |
| 2100 // template. |
| 2101 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Traits> |
| 2102 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, WTF::
LinkedHashSetNode<Value>, Traits> { |
| 2103 static void trace(Visitor* visitor, WTF::LinkedHashSetNode<Value>& self) |
| 2104 { |
| 2105 ASSERT(WTF::ShouldBeTraced<Traits>::value); |
| 2106 TraceTrait<Value>::trace(visitor, &self.m_value); |
2085 } | 2107 } |
2086 }; | 2108 }; |
2087 | 2109 |
2088 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Traits> | 2110 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Traits> |
2089 struct BaseVisitLinkedNodeTrait { | 2111 struct TraceInCollectionTrait<WTF::WeakHandlingInCollections, strongify, WTF::Li
nkedHashSetNode<Value>, Traits> { |
2090 static void trace(WebCore::Visitor* visitor, WTF::LinkedHashSetNode<Value>&
self) | 2112 static void trace(Visitor* visitor, WTF::LinkedHashSetNode<Value>& self) |
2091 { | 2113 { |
2092 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); | 2114 ASSERT(WTF::ShouldBeTraced<Traits>::value || strongify == WeakPointersAc
tStrong); |
2093 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, strongify, Value, Traits>::trace(visitor, self.m_value); | 2115 TraceInCollectionTrait<WTF::WeakHandlingInCollections, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.m_value); |
2094 } | 2116 } |
2095 }; | 2117 }; |
2096 | 2118 |
2097 // Catch-all for things that don't need marking and have no weak pointers. We | |
2098 // do nothing, even if WeakPointersActStrong. | |
2099 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U> | |
2100 struct CollectionBackingTraceTrait<false, false, strongify, T, U> { | |
2101 static void trace(Visitor*, const T&) { } | |
2102 static void trace(Visitor*, const void*) { } | |
2103 }; | |
2104 | |
2105 // Catch-all for things that don't need marking. They have weak pointers, but | |
2106 // we are not marking weak pointers in this object in this GC. | |
2107 template<typename T, typename U> | |
2108 struct CollectionBackingTraceTrait<false, true, WeakPointersActWeak, T, U> { | |
2109 static void trace(Visitor*, const T&) { } | |
2110 static void trace(Visitor*, const void*) { } | |
2111 }; | |
2112 | |
2113 // For each type that we understand we have the strongified case and the | |
2114 // needsMarking case. The strongified case is where we would not normally need | |
2115 // to mark it, but it has weak pointers, and we are marking them as strong | |
2116 // because there is a live iterator that would be disturbed if the collection | |
2117 // were subject to weak processing right now. The needsMarking case is the | |
2118 // case for things that need marking, which may also be strongified (eg. for | |
2119 // a map pair that has a key that is weak and a value that needs marking). | |
2120 | |
2121 // The body is the same for most objects, but there are two template | |
2122 // specializations because there is no way to express needsMarking || (isWeak | |
2123 // && WeakPointersActStrong) in a single specialization. | |
2124 | |
2125 // Hash table that would not normally need marking, but strongified. | |
2126 template<typename Table> | |
2127 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, HeapHashT
ableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<WeakPointersAc
tStrong, Table> { | |
2128 }; | |
2129 | |
2130 // Hash table that needs marking, optionally also strongified. | |
2131 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Tab
le> | |
2132 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapHashTableBacking
<Table>, void> : public BaseVisitHashTableBackingTrait<strongify, Table> { | |
2133 }; | |
2134 | |
2135 // Key-value pair that would not normally need marking, but strongified. | |
2136 template<typename Key, typename Value, typename Traits> | |
2137 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::KeyV
aluePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<WeakPointersAc
tStrong, Key, Value, Traits> { | |
2138 }; | |
2139 | |
2140 // Key value pair that needs marking, optionally also strongified. | |
2141 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Key
, typename Value, typename Traits> | |
2142 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::KeyValuePair<Ke
y, Value>, Traits> : public BaseVisitKeyValuePairTrait<strongify, Key, Value, Tr
aits> { | |
2143 }; | |
2144 | |
2145 // Linked hash set node that would not normally need marking, but strongified. | |
2146 template<typename Value, typename Traits> | |
2147 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::Link
edHashSetNode<Value>, Traits> : public BaseVisitLinkedNodeTrait<WeakPointersActS
trong, Value, Traits> { | |
2148 }; | |
2149 | |
2150 // Linked hash set node that needs marking, optionally also strongified. | |
2151 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Val
ue, typename Traits> | |
2152 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::LinkedHashSetNo
de<Value>, Traits> : public BaseVisitLinkedNodeTrait<strongify, Value, Traits> { | |
2153 }; | |
2154 | |
2155 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the
se pointers). | 2119 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the
se pointers). |
2156 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> | 2120 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> |
2157 struct CollectionBackingTraceTrait<true, false, strongify, WTF::ListHashSetNode<
Value, HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits> { | 2121 struct TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, strongify, WTF::
ListHashSetNode<Value, HeapListHashSetAllocator<Value, inlineCapacity> >*, Trait
s> { |
2158 typedef WTF::ListHashSetNode<Value, HeapListHashSetAllocator<Value, inlineCa
pacity> > Node; | 2122 typedef WTF::ListHashSetNode<Value, HeapListHashSetAllocator<Value, inlineCa
pacity> > Node; |
2159 static void trace(WebCore::Visitor* visitor, Node* node) | 2123 static void trace(Visitor* visitor, Node* node) |
2160 { | 2124 { |
2161 traceListHashSetValue(visitor, node->m_value); | 2125 traceListHashSetValue(visitor, node->m_value); |
2162 // Just mark the node without tracing because we already traced the | 2126 // Just mark the node without tracing because we already traced the |
2163 // contents, and there is no need to trace the next and prev fields | 2127 // contents, and there is no need to trace the next and prev fields |
2164 // since iterating over the hash table backing will find the whole | 2128 // since iterating over the hash table backing will find the whole |
2165 // chain. | 2129 // chain. |
2166 visitor->markNoTracing(node); | 2130 visitor->markNoTracing(node); |
2167 } | 2131 } |
2168 }; | 2132 }; |
2169 | 2133 |
2170 // Vector backing that needs marking. We don't support weak members in vectors, | 2134 // FIXME: oilpan: Perhaps we don't need this any more. |
2171 // so we don't need a strongified variant here. | 2135 // Catch-all for things that don't need marking and have no weak pointers. We |
2172 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> | 2136 // do nothing, even if WeakPointersActStrong. |
2173 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapVectorBacking<T,
Traits>, void> : public BaseVisitVectorBackingTrait<T, Traits> { | 2137 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U> |
| 2138 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, U> { |
| 2139 static void trace(Visitor*, T&) { } |
2174 }; | 2140 }; |
2175 | 2141 |
2176 // Member always needs marking, never weak. | 2142 // Catch-all for things that don't need marking. They have weak pointers, but |
2177 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2143 // we are not marking weak pointers in this object in this GC. |
2178 struct CollectionBackingTraceTrait<true, false, strongify, Member<T>, Traits> { | 2144 template<typename T, typename U> |
2179 static void trace(WebCore::Visitor* visitor, Member<T> self) | 2145 struct CollectionBackingTraceTrait<false, WTF::WeakHandlingInCollections, WeakPo
intersActWeak, T, U> { |
2180 { | 2146 static void trace(Visitor*, T&) { } |
2181 visitor->mark(self.get()); | |
2182 } | |
2183 }; | 2147 }; |
2184 | 2148 |
2185 // Weak member never has needsMarking, always weak, strongified case. | 2149 // Things that need marking because they contain weak pointers that we are makin
g |
| 2150 // strong for this GC because there is an outstanding iterator that would be |
| 2151 // disturbed if we started removing entries from the colletion. |
2186 template<typename T, typename Traits> | 2152 template<typename T, typename Traits> |
2187 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WeakMembe
r<T>, Traits> { | 2153 struct CollectionBackingTraceTrait<false, WTF::WeakHandlingInCollections, WeakPo
intersActStrong, T, Traits> { |
2188 static void trace(WebCore::Visitor* visitor, WeakMember<T> self) | 2154 static void trace(Visitor* visitor, T& t) { TraceInCollectionTrait<WTF::Weak
HandlingInCollections, WeakPointersActStrong, T, Traits>::trace(visitor, t); } |
2189 { | 2155 static void trace(Visitor* visitor, void* t) { TraceInCollectionTrait<WTF::W
eakHandlingInCollections, WeakPointersActStrong, T, Traits>::trace(visitor, t);
} |
2190 // This can mark weak members as if they were strong. The reason we | |
2191 // need this is that we don't do weak processing unless we reach the | |
2192 // backing only through the hash table. Reaching it in any other way | |
2193 // makes it impossible to update the size and deleted slot count of the | |
2194 // table, and exposes us to weak processing during iteration issues. | |
2195 visitor->mark(self.get()); | |
2196 } | |
2197 }; | 2156 }; |
2198 | 2157 |
2199 // Catch-all for things that have a way to trace. For things that contain weak | 2158 // Things that need marking because they contain strong pointers |
2200 // pointers they will generally be visited weakly even if | 2159 template<WTF::WeakHandlingFlag weakHandlingFlag, ShouldWeakPointersBeMarkedStron
gly strongify, typename T, typename Traits> |
2201 // WeakPointersActStrong. This is a deliberate choice: We currently don't | 2160 struct CollectionBackingTraceTrait<true, weakHandlingFlag, strongify, T, Traits>
{ |
2202 // strongify weak members that are embedded in larger structures, they are just | 2161 static void trace(Visitor* visitor, T& t) { TraceInCollectionTrait<weakHandl
ingFlag, strongify, T, Traits>::trace(visitor, t); } |
2203 // zeroed during weak processing without the whole structure being | 2162 template <typename U> |
2204 // removed from the collection. | 2163 static void trace(Visitor* visitor, U* t) { TraceInCollectionTrait<weakHandl
ingFlag, strongify, T, Traits>::trace(visitor, T(t)); } |
2205 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> | 2164 }; |
2206 struct CollectionBackingTraceTrait<true, isWeak, strongify, T, Traits> { | 2165 |
2207 static void trace(WebCore::Visitor* visitor, T& t) | 2166 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
| 2167 // We want to treat the object as a weak object in the sense that it can |
| 2168 // disappear from hash sets and hash maps. |
| 2169 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 2170 // Normally whether or not an object needs tracing is inferred |
| 2171 // automatically from the presence of the trace method, but we don't |
| 2172 // necessarily have a trace method, and we may not need one because T |
| 2173 // can perhaps only be allocated inside collections, never as indpendent |
| 2174 // objects. Explicitly mark this as needing tracing and it will be traced |
| 2175 // in collections using the traceInCollection method, which it must have. |
| 2176 template<typename U = void> struct NeedsTracingLazily { |
| 2177 static const bool value = true; |
| 2178 }; |
| 2179 // This method is called at the end of GC to test which elements should be |
| 2180 // removed from the collection. It returns true if the object contains |
| 2181 // non-live pointers. If this method incorrectly returns false, then we can |
| 2182 // have dangerous dangling pointers! |
| 2183 template<typename Visitor> static bool shouldRemoveFromCollection(Visitor* v
isitor, T& t) |
2208 { | 2184 { |
2209 TraceTrait<T>::trace(visitor, &t); | 2185 return t.shouldRemoveFromCollection(visitor); |
| 2186 } |
| 2187 // The traceInCollection method traces differently depending on whether we |
| 2188 // are strongifying the trace operation. We strongify the trace operation |
| 2189 // when there are active iterators on the object. In this case all |
| 2190 // WeakMembers are marked like strong members so that elements do not |
| 2191 // suddenly disappear during iteration. |
| 2192 static void traceInCollection(WebCore::Visitor* visitor, T& t, WebCore::Shou
ldWeakPointersBeMarkedStrongly strongify) |
| 2193 { |
| 2194 t.traceInCollection(visitor, strongify); |
2210 } | 2195 } |
2211 }; | 2196 }; |
2212 | 2197 |
2213 template<typename T, typename Traits> | 2198 template<typename T, typename Traits> |
2214 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 2199 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
2215 typedef HeapVectorBacking<T, Traits> Backing; | 2200 typedef HeapVectorBacking<T, Traits> Backing; |
2216 static void trace(WebCore::Visitor* visitor, void* self) | 2201 static void trace(Visitor* visitor, void* self) |
2217 { | 2202 { |
2218 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectorsOrDequ
es); | 2203 COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVector
sOrDeques); |
2219 if (WTF::ShouldBeTraced<Traits>::value) | 2204 if (WTF::ShouldBeTraced<Traits>::value) |
2220 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals
e, WeakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self
); | 2205 TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WeakPointer
sActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
2221 } | 2206 } |
2222 static void mark(Visitor* visitor, const Backing* backing) | 2207 static void mark(Visitor* visitor, const Backing* backing) |
2223 { | 2208 { |
2224 visitor->mark(backing, &trace); | 2209 visitor->mark(backing, &trace); |
2225 } | 2210 } |
2226 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2211 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
2227 { | 2212 { |
2228 #ifndef NDEBUG | 2213 #ifndef NDEBUG |
2229 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 2214 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
2230 #endif | 2215 #endif |
2231 } | 2216 } |
2232 }; | 2217 }; |
2233 | 2218 |
2234 // The trace trait for the heap hashtable backing is used when we find a | 2219 // The trace trait for the heap hashtable backing is used when we find a |
2235 // direct pointer to the backing from the conservative stack scanner. This | 2220 // direct pointer to the backing from the conservative stack scanner. This |
2236 // normally indicates that there is an ongoing iteration over the table, and so | 2221 // normally indicates that there is an ongoing iteration over the table, and so |
2237 // we disable weak processing of table entries. When the backing is found | 2222 // we disable weak processing of table entries. When the backing is found |
2238 // through the owning hash table we mark differently, in order to do weak | 2223 // through the owning hash table we mark differently, in order to do weak |
2239 // processing. | 2224 // processing. |
2240 template<typename Table> | 2225 template<typename Table> |
2241 struct TraceTrait<HeapHashTableBacking<Table> > { | 2226 struct TraceTrait<HeapHashTableBacking<Table> > { |
2242 typedef HeapHashTableBacking<Table> Backing; | 2227 typedef HeapHashTableBacking<Table> Backing; |
2243 typedef typename Table::ValueTraits Traits; | 2228 typedef typename Table::ValueTraits Traits; |
2244 static void trace(WebCore::Visitor* visitor, void* self) | 2229 static void trace(Visitor* visitor, void* self) |
2245 { | 2230 { |
2246 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 2231 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
2247 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, Backing, void>::trace(visitor, self); | 2232 TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WeakPointer
sActStrong, Backing, void>::trace(visitor, self); |
2248 } | 2233 } |
2249 static void mark(Visitor* visitor, const Backing* backing) | 2234 static void mark(Visitor* visitor, const Backing* backing) |
2250 { | 2235 { |
2251 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 2236 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
2252 visitor->mark(backing, &trace); | 2237 visitor->mark(backing, &trace); |
2253 else | 2238 else |
2254 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. | 2239 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. |
2255 } | 2240 } |
2256 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2241 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
2257 { | 2242 { |
2258 #ifndef NDEBUG | 2243 #ifndef NDEBUG |
2259 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 2244 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
2260 #endif | 2245 #endif |
2261 } | 2246 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2311 // to export. This forces it to export all the methods from ThreadHeap. | 2296 // to export. This forces it to export all the methods from ThreadHeap. |
2312 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); | 2297 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); |
2313 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 2298 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); |
2314 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 2299 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; |
2315 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; | 2300 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; |
2316 #endif | 2301 #endif |
2317 | 2302 |
2318 } | 2303 } |
2319 | 2304 |
2320 #endif // Heap_h | 2305 #endif // Heap_h |
OLD | NEW |