| 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 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 static void deleteArray(void* ptr) | 1514 static void deleteArray(void* ptr) |
| 1515 { | 1515 { |
| 1516 ASSERT_NOT_REACHED(); | 1516 ASSERT_NOT_REACHED(); |
| 1517 } | 1517 } |
| 1518 | 1518 |
| 1519 static bool isAllocationAllowed() | 1519 static bool isAllocationAllowed() |
| 1520 { | 1520 { |
| 1521 return ThreadState::current()->isAllocationAllowed(); | 1521 return ThreadState::current()->isAllocationAllowed(); |
| 1522 } | 1522 } |
| 1523 | 1523 |
| 1524 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } | 1524 template<typename VisitorDispatcher> |
| 1525 static void markNoTracing(VisitorDispatcher visitor, const void* t) { visito
r->markNoTracing(t); } |
| 1525 | 1526 |
| 1526 template<typename T, typename Traits> | 1527 template<typename VisitorDispatcher, typename T, typename Traits> |
| 1527 static void trace(Visitor* visitor, T& t) | 1528 static void trace(VisitorDispatcher visitor, T& t) |
| 1528 { | 1529 { |
| 1529 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); | 1530 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); |
| 1530 } | 1531 } |
| 1531 | 1532 |
| 1532 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) | 1533 template<typename VisitorDispatcher> |
| 1534 static void registerDelayedMarkNoTracing(VisitorDispatcher visitor, const vo
id* object) |
| 1533 { | 1535 { |
| 1534 visitor->registerDelayedMarkNoTracing(object); | 1536 visitor->registerDelayedMarkNoTracing(object); |
| 1535 } | 1537 } |
| 1536 | 1538 |
| 1537 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1539 template<typename VisitorDispatcher> |
| 1540 static void registerWeakMembers(VisitorDispatcher visitor, const void* closu
re, const void* object, WeakPointerCallback callback) |
| 1538 { | 1541 { |
| 1539 visitor->registerWeakMembers(closure, object, callback); | 1542 visitor->registerWeakMembers(closure, object, callback); |
| 1540 } | 1543 } |
| 1541 | 1544 |
| 1542 static void registerWeakTable(Visitor* visitor, const void* closure, Ephemer
onCallback iterationCallback, EphemeronCallback iterationDoneCallback) | 1545 template<typename VisitorDispatcher> |
| 1546 static void registerWeakTable(VisitorDispatcher visitor, const void* closure
, EphemeronCallback iterationCallback, EphemeronCallback iterationDoneCallback) |
| 1543 { | 1547 { |
| 1544 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); | 1548 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); |
| 1545 } | 1549 } |
| 1546 | 1550 |
| 1547 #if ENABLE(ASSERT) | 1551 #if ENABLE(ASSERT) |
| 1548 static bool weakTableRegistered(Visitor* visitor, const void* closure) | 1552 static bool weakTableRegistered(Visitor* visitor, const void* closure) |
| 1549 { | 1553 { |
| 1550 return visitor->weakTableRegistered(closure); | 1554 return visitor->weakTableRegistered(closure); |
| 1551 } | 1555 } |
| 1552 #endif | 1556 #endif |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 namespace WTF { | 2093 namespace WTF { |
| 2090 | 2094 |
| 2091 // Catch-all for types that have a way to trace that don't have special | 2095 // Catch-all for types that have a way to trace that don't have special |
| 2092 // handling for weakness in collections. This means that if this type | 2096 // handling for weakness in collections. This means that if this type |
| 2093 // contains WeakMember fields, they will simply be zeroed, but the entry | 2097 // contains WeakMember fields, they will simply be zeroed, but the entry |
| 2094 // will not be removed from the collection. This always happens for | 2098 // will not be removed from the collection. This always happens for |
| 2095 // things in vectors, which don't currently support special handling of | 2099 // things in vectors, which don't currently support special handling of |
| 2096 // weak elements. | 2100 // weak elements. |
| 2097 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2101 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2098 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ | 2102 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ |
| 2099 static bool trace(blink::Visitor* visitor, T& t) | 2103 template<typename VisitorDispatcher> |
| 2104 static bool trace(VisitorDispatcher visitor, T& t) |
| 2100 { | 2105 { |
| 2101 blink::TraceTrait<T>::trace(visitor, &t); | 2106 blink::TraceTrait<T>::trace(visitor, &t); |
| 2102 return false; | 2107 return false; |
| 2103 } | 2108 } |
| 2104 }; | 2109 }; |
| 2105 | 2110 |
| 2106 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2111 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2107 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { | 2112 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { |
| 2108 static bool trace(blink::Visitor* visitor, blink::Member<T>& t) | 2113 template<typename VisitorDispatcher> |
| 2114 static bool trace(VisitorDispatcher visitor, blink::Member<T>& t) |
| 2109 { | 2115 { |
| 2110 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); | 2116 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); |
| 2111 return false; | 2117 return false; |
| 2112 } | 2118 } |
| 2113 }; | 2119 }; |
| 2114 | 2120 |
| 2115 // Catch-all for things that have HashTrait support for tracing with weakness. | 2121 // Catch-all for things that have HashTrait support for tracing with weakness. |
| 2116 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2122 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2117 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { | 2123 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { |
| 2118 static bool trace(blink::Visitor* visitor, T& t) | 2124 template<typename VisitorDispatcher> |
| 2125 static bool trace(VisitorDispatcher visitor, T& t) |
| 2119 { | 2126 { |
| 2120 return Traits::traceInCollection(visitor, t, strongify); | 2127 return Traits::traceInCollection(visitor, t, strongify); |
| 2121 } | 2128 } |
| 2122 }; | 2129 }; |
| 2123 | 2130 |
| 2124 // Vector backing that needs marking. We don't support weak members in vectors. | 2131 // Vector backing that needs marking. We don't support weak members in vectors. |
| 2125 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2132 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2126 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { | 2133 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { |
| 2127 static bool trace(blink::Visitor* visitor, void* self) | 2134 template<typename VisitorDispatcher> |
| 2135 static bool trace(VisitorDispatcher visitor, void* self) |
| 2128 { | 2136 { |
| 2129 // The allocator can oversize the allocation a little, according to | 2137 // The allocator can oversize the allocation a little, according to |
| 2130 // the allocation granularity. The extra size is included in the | 2138 // the allocation granularity. The extra size is included in the |
| 2131 // payloadSize call below, since there is nowhere to store the | 2139 // payloadSize call below, since there is nowhere to store the |
| 2132 // originally allocated memory. This assert ensures that visiting the | 2140 // originally allocated memory. This assert ensures that visiting the |
| 2133 // last bit of memory can't cause trouble. | 2141 // last bit of memory can't cause trouble. |
| 2134 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc
ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca
use spurious visits"); | 2142 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc
ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca
use spurious visits"); |
| 2135 | 2143 |
| 2136 T* array = reinterpret_cast<T*>(self); | 2144 T* array = reinterpret_cast<T*>(self); |
| 2137 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); | 2145 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); |
| 2138 // Use the payload size as recorded by the heap to determine how many | 2146 // Use the payload size as recorded by the heap to determine how many |
| 2139 // elements to mark. | 2147 // elements to mark. |
| 2140 size_t length = header->payloadSize() / sizeof(T); | 2148 size_t length = header->payloadSize() / sizeof(T); |
| 2141 for (size_t i = 0; i < length; ++i) | 2149 for (size_t i = 0; i < length; ++i) |
| 2142 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); | 2150 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); |
| 2143 return false; | 2151 return false; |
| 2144 } | 2152 } |
| 2145 }; | 2153 }; |
| 2146 | 2154 |
| 2147 // Almost all hash table backings are visited with this specialization. | 2155 // Almost all hash table backings are visited with this specialization. |
| 2148 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 2156 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
| 2149 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { | 2157 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { |
| 2150 using Value = typename Table::ValueType; | 2158 using Value = typename Table::ValueType; |
| 2151 using Traits = typename Table::ValueTraits; | 2159 using Traits = typename Table::ValueTraits; |
| 2152 static bool trace(blink::Visitor* visitor, void* self) | 2160 |
| 2161 template<typename VisitorDispatcher> |
| 2162 static bool trace(VisitorDispatcher visitor, void* self) |
| 2153 { | 2163 { |
| 2154 Value* array = reinterpret_cast<Value*>(self); | 2164 Value* array = reinterpret_cast<Value*>(self); |
| 2155 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); | 2165 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); |
| 2156 size_t length = header->payloadSize() / sizeof(Value); | 2166 size_t length = header->payloadSize() / sizeof(Value); |
| 2157 for (size_t i = 0; i < length; ++i) { | 2167 for (size_t i = 0; i < length; ++i) { |
| 2158 if (!HashTableHelper<Value, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | 2168 if (!HashTableHelper<Value, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) |
| 2159 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value
, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); | 2169 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value
, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); |
| 2160 } | 2170 } |
| 2161 return false; | 2171 return false; |
| 2162 } | 2172 } |
| 2163 }; | 2173 }; |
| 2164 | 2174 |
| 2165 // This specialization of TraceInCollectionTrait is for the backing of | 2175 // This specialization of TraceInCollectionTrait is for the backing of |
| 2166 // HeapListHashSet. This is for the case that we find a reference to the | 2176 // HeapListHashSet. This is for the case that we find a reference to the |
| 2167 // backing from the stack. That probably means we have a GC while we are in a | 2177 // backing from the stack. That probably means we have a GC while we are in a |
| 2168 // ListHashSet method since normal API use does not put pointers to the backing | 2178 // ListHashSet method since normal API use does not put pointers to the backing |
| 2169 // on the stack. | 2179 // on the stack. |
| 2170 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> | 2180 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> |
| 2171 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity>>*, U, V, W, X, Y, blink::HeapAllocator>>, void> { | 2181 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity>>*, U, V, W, X, Y, blink::HeapAllocator>>, void> { |
| 2172 using Node = ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T
, inlineCapacity>>; | 2182 using Node = ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T
, inlineCapacity>>; |
| 2173 using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>; | 2183 using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>; |
| 2174 static bool trace(blink::Visitor* visitor, void* self) | 2184 |
| 2185 template<typename VisitorDispatcher> |
| 2186 static bool trace(VisitorDispatcher visitor, void* self) |
| 2175 { | 2187 { |
| 2176 Node** array = reinterpret_cast<Node**>(self); | 2188 Node** array = reinterpret_cast<Node**>(self); |
| 2177 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); | 2189 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); |
| 2178 size_t length = header->payloadSize() / sizeof(Node*); | 2190 size_t length = header->payloadSize() / sizeof(Node*); |
| 2179 for (size_t i = 0; i < length; ++i) { | 2191 for (size_t i = 0; i < length; ++i) { |
| 2180 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { | 2192 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { |
| 2181 traceListHashSetValue(visitor, array[i]->m_value); | 2193 traceListHashSetValue(visitor, array[i]->m_value); |
| 2182 // Just mark the node without tracing because we already traced | 2194 // Just mark the node without tracing because we already traced |
| 2183 // the contents, and there is no need to trace the next and | 2195 // the contents, and there is no need to trace the next and |
| 2184 // prev fields since iterating over the hash table backing will | 2196 // prev fields since iterating over the hash table backing will |
| 2185 // find the whole chain. | 2197 // find the whole chain. |
| 2186 visitor->markNoTracing(array[i]); | 2198 visitor->markNoTracing(array[i]); |
| 2187 } | 2199 } |
| 2188 } | 2200 } |
| 2189 return false; | 2201 return false; |
| 2190 } | 2202 } |
| 2191 }; | 2203 }; |
| 2192 | 2204 |
| 2193 // Key value pairs, as used in HashMap. To disambiguate template choice we have | 2205 // Key value pairs, as used in HashMap. To disambiguate template choice we have |
| 2194 // to have two versions, first the one with no special weak handling, then the | 2206 // to have two versions, first the one with no special weak handling, then the |
| 2195 // one with weak handling. | 2207 // one with weak handling. |
| 2196 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2208 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 2197 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { | 2209 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { |
| 2198 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2210 template<typename VisitorDispatcher> |
| 2211 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) |
| 2199 { | 2212 { |
| 2200 ASSERT(ShouldBeTraced<Traits>::value); | 2213 ASSERT(ShouldBeTraced<Traits>::value); |
| 2201 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr
aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT
raits>::trace(visitor, self.key); | 2214 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr
aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT
raits>::trace(visitor, self.key); |
| 2202 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value
Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::
ValueTraits>::trace(visitor, self.value); | 2215 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value
Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::
ValueTraits>::trace(visitor, self.value); |
| 2203 return false; | 2216 return false; |
| 2204 } | 2217 } |
| 2205 }; | 2218 }; |
| 2206 | 2219 |
| 2207 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2220 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 2208 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { | 2221 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { |
| 2209 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2222 template<typename VisitorDispatcher> |
| 2223 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) |
| 2210 { | 2224 { |
| 2211 // This is the core of the ephemeron-like functionality. If there is | 2225 // This is the core of the ephemeron-like functionality. If there is |
| 2212 // weakness on the key side then we first check whether there are | 2226 // weakness on the key side then we first check whether there are |
| 2213 // dead weak pointers on that side, and if there are we don't mark the | 2227 // dead weak pointers on that side, and if there are we don't mark the |
| 2214 // value side (yet). Conversely if there is weakness on the value side | 2228 // value side (yet). Conversely if there is weakness on the value side |
| 2215 // we check that first and don't mark the key side yet if we find dead | 2229 // we check that first and don't mark the key side yet if we find dead |
| 2216 // weak pointers. | 2230 // weak pointers. |
| 2217 // Corner case: If there is weakness on both the key and value side, | 2231 // Corner case: If there is weakness on both the key and value side, |
| 2218 // and there are also strong pointers on the both sides then we could | 2232 // and there are also strong pointers on the both sides then we could |
| 2219 // unexpectedly leak. The scenario is that the weak pointer on the key | 2233 // unexpectedly leak. The scenario is that the weak pointer on the key |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2240 if (deadWeakObjectsFoundOnKeySide) | 2254 if (deadWeakObjectsFoundOnKeySide) |
| 2241 return true; | 2255 return true; |
| 2242 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits
::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.value); | 2256 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits
::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.value); |
| 2243 } | 2257 } |
| 2244 }; | 2258 }; |
| 2245 | 2259 |
| 2246 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the | 2260 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the |
| 2247 // template. | 2261 // template. |
| 2248 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2262 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
| 2249 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { | 2263 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { |
| 2250 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2264 template<typename VisitorDispatcher> |
| 2265 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca
tor>& self) |
| 2251 { | 2266 { |
| 2252 ASSERT(ShouldBeTraced<Traits>::value); | 2267 ASSERT(ShouldBeTraced<Traits>::value); |
| 2253 return TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, Va
lue, typename Traits::ValueTraits>::trace(visitor, self.m_value); | 2268 return TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, Va
lue, typename Traits::ValueTraits>::trace(visitor, self.m_value); |
| 2254 } | 2269 } |
| 2255 }; | 2270 }; |
| 2256 | 2271 |
| 2257 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2272 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
| 2258 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { | 2273 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { |
| 2259 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2274 template<typename VisitorDispatcher> |
| 2275 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca
tor>& self) |
| 2260 { | 2276 { |
| 2261 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu
e, typename Traits::ValueTraits>::trace(visitor, self.m_value); | 2277 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu
e, typename Traits::ValueTraits>::trace(visitor, self.m_value); |
| 2262 } | 2278 } |
| 2263 }; | 2279 }; |
| 2264 | 2280 |
| 2265 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of | 2281 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of |
| 2266 // these pointers). | 2282 // these pointers). |
| 2267 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> | 2283 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> |
| 2268 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity>>*, Traits> { | 2284 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity>>*, Traits> { |
| 2269 using Node = ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, i
nlineCapacity>>; | 2285 using Node = ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, i
nlineCapacity>>; |
| 2270 static bool trace(blink::Visitor* visitor, Node* node) | 2286 |
| 2287 template<typename VisitorDispatcher> |
| 2288 static bool trace(VisitorDispatcher visitor, Node* node) |
| 2271 { | 2289 { |
| 2272 traceListHashSetValue(visitor, node->m_value); | 2290 traceListHashSetValue(visitor, node->m_value); |
| 2273 // Just mark the node without tracing because we already traced the | 2291 // Just mark the node without tracing because we already traced the |
| 2274 // contents, and there is no need to trace the next and prev fields | 2292 // contents, and there is no need to trace the next and prev fields |
| 2275 // since iterating over the hash table backing will find the whole | 2293 // since iterating over the hash table backing will find the whole |
| 2276 // chain. | 2294 // chain. |
| 2277 visitor->markNoTracing(node); | 2295 visitor->markNoTracing(node); |
| 2278 return false; | 2296 return false; |
| 2279 } | 2297 } |
| 2280 }; | 2298 }; |
| 2281 | 2299 |
| 2282 } // namespace WTF | 2300 } // namespace WTF |
| 2283 | 2301 |
| 2284 namespace blink { | 2302 namespace blink { |
| 2285 | 2303 |
| 2286 // CollectionBackingTraceTrait. Do nothing for things in collections that don't | 2304 // CollectionBackingTraceTrait. Do nothing for things in collections that don't |
| 2287 // need tracing, or call TraceInCollectionTrait for those that do. | 2305 // need tracing, or call TraceInCollectionTrait for those that do. |
| 2288 | 2306 |
| 2289 // Specialization for things that don't need marking and have no weak pointers. | 2307 // Specialization for things that don't need marking and have no weak pointers. |
| 2290 // We do nothing, even if WTF::WeakPointersActStrong. | 2308 // We do nothing, even if WTF::WeakPointersActStrong. |
| 2291 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> | 2309 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> |
| 2292 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { | 2310 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { |
| 2293 static bool trace(Visitor*, T&) { return false; } | 2311 template<typename VisitorDispatcher> |
| 2312 static bool trace(VisitorDispatcher, T&) { return false; } |
| 2294 }; | 2313 }; |
| 2295 | 2314 |
| 2296 template<typename T> | 2315 template<typename T> |
| 2297 static void verifyGarbageCollectedIfMember(T*) | 2316 static void verifyGarbageCollectedIfMember(T*) |
| 2298 { | 2317 { |
| 2299 } | 2318 } |
| 2300 | 2319 |
| 2301 template<typename T> | 2320 template<typename T> |
| 2302 static void verifyGarbageCollectedIfMember(Member<T>* t) | 2321 static void verifyGarbageCollectedIfMember(Member<T>* t) |
| 2303 { | 2322 { |
| 2304 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "non garbage collected object in membe
r"); | 2323 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "non garbage collected object in membe
r"); |
| 2305 } | 2324 } |
| 2306 | 2325 |
| 2307 // Specialization for things that either need marking or have weak pointers or | 2326 // Specialization for things that either need marking or have weak pointers or |
| 2308 // both. | 2327 // both. |
| 2309 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> | 2328 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
| 2310 struct CollectionBackingTraceTrait { | 2329 struct CollectionBackingTraceTrait { |
| 2311 static bool trace(Visitor* visitor, T&t) | 2330 template<typename VisitorDispatcher> |
| 2331 static bool trace(VisitorDispatcher visitor, T&t) |
| 2312 { | 2332 { |
| 2313 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); | 2333 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); |
| 2314 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); | 2334 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); |
| 2315 } | 2335 } |
| 2316 }; | 2336 }; |
| 2317 | 2337 |
| 2318 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 2338 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
| 2319 // We want to treat the object as a weak object in the sense that it can | 2339 // We want to treat the object as a weak object in the sense that it can |
| 2320 // disappear from hash sets and hash maps. | 2340 // disappear from hash sets and hash maps. |
| 2321 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 2341 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 2322 // Normally whether or not an object needs tracing is inferred | 2342 // Normally whether or not an object needs tracing is inferred |
| 2323 // automatically from the presence of the trace method, but we don't | 2343 // automatically from the presence of the trace method, but we don't |
| 2324 // necessarily have a trace method, and we may not need one because T | 2344 // necessarily have a trace method, and we may not need one because T |
| 2325 // can perhaps only be allocated inside collections, never as independent | 2345 // can perhaps only be allocated inside collections, never as independent |
| 2326 // objects. Explicitly mark this as needing tracing and it will be traced | 2346 // objects. Explicitly mark this as needing tracing and it will be traced |
| 2327 // in collections using the traceInCollection method, which it must have. | 2347 // in collections using the traceInCollection method, which it must have. |
| 2328 template<typename U = void> struct NeedsTracingLazily { | 2348 template<typename U = void> struct NeedsTracingLazily { |
| 2329 static const bool value = true; | 2349 static const bool value = true; |
| 2330 }; | 2350 }; |
| 2331 // The traceInCollection method traces differently depending on whether we | 2351 // The traceInCollection method traces differently depending on whether we |
| 2332 // are strongifying the trace operation. We strongify the trace operation | 2352 // are strongifying the trace operation. We strongify the trace operation |
| 2333 // when there are active iterators on the object. In this case all | 2353 // when there are active iterators on the object. In this case all |
| 2334 // WeakMembers are marked like strong members so that elements do not | 2354 // WeakMembers are marked like strong members so that elements do not |
| 2335 // suddenly disappear during iteration. Returns true if weak pointers to | 2355 // suddenly disappear during iteration. Returns true if weak pointers to |
| 2336 // dead objects were found: In this case any strong pointers were not yet | 2356 // dead objects were found: In this case any strong pointers were not yet |
| 2337 // traced and the entry should be removed from the collection. | 2357 // traced and the entry should be removed from the collection. |
| 2338 static bool traceInCollection(Visitor* visitor, T& t, WTF::ShouldWeakPointer
sBeMarkedStrongly strongify) | 2358 template<typename VisitorDispatcher> |
| 2359 static bool traceInCollection(VisitorDispatcher visitor, T& t, WTF::ShouldWe
akPointersBeMarkedStrongly strongify) |
| 2339 { | 2360 { |
| 2340 return t.traceInCollection(visitor, strongify); | 2361 return t.traceInCollection(visitor, strongify); |
| 2341 } | 2362 } |
| 2342 }; | 2363 }; |
| 2343 | 2364 |
| 2344 template<typename T, typename Traits> | 2365 template<typename T, typename Traits> |
| 2345 struct TraceTrait<HeapVectorBacking<T, Traits>> { | 2366 struct TraceTrait<HeapVectorBacking<T, Traits>> { |
| 2346 using Backing = HeapVectorBacking<T, Traits>; | 2367 using Backing = HeapVectorBacking<T, Traits>; |
| 2347 static void trace(Visitor* visitor, void* self) | 2368 |
| 2369 template<typename VisitorDispatcher> |
| 2370 static void trace(VisitorDispatcher visitor, void* self) |
| 2348 { | 2371 { |
| 2349 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); | 2372 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); |
| 2350 if (WTF::ShouldBeTraced<Traits>::value) | 2373 if (WTF::ShouldBeTraced<Traits>::value) |
| 2351 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | 2374 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
| 2352 } | 2375 } |
| 2353 static void mark(Visitor* visitor, const Backing* backing) | 2376 |
| 2377 template<typename VisitorDispatcher> |
| 2378 static void mark(VisitorDispatcher visitor, const Backing* backing) |
| 2354 { | 2379 { |
| 2355 visitor->mark(backing, &trace); | 2380 visitor->mark(backing, &trace); |
| 2356 } | 2381 } |
| 2357 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2382 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 2358 { | 2383 { |
| 2359 #if ENABLE(ASSERT) | 2384 #if ENABLE(ASSERT) |
| 2360 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::get()); | 2385 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::get()); |
| 2361 #endif | 2386 #endif |
| 2362 } | 2387 } |
| 2363 }; | 2388 }; |
| 2364 | 2389 |
| 2365 // The trace trait for the heap hashtable backing is used when we find a | 2390 // The trace trait for the heap hashtable backing is used when we find a |
| 2366 // direct pointer to the backing from the conservative stack scanner. This | 2391 // direct pointer to the backing from the conservative stack scanner. This |
| 2367 // normally indicates that there is an ongoing iteration over the table, and so | 2392 // normally indicates that there is an ongoing iteration over the table, and so |
| 2368 // we disable weak processing of table entries. When the backing is found | 2393 // we disable weak processing of table entries. When the backing is found |
| 2369 // through the owning hash table we mark differently, in order to do weak | 2394 // through the owning hash table we mark differently, in order to do weak |
| 2370 // processing. | 2395 // processing. |
| 2371 template<typename Table> | 2396 template<typename Table> |
| 2372 struct TraceTrait<HeapHashTableBacking<Table>> { | 2397 struct TraceTrait<HeapHashTableBacking<Table>> { |
| 2373 using Backing = HeapHashTableBacking<Table>; | 2398 using Backing = HeapHashTableBacking<Table>; |
| 2374 using Traits = typename Table::ValueTraits; | 2399 using Traits = typename Table::ValueTraits; |
| 2375 static void trace(Visitor* visitor, void* self) | 2400 |
| 2401 template<typename VisitorDispatcher> |
| 2402 static void trace(VisitorDispatcher visitor, void* self) |
| 2376 { | 2403 { |
| 2377 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2404 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
| 2378 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); | 2405 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); |
| 2379 } | 2406 } |
| 2380 static void mark(Visitor* visitor, const Backing* backing) | 2407 |
| 2408 template<typename VisitorDispatcher> |
| 2409 static void mark(VisitorDispatcher visitor, const Backing* backing) |
| 2381 { | 2410 { |
| 2382 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2411 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
| 2383 visitor->mark(backing, &trace); | 2412 visitor->mark(backing, &trace); |
| 2384 else | 2413 else |
| 2385 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. | 2414 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. |
| 2386 } | 2415 } |
| 2387 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2416 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 2388 { | 2417 { |
| 2389 #if ENABLE(ASSERT) | 2418 #if ENABLE(ASSERT) |
| 2390 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::get()); | 2419 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::get()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2419 template<typename T, size_t inlineCapacity> | 2448 template<typename T, size_t inlineCapacity> |
| 2420 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2449 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
| 2421 template<typename T, size_t inlineCapacity> | 2450 template<typename T, size_t inlineCapacity> |
| 2422 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2451 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
| 2423 template<typename T, typename U, typename V> | 2452 template<typename T, typename U, typename V> |
| 2424 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2453 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
| 2425 | 2454 |
| 2426 } // namespace blink | 2455 } // namespace blink |
| 2427 | 2456 |
| 2428 #endif // Heap_h | 2457 #endif // Heap_h |
| OLD | NEW |