| 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 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 static void markUsingGCInfo(Visitor* visitor, const void* buffer) | 1625 static void markUsingGCInfo(Visitor* visitor, const void* buffer) |
| 1626 { | 1626 { |
| 1627 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr
aceCallback()); | 1627 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr
aceCallback()); |
| 1628 } | 1628 } |
| 1629 | 1629 |
| 1630 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } | 1630 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } |
| 1631 | 1631 |
| 1632 template<typename T, typename Traits> | 1632 template<typename T, typename Traits> |
| 1633 static void trace(Visitor* visitor, T& t) | 1633 static void trace(Visitor* visitor, T& t) |
| 1634 { | 1634 { |
| 1635 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); | |
| 1636 } | 1635 } |
| 1637 | 1636 |
| 1638 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) | 1637 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) |
| 1639 { | 1638 { |
| 1640 visitor->registerDelayedMarkNoTracing(object); | 1639 visitor->registerDelayedMarkNoTracing(object); |
| 1641 } | 1640 } |
| 1642 | 1641 |
| 1643 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1642 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
| 1644 { | 1643 { |
| 1645 visitor->registerWeakMembers(closure, object, callback); | 1644 visitor->registerWeakMembers(closure, object, callback); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1708 | 1707 |
| 1709 private: | 1708 private: |
| 1710 template<typename T, size_t u, typename V> friend class WTF::Vector; | 1709 template<typename T, size_t u, typename V> friend class WTF::Vector; |
| 1711 template<typename T, typename U, typename V, typename W> friend class WTF::H
ashSet; | 1710 template<typename T, typename U, typename V, typename W> friend class WTF::H
ashSet; |
| 1712 template<typename T, typename U, typename V, typename W, typename X, typenam
e Y> friend class WTF::HashMap; | 1711 template<typename T, typename U, typename V, typename W, typename X, typenam
e Y> friend class WTF::HashMap; |
| 1713 }; | 1712 }; |
| 1714 | 1713 |
| 1715 template<typename Value> | 1714 template<typename Value> |
| 1716 static void traceListHashSetValue(Visitor* visitor, Value& value) | 1715 static void traceListHashSetValue(Visitor* visitor, Value& value) |
| 1717 { | 1716 { |
| 1718 // We use the default hash traits for the value in the node, because | |
| 1719 // ListHashSet does not let you specify any specific ones. | |
| 1720 // We don't allow ListHashSet of WeakMember, so we set that one false | |
| 1721 // (there's an assert elsewhere), but we have to specify some value for the | |
| 1722 // strongify template argument, so we specify WTF::WeakPointersActWeak, | |
| 1723 // arbitrarily. | |
| 1724 CollectionBackingTraceTrait<WTF::ShouldBeTraced<WTF::HashTraits<Value> >::va
lue, WTF::NoWeakHandlingInCollections, WTF::WeakPointersActWeak, Value, WTF::Has
hTraits<Value> >::trace(visitor, value); | |
| 1725 } | 1717 } |
| 1726 | 1718 |
| 1727 // The inline capacity is just a dummy template argument to match the off-heap | 1719 // The inline capacity is just a dummy template argument to match the off-heap |
| 1728 // allocator. | 1720 // allocator. |
| 1729 // This inherits from the static-only HeapAllocator trait class, but we do | 1721 // This inherits from the static-only HeapAllocator trait class, but we do |
| 1730 // declare pointers to instances. These pointers are always null, and no | 1722 // declare pointers to instances. These pointers are always null, and no |
| 1731 // objects are instantiated. | 1723 // objects are instantiated. |
| 1732 template<typename ValueArg, size_t inlineCapacity> | 1724 template<typename ValueArg, size_t inlineCapacity> |
| 1733 struct HeapListHashSetAllocator : public HeapAllocator { | 1725 struct HeapListHashSetAllocator : public HeapAllocator { |
| 1734 typedef HeapAllocator TableAllocator; | 1726 typedef HeapAllocator TableAllocator; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2208 // Catch-all for types that have a way to trace that don't have special | 2200 // Catch-all for types that have a way to trace that don't have special |
| 2209 // handling for weakness in collections. This means that if this type | 2201 // handling for weakness in collections. This means that if this type |
| 2210 // contains WeakMember fields, they will simply be zeroed, but the entry | 2202 // contains WeakMember fields, they will simply be zeroed, but the entry |
| 2211 // will not be removed from the collection. This always happens for | 2203 // will not be removed from the collection. This always happens for |
| 2212 // things in vectors, which don't currently support special handling of | 2204 // things in vectors, which don't currently support special handling of |
| 2213 // weak elements. | 2205 // weak elements. |
| 2214 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2206 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2215 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ | 2207 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ |
| 2216 static bool trace(blink::Visitor* visitor, T& t) | 2208 static bool trace(blink::Visitor* visitor, T& t) |
| 2217 { | 2209 { |
| 2218 blink::TraceTrait<T>::trace(visitor, &t); | |
| 2219 return false; | 2210 return false; |
| 2220 } | 2211 } |
| 2221 }; | 2212 }; |
| 2222 | 2213 |
| 2223 // Catch-all for things that have HashTrait support for tracing with weakness. | 2214 // Catch-all for things that have HashTrait support for tracing with weakness. |
| 2224 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2215 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2225 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { | 2216 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { |
| 2226 static bool trace(blink::Visitor* visitor, T& t) | 2217 static bool trace(blink::Visitor* visitor, T& t) |
| 2227 { | 2218 { |
| 2228 return Traits::traceInCollection(visitor, t, strongify); | 2219 return false; |
| 2229 } | 2220 } |
| 2230 }; | 2221 }; |
| 2231 | 2222 |
| 2232 // Vector backing that needs marking. We don't support weak members in vectors. | 2223 // Vector backing that needs marking. We don't support weak members in vectors. |
| 2233 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2224 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 2234 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { | 2225 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { |
| 2235 static bool trace(blink::Visitor* visitor, void* self) | 2226 static bool trace(blink::Visitor* visitor, void* self) |
| 2236 { | 2227 { |
| 2237 // The allocator can oversize the allocation a little, according to | |
| 2238 // the allocation granularity. The extra size is included in the | |
| 2239 // payloadSize call below, since there is nowhere to store the | |
| 2240 // originally allocated memory. This assert ensures that visiting the | |
| 2241 // last bit of memory can't cause trouble. | |
| 2242 COMPILE_ASSERT(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::allo
cationGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCause
SpuriousVisits); | |
| 2243 | |
| 2244 T* array = reinterpret_cast<T*>(self); | |
| 2245 blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHea
der::fromPayload(self); | |
| 2246 // Use the payload size as recorded by the heap to determine how many | |
| 2247 // elements to mark. | |
| 2248 size_t length = header->payloadSize() / sizeof(T); | |
| 2249 for (size_t i = 0; i < length; i++) | |
| 2250 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); | |
| 2251 return false; | 2228 return false; |
| 2252 } | 2229 } |
| 2253 }; | 2230 }; |
| 2254 | 2231 |
| 2255 // Almost all hash table backings are visited with this specialization. | 2232 // Almost all hash table backings are visited with this specialization. |
| 2256 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 2233 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
| 2257 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { | 2234 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { |
| 2258 typedef typename Table::ValueType Value; | 2235 typedef typename Table::ValueType Value; |
| 2259 typedef typename Table::ValueTraits Traits; | 2236 typedef typename Table::ValueTraits Traits; |
| 2260 static bool trace(blink::Visitor* visitor, void* self) | 2237 static bool trace(blink::Visitor* visitor, void* self) |
| 2261 { | 2238 { |
| 2262 Value* array = reinterpret_cast<Value*>(self); | |
| 2263 blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHea
der::fromPayload(self); | |
| 2264 size_t length = header->payloadSize() / sizeof(Value); | |
| 2265 for (size_t i = 0; i < length; i++) { | |
| 2266 if (!HashTableHelper<Value, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | |
| 2267 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value
, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); | |
| 2268 } | |
| 2269 return false; | 2239 return false; |
| 2270 } | 2240 } |
| 2271 }; | 2241 }; |
| 2272 | 2242 |
| 2273 // This specialization of TraceInCollectionTrait is for the backing of | 2243 // This specialization of TraceInCollectionTrait is for the backing of |
| 2274 // HeapListHashSet. This is for the case that we find a reference to the | 2244 // HeapListHashSet. This is for the case that we find a reference to the |
| 2275 // backing from the stack. That probably means we have a GC while we are in a | 2245 // backing from the stack. That probably means we have a GC while we are in a |
| 2276 // ListHashSet method since normal API use does not put pointers to the backing | 2246 // ListHashSet method since normal API use does not put pointers to the backing |
| 2277 // on the stack. | 2247 // on the stack. |
| 2278 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> | 2248 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> |
| 2279 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity> >*, U, V, W, X, Y, blink::HeapAllocator> >, void> { | 2249 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity> >*, U, V, W, X, Y, blink::HeapAllocator> >, void> { |
| 2280 typedef ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T, inl
ineCapacity> > Node; | 2250 typedef ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T, inl
ineCapacity> > Node; |
| 2281 typedef HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator> Table; | 2251 typedef HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator> Table; |
| 2282 static bool trace(blink::Visitor* visitor, void* self) | 2252 static bool trace(blink::Visitor* visitor, void* self) |
| 2283 { | 2253 { |
| 2284 Node** array = reinterpret_cast<Node**>(self); | |
| 2285 blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHea
der::fromPayload(self); | |
| 2286 size_t length = header->payloadSize() / sizeof(Node*); | |
| 2287 for (size_t i = 0; i < length; i++) { | |
| 2288 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { | |
| 2289 traceListHashSetValue(visitor, array[i]->m_value); | |
| 2290 // Just mark the node without tracing because we already traced | |
| 2291 // the contents, and there is no need to trace the next and | |
| 2292 // prev fields since iterating over the hash table backing will | |
| 2293 // find the whole chain. | |
| 2294 visitor->markNoTracing(array[i]); | |
| 2295 } | |
| 2296 } | |
| 2297 return false; | 2254 return false; |
| 2298 } | 2255 } |
| 2299 }; | 2256 }; |
| 2300 | 2257 |
| 2301 // Key value pairs, as used in HashMap. To disambiguate template choice we have | 2258 // Key value pairs, as used in HashMap. To disambiguate template choice we have |
| 2302 // to have two versions, first the one with no special weak handling, then the | 2259 // to have two versions, first the one with no special weak handling, then the |
| 2303 // one with weak handling. | 2260 // one with weak handling. |
| 2304 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2261 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 2305 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { | 2262 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { |
| 2306 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2263 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) |
| 2307 { | 2264 { |
| 2308 ASSERT(ShouldBeTraced<Traits>::value); | |
| 2309 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr
aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT
raits>::trace(visitor, self.key); | |
| 2310 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value
Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::
ValueTraits>::trace(visitor, self.value); | |
| 2311 return false; | 2265 return false; |
| 2312 } | 2266 } |
| 2313 }; | 2267 }; |
| 2314 | 2268 |
| 2315 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2269 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 2316 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { | 2270 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { |
| 2317 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2271 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) |
| 2318 { | 2272 { |
| 2319 // This is the core of the ephemeron-like functionality. If there is | 2273 return false; |
| 2320 // weakness on the key side then we first check whether there are | |
| 2321 // dead weak pointers on that side, and if there are we don't mark the | |
| 2322 // value side (yet). Conversely if there is weakness on the value side | |
| 2323 // we check that first and don't mark the key side yet if we find dead | |
| 2324 // weak pointers. | |
| 2325 // Corner case: If there is weakness on both the key and value side, | |
| 2326 // and there are also strong pointers on the both sides then we could | |
| 2327 // unexpectedly leak. The scenario is that the weak pointer on the key | |
| 2328 // side is alive, which causes the strong pointer on the key side to be | |
| 2329 // marked. If that then results in the object pointed to by the weak | |
| 2330 // pointer on the value side being marked live, then the whole | |
| 2331 // key-value entry is leaked. To avoid unexpected leaking, we disallow | |
| 2332 // this case, but if you run into this assert, please reach out to Blink | |
| 2333 // reviewers, and we may relax it. | |
| 2334 const bool keyIsWeak = Traits::KeyTraits::weakHandlingFlag == WeakHandli
ngInCollections; | |
| 2335 const bool valueIsWeak = Traits::ValueTraits::weakHandlingFlag == WeakHa
ndlingInCollections; | |
| 2336 const bool keyHasStrongRefs = ShouldBeTraced<typename Traits::KeyTraits>
::value; | |
| 2337 const bool valueHasStrongRefs = ShouldBeTraced<typename Traits::ValueTra
its>::value; | |
| 2338 COMPILE_ASSERT(!keyIsWeak || !valueIsWeak || !keyHasStrongRefs || !value
HasStrongRefs, ThisConfigurationWasDisallowedToAvoidUnexpectedLeaks); | |
| 2339 if ((valueIsWeak && !keyIsWeak) || (valueIsWeak && keyIsWeak && !valueHa
sStrongRefs)) { | |
| 2340 // Check value first. | |
| 2341 bool deadWeakObjectsFoundOnValueSide = blink::CollectionBackingTrace
Trait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits::
weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor
, self.value); | |
| 2342 if (deadWeakObjectsFoundOnValueSide) | |
| 2343 return true; | |
| 2344 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Tr
aits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, ty
pename Traits::KeyTraits>::trace(visitor, self.key); | |
| 2345 } | |
| 2346 // Check key first. | |
| 2347 bool deadWeakObjectsFoundOnKeySide = blink::CollectionBackingTraceTrait<
ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandli
ngFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key); | |
| 2348 if (deadWeakObjectsFoundOnKeySide) | |
| 2349 return true; | |
| 2350 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits
::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.value); | |
| 2351 } | 2274 } |
| 2352 }; | 2275 }; |
| 2353 | 2276 |
| 2354 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the | 2277 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the |
| 2355 // template. | 2278 // template. |
| 2356 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2279 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
| 2357 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { | 2280 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { |
| 2358 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2281 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) |
| 2359 { | 2282 { |
| 2360 ASSERT(ShouldBeTraced<Traits>::value); | |
| 2361 blink::TraceTrait<Value>::trace(visitor, &self.m_value); | |
| 2362 return false; | 2283 return false; |
| 2363 } | 2284 } |
| 2364 }; | 2285 }; |
| 2365 | 2286 |
| 2366 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2287 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
| 2367 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { | 2288 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { |
| 2368 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2289 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) |
| 2369 { | 2290 { |
| 2370 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu
e, typename Traits::ValueTraits>::trace(visitor, self.m_value); | 2291 return false; |
| 2371 } | 2292 } |
| 2372 }; | 2293 }; |
| 2373 | 2294 |
| 2374 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the
se pointers). | 2295 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the
se pointers). |
| 2375 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> | 2296 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> |
| 2376 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits>
{ | 2297 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits>
{ |
| 2377 typedef ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, inline
Capacity> > Node; | 2298 typedef ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, inline
Capacity> > Node; |
| 2378 static bool trace(blink::Visitor* visitor, Node* node) | 2299 static bool trace(blink::Visitor* visitor, Node* node) |
| 2379 { | 2300 { |
| 2380 traceListHashSetValue(visitor, node->m_value); | |
| 2381 // Just mark the node without tracing because we already traced the | |
| 2382 // contents, and there is no need to trace the next and prev fields | |
| 2383 // since iterating over the hash table backing will find the whole | |
| 2384 // chain. | |
| 2385 visitor->markNoTracing(node); | |
| 2386 return false; | 2301 return false; |
| 2387 } | 2302 } |
| 2388 }; | 2303 }; |
| 2389 | 2304 |
| 2390 } // namespace WTF | 2305 } // namespace WTF |
| 2391 | 2306 |
| 2392 namespace blink { | 2307 namespace blink { |
| 2393 | 2308 |
| 2394 // CollectionBackingTraceTrait. Do nothing for things in collections that don't | 2309 // CollectionBackingTraceTrait. Do nothing for things in collections that don't |
| 2395 // need tracing, or call TraceInCollectionTrait for those that do. | 2310 // need tracing, or call TraceInCollectionTrait for those that do. |
| 2396 | 2311 |
| 2397 // Specialization for things that don't need marking and have no weak pointers.
We | 2312 // Specialization for things that don't need marking and have no weak pointers.
We |
| 2398 // do nothing, even if WTF::WeakPointersActStrong. | 2313 // do nothing, even if WTF::WeakPointersActStrong. |
| 2399 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> | 2314 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> |
| 2400 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { | 2315 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { |
| 2401 static bool trace(Visitor*, T&) { return false; } | 2316 static bool trace(Visitor*, T&) { return false; } |
| 2402 }; | 2317 }; |
| 2403 | 2318 |
| 2404 // Specialization for things that either need marking or have weak pointers or | 2319 // Specialization for things that either need marking or have weak pointers or |
| 2405 // both. | 2320 // both. |
| 2406 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> | 2321 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
| 2407 struct CollectionBackingTraceTrait { | 2322 struct CollectionBackingTraceTrait { |
| 2408 static bool trace(Visitor* visitor, T&t) | 2323 static bool trace(Visitor* visitor, T&t) |
| 2409 { | 2324 { |
| 2410 Visitor::verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); | 2325 return false; |
| 2411 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); | |
| 2412 } | 2326 } |
| 2413 }; | 2327 }; |
| 2414 | 2328 |
| 2415 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 2329 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
| 2416 // We want to treat the object as a weak object in the sense that it can | 2330 // We want to treat the object as a weak object in the sense that it can |
| 2417 // disappear from hash sets and hash maps. | 2331 // disappear from hash sets and hash maps. |
| 2418 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 2332 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 2419 // Normally whether or not an object needs tracing is inferred | 2333 // Normally whether or not an object needs tracing is inferred |
| 2420 // automatically from the presence of the trace method, but we don't | 2334 // automatically from the presence of the trace method, but we don't |
| 2421 // necessarily have a trace method, and we may not need one because T | 2335 // necessarily have a trace method, and we may not need one because T |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2436 { | 2350 { |
| 2437 return t.traceInCollection(visitor, strongify); | 2351 return t.traceInCollection(visitor, strongify); |
| 2438 } | 2352 } |
| 2439 }; | 2353 }; |
| 2440 | 2354 |
| 2441 template<typename T, typename Traits> | 2355 template<typename T, typename Traits> |
| 2442 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 2356 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
| 2443 typedef HeapVectorBacking<T, Traits> Backing; | 2357 typedef HeapVectorBacking<T, Traits> Backing; |
| 2444 static void trace(Visitor* visitor, void* self) | 2358 static void trace(Visitor* visitor, void* self) |
| 2445 { | 2359 { |
| 2446 COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVector
sOrDeques); | |
| 2447 if (WTF::ShouldBeTraced<Traits>::value) | |
| 2448 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | |
| 2449 } | 2360 } |
| 2450 static void mark(Visitor* visitor, const Backing* backing) | 2361 static void mark(Visitor* visitor, const Backing* backing) |
| 2451 { | 2362 { |
| 2452 visitor->mark(backing, &trace); | |
| 2453 } | |
| 2454 static void checkGCInfo(Visitor* visitor, const Backing* backing) | |
| 2455 { | |
| 2456 #if ENABLE(ASSERT) | |
| 2457 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | |
| 2458 #endif | |
| 2459 } | 2363 } |
| 2460 }; | 2364 }; |
| 2461 | 2365 |
| 2462 // The trace trait for the heap hashtable backing is used when we find a | 2366 // The trace trait for the heap hashtable backing is used when we find a |
| 2463 // direct pointer to the backing from the conservative stack scanner. This | 2367 // direct pointer to the backing from the conservative stack scanner. This |
| 2464 // normally indicates that there is an ongoing iteration over the table, and so | 2368 // normally indicates that there is an ongoing iteration over the table, and so |
| 2465 // we disable weak processing of table entries. When the backing is found | 2369 // we disable weak processing of table entries. When the backing is found |
| 2466 // through the owning hash table we mark differently, in order to do weak | 2370 // through the owning hash table we mark differently, in order to do weak |
| 2467 // processing. | 2371 // processing. |
| 2468 template<typename Table> | 2372 template<typename Table> |
| 2469 struct TraceTrait<HeapHashTableBacking<Table> > { | 2373 struct TraceTrait<HeapHashTableBacking<Table> > { |
| 2470 typedef HeapHashTableBacking<Table> Backing; | 2374 typedef HeapHashTableBacking<Table> Backing; |
| 2471 typedef typename Table::ValueTraits Traits; | 2375 typedef typename Table::ValueTraits Traits; |
| 2472 static void trace(Visitor* visitor, void* self) | 2376 static void trace(Visitor* visitor, void* self) |
| 2473 { | 2377 { |
| 2474 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | |
| 2475 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); | |
| 2476 } | 2378 } |
| 2477 static void mark(Visitor* visitor, const Backing* backing) | 2379 static void mark(Visitor* visitor, const Backing* backing) |
| 2478 { | 2380 { |
| 2479 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | |
| 2480 visitor->mark(backing, &trace); | |
| 2481 else | |
| 2482 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. | |
| 2483 } | |
| 2484 static void checkGCInfo(Visitor* visitor, const Backing* backing) | |
| 2485 { | |
| 2486 #if ENABLE(ASSERT) | |
| 2487 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | |
| 2488 #endif | |
| 2489 } | 2381 } |
| 2490 }; | 2382 }; |
| 2491 | 2383 |
| 2492 template<typename Table> | 2384 template<typename Table> |
| 2493 void HeapHashTableBacking<Table>::finalize(void* pointer) | 2385 void HeapHashTableBacking<Table>::finalize(void* pointer) |
| 2494 { | 2386 { |
| 2495 typedef typename Table::ValueType Value; | |
| 2496 ASSERT(Table::ValueTraits::needsDestruction); | |
| 2497 FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPayload(p
ointer); | |
| 2498 // Use the payload size as recorded by the heap to determine how many | |
| 2499 // elements to finalize. | |
| 2500 size_t length = header->payloadSize() / sizeof(Value); | |
| 2501 Value* table = reinterpret_cast<Value*>(pointer); | |
| 2502 for (unsigned i = 0; i < length; i++) { | |
| 2503 if (!Table::isEmptyOrDeletedBucket(table[i])) | |
| 2504 table[i].~Value(); | |
| 2505 } | |
| 2506 } | 2387 } |
| 2507 | 2388 |
| 2508 template<typename T, typename U, typename V, typename W, typename X> | 2389 template<typename T, typename U, typename V, typename W, typename X> |
| 2509 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; | 2390 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; |
| 2510 template<typename T, typename U, typename V> | 2391 template<typename T, typename U, typename V> |
| 2511 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; | 2392 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; |
| 2512 template<typename T, typename U, typename V> | 2393 template<typename T, typename U, typename V> |
| 2513 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashS
et<T, U, V, HeapAllocator> > { }; | 2394 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashS
et<T, U, V, HeapAllocator> > { }; |
| 2514 template<typename T, size_t inlineCapacity, typename U> | 2395 template<typename T, size_t inlineCapacity, typename U> |
| 2515 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U> > : public GCInfoTrait<
ListHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity> >
> { }; | 2396 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U> > : public GCInfoTrait<
ListHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity> >
> { }; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2530 }; | 2411 }; |
| 2531 | 2412 |
| 2532 template<typename T> | 2413 template<typename T> |
| 2533 struct IfWeakMember<WeakMember<T> > { | 2414 struct IfWeakMember<WeakMember<T> > { |
| 2534 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } | 2415 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } |
| 2535 }; | 2416 }; |
| 2536 | 2417 |
| 2537 } | 2418 } |
| 2538 | 2419 |
| 2539 #endif // Heap_h | 2420 #endif // Heap_h |
| OLD | NEW |