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 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 static void deleteArray(void* ptr) | 1455 static void deleteArray(void* ptr) |
1456 { | 1456 { |
1457 ASSERT_NOT_REACHED(); | 1457 ASSERT_NOT_REACHED(); |
1458 } | 1458 } |
1459 | 1459 |
1460 static bool isAllocationAllowed() | 1460 static bool isAllocationAllowed() |
1461 { | 1461 { |
1462 return ThreadState::current()->isAllocationAllowed(); | 1462 return ThreadState::current()->isAllocationAllowed(); |
1463 } | 1463 } |
1464 | 1464 |
1465 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } | 1465 template<typename VisitorDispatcher> |
| 1466 static void markNoTracing(VisitorDispatcher visitor, const void* t) { visito
r->markNoTracing(t); } |
1466 | 1467 |
1467 template<typename T, typename Traits> | 1468 template<typename VisitorDispatcher, typename T, typename Traits> |
1468 static void trace(Visitor* visitor, T& t) | 1469 static void trace(VisitorDispatcher visitor, T& t) |
1469 { | 1470 { |
1470 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); | 1471 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); |
1471 } | 1472 } |
1472 | 1473 |
1473 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) | 1474 template<typename VisitorDispatcher> |
| 1475 static void registerDelayedMarkNoTracing(VisitorDispatcher visitor, const vo
id* object) |
1474 { | 1476 { |
1475 visitor->registerDelayedMarkNoTracing(object); | 1477 visitor->registerDelayedMarkNoTracing(object); |
1476 } | 1478 } |
1477 | 1479 |
1478 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1480 template<typename VisitorDispatcher> |
| 1481 static void registerWeakMembers(VisitorDispatcher visitor, const void* closu
re, const void* object, WeakPointerCallback callback) |
1479 { | 1482 { |
1480 visitor->registerWeakMembers(closure, object, callback); | 1483 visitor->registerWeakMembers(closure, object, callback); |
1481 } | 1484 } |
1482 | 1485 |
1483 static void registerWeakTable(Visitor* visitor, const void* closure, Ephemer
onCallback iterationCallback, EphemeronCallback iterationDoneCallback) | 1486 template<typename VisitorDispatcher> |
| 1487 static void registerWeakTable(VisitorDispatcher visitor, const void* closure
, EphemeronCallback iterationCallback, EphemeronCallback iterationDoneCallback) |
1484 { | 1488 { |
1485 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); | 1489 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); |
1486 } | 1490 } |
1487 | 1491 |
1488 #if ENABLE(ASSERT) | 1492 #if ENABLE(ASSERT) |
1489 static bool weakTableRegistered(Visitor* visitor, const void* closure) | 1493 static bool weakTableRegistered(Visitor* visitor, const void* closure) |
1490 { | 1494 { |
1491 return visitor->weakTableRegistered(closure); | 1495 return visitor->weakTableRegistered(closure); |
1492 } | 1496 } |
1493 #endif | 1497 #endif |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 namespace WTF { | 2034 namespace WTF { |
2031 | 2035 |
2032 // Catch-all for types that have a way to trace that don't have special | 2036 // Catch-all for types that have a way to trace that don't have special |
2033 // handling for weakness in collections. This means that if this type | 2037 // handling for weakness in collections. This means that if this type |
2034 // contains WeakMember fields, they will simply be zeroed, but the entry | 2038 // contains WeakMember fields, they will simply be zeroed, but the entry |
2035 // will not be removed from the collection. This always happens for | 2039 // will not be removed from the collection. This always happens for |
2036 // things in vectors, which don't currently support special handling of | 2040 // things in vectors, which don't currently support special handling of |
2037 // weak elements. | 2041 // weak elements. |
2038 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2042 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2039 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ | 2043 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ |
2040 static bool trace(blink::Visitor* visitor, T& t) | 2044 template<typename VisitorDispatcher> |
| 2045 static bool trace(VisitorDispatcher visitor, T& t) |
2041 { | 2046 { |
2042 blink::TraceTrait<T>::trace(visitor, &t); | 2047 blink::TraceTrait<T>::trace(visitor, &t); |
2043 return false; | 2048 return false; |
2044 } | 2049 } |
2045 }; | 2050 }; |
2046 | 2051 |
2047 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2052 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2048 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { | 2053 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { |
2049 static bool trace(blink::Visitor* visitor, blink::Member<T>& t) | 2054 template<typename VisitorDispatcher> |
| 2055 static bool trace(VisitorDispatcher visitor, blink::Member<T>& t) |
2050 { | 2056 { |
2051 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); | 2057 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); |
2052 return false; | 2058 return false; |
2053 } | 2059 } |
2054 }; | 2060 }; |
2055 | 2061 |
2056 // Catch-all for things that have HashTrait support for tracing with weakness. | 2062 // Catch-all for things that have HashTrait support for tracing with weakness. |
2057 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2063 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2058 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { | 2064 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { |
2059 static bool trace(blink::Visitor* visitor, T& t) | 2065 template<typename VisitorDispatcher> |
| 2066 static bool trace(VisitorDispatcher visitor, T& t) |
2060 { | 2067 { |
2061 return Traits::traceInCollection(visitor, t, strongify); | 2068 return Traits::traceInCollection(visitor, t, strongify); |
2062 } | 2069 } |
2063 }; | 2070 }; |
2064 | 2071 |
2065 // Vector backing that needs marking. We don't support weak members in vectors. | 2072 // Vector backing that needs marking. We don't support weak members in vectors. |
2066 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2073 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2067 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { | 2074 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { |
2068 static bool trace(blink::Visitor* visitor, void* self) | 2075 template<typename VisitorDispatcher> |
| 2076 static bool trace(VisitorDispatcher visitor, void* self) |
2069 { | 2077 { |
2070 // The allocator can oversize the allocation a little, according to | 2078 // The allocator can oversize the allocation a little, according to |
2071 // the allocation granularity. The extra size is included in the | 2079 // the allocation granularity. The extra size is included in the |
2072 // payloadSize call below, since there is nowhere to store the | 2080 // payloadSize call below, since there is nowhere to store the |
2073 // originally allocated memory. This assert ensures that visiting the | 2081 // originally allocated memory. This assert ensures that visiting the |
2074 // last bit of memory can't cause trouble. | 2082 // last bit of memory can't cause trouble. |
2075 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc
ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca
use spurious visits"); | 2083 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc
ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca
use spurious visits"); |
2076 | 2084 |
2077 T* array = reinterpret_cast<T*>(self); | 2085 T* array = reinterpret_cast<T*>(self); |
2078 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); | 2086 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); |
2079 // Use the payload size as recorded by the heap to determine how many | 2087 // Use the payload size as recorded by the heap to determine how many |
2080 // elements to mark. | 2088 // elements to mark. |
2081 size_t length = header->payloadSize() / sizeof(T); | 2089 size_t length = header->payloadSize() / sizeof(T); |
2082 for (size_t i = 0; i < length; ++i) | 2090 for (size_t i = 0; i < length; ++i) |
2083 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); | 2091 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); |
2084 return false; | 2092 return false; |
2085 } | 2093 } |
2086 }; | 2094 }; |
2087 | 2095 |
2088 // Almost all hash table backings are visited with this specialization. | 2096 // Almost all hash table backings are visited with this specialization. |
2089 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 2097 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
2090 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { | 2098 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<Table>, void> { |
2091 using Value = typename Table::ValueType; | 2099 using Value = typename Table::ValueType; |
2092 using Traits = typename Table::ValueTraits; | 2100 using Traits = typename Table::ValueTraits; |
2093 static bool trace(blink::Visitor* visitor, void* self) | 2101 |
| 2102 template<typename VisitorDispatcher> |
| 2103 static bool trace(VisitorDispatcher visitor, void* self) |
2094 { | 2104 { |
2095 Value* array = reinterpret_cast<Value*>(self); | 2105 Value* array = reinterpret_cast<Value*>(self); |
2096 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); | 2106 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); |
2097 size_t length = header->payloadSize() / sizeof(Value); | 2107 size_t length = header->payloadSize() / sizeof(Value); |
2098 for (size_t i = 0; i < length; ++i) { | 2108 for (size_t i = 0; i < length; ++i) { |
2099 if (!HashTableHelper<Value, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | 2109 if (!HashTableHelper<Value, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) |
2100 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value
, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); | 2110 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value
, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]); |
2101 } | 2111 } |
2102 return false; | 2112 return false; |
2103 } | 2113 } |
2104 }; | 2114 }; |
2105 | 2115 |
2106 // This specialization of TraceInCollectionTrait is for the backing of | 2116 // This specialization of TraceInCollectionTrait is for the backing of |
2107 // HeapListHashSet. This is for the case that we find a reference to the | 2117 // HeapListHashSet. This is for the case that we find a reference to the |
2108 // backing from the stack. That probably means we have a GC while we are in a | 2118 // backing from the stack. That probably means we have a GC while we are in a |
2109 // ListHashSet method since normal API use does not put pointers to the backing | 2119 // ListHashSet method since normal API use does not put pointers to the backing |
2110 // on the stack. | 2120 // on the stack. |
2111 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> | 2121 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si
ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X,
typename Y> |
2112 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity>>*, U, V, W, X, Y, blink::HeapAllocator>>, void> { | 2122 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet
Allocator<T, inlineCapacity>>*, U, V, W, X, Y, blink::HeapAllocator>>, void> { |
2113 using Node = ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T
, inlineCapacity>>; | 2123 using Node = ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T
, inlineCapacity>>; |
2114 using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>; | 2124 using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>; |
2115 static bool trace(blink::Visitor* visitor, void* self) | 2125 |
| 2126 template<typename VisitorDispatcher> |
| 2127 static bool trace(VisitorDispatcher visitor, void* self) |
2116 { | 2128 { |
2117 Node** array = reinterpret_cast<Node**>(self); | 2129 Node** array = reinterpret_cast<Node**>(self); |
2118 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); | 2130 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s
elf); |
2119 size_t length = header->payloadSize() / sizeof(Node*); | 2131 size_t length = header->payloadSize() / sizeof(Node*); |
2120 for (size_t i = 0; i < length; ++i) { | 2132 for (size_t i = 0; i < length; ++i) { |
2121 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { | 2133 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename
Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { |
2122 traceListHashSetValue(visitor, array[i]->m_value); | 2134 traceListHashSetValue(visitor, array[i]->m_value); |
2123 // Just mark the node without tracing because we already traced | 2135 // Just mark the node without tracing because we already traced |
2124 // the contents, and there is no need to trace the next and | 2136 // the contents, and there is no need to trace the next and |
2125 // prev fields since iterating over the hash table backing will | 2137 // prev fields since iterating over the hash table backing will |
2126 // find the whole chain. | 2138 // find the whole chain. |
2127 visitor->markNoTracing(array[i]); | 2139 visitor->markNoTracing(array[i]); |
2128 } | 2140 } |
2129 } | 2141 } |
2130 return false; | 2142 return false; |
2131 } | 2143 } |
2132 }; | 2144 }; |
2133 | 2145 |
2134 // Key value pairs, as used in HashMap. To disambiguate template choice we have | 2146 // Key value pairs, as used in HashMap. To disambiguate template choice we have |
2135 // to have two versions, first the one with no special weak handling, then the | 2147 // to have two versions, first the one with no special weak handling, then the |
2136 // one with weak handling. | 2148 // one with weak handling. |
2137 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2149 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
2138 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { | 2150 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa
ir<Key, Value>, Traits> { |
2139 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2151 template<typename VisitorDispatcher> |
| 2152 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) |
2140 { | 2153 { |
2141 ASSERT(ShouldBeTraced<Traits>::value); | 2154 ASSERT(ShouldBeTraced<Traits>::value); |
2142 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr
aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT
raits>::trace(visitor, self.key); | 2155 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr
aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT
raits>::trace(visitor, self.key); |
2143 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value
Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::
ValueTraits>::trace(visitor, self.value); | 2156 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value
Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::
ValueTraits>::trace(visitor, self.value); |
2144 return false; | 2157 return false; |
2145 } | 2158 } |
2146 }; | 2159 }; |
2147 | 2160 |
2148 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> | 2161 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
2149 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { | 2162 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair
<Key, Value>, Traits> { |
2150 static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) | 2163 template<typename VisitorDispatcher> |
| 2164 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self) |
2151 { | 2165 { |
2152 // This is the core of the ephemeron-like functionality. If there is | 2166 // This is the core of the ephemeron-like functionality. If there is |
2153 // weakness on the key side then we first check whether there are | 2167 // weakness on the key side then we first check whether there are |
2154 // dead weak pointers on that side, and if there are we don't mark the | 2168 // dead weak pointers on that side, and if there are we don't mark the |
2155 // value side (yet). Conversely if there is weakness on the value side | 2169 // value side (yet). Conversely if there is weakness on the value side |
2156 // we check that first and don't mark the key side yet if we find dead | 2170 // we check that first and don't mark the key side yet if we find dead |
2157 // weak pointers. | 2171 // weak pointers. |
2158 // Corner case: If there is weakness on both the key and value side, | 2172 // Corner case: If there is weakness on both the key and value side, |
2159 // and there are also strong pointers on the both sides then we could | 2173 // and there are also strong pointers on the both sides then we could |
2160 // unexpectedly leak. The scenario is that the weak pointer on the key | 2174 // unexpectedly leak. The scenario is that the weak pointer on the key |
(...skipping 20 matching lines...) Expand all Loading... |
2181 if (deadWeakObjectsFoundOnKeySide) | 2195 if (deadWeakObjectsFoundOnKeySide) |
2182 return true; | 2196 return true; |
2183 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits
::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.value); | 2197 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits
::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value,
typename Traits::ValueTraits>::trace(visitor, self.value); |
2184 } | 2198 } |
2185 }; | 2199 }; |
2186 | 2200 |
2187 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the | 2201 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the |
2188 // template. | 2202 // template. |
2189 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2203 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
2190 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { | 2204 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash
SetNode<Value, Allocator>, Traits> { |
2191 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2205 template<typename VisitorDispatcher> |
| 2206 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca
tor>& self) |
2192 { | 2207 { |
2193 ASSERT(ShouldBeTraced<Traits>::value); | 2208 ASSERT(ShouldBeTraced<Traits>::value); |
2194 return TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, Va
lue, typename Traits::ValueTraits>::trace(visitor, self.m_value); | 2209 return TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, Va
lue, typename Traits::ValueTraits>::trace(visitor, self.m_value); |
2195 } | 2210 } |
2196 }; | 2211 }; |
2197 | 2212 |
2198 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> | 2213 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Allocator, typename Traits> |
2199 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { | 2214 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe
tNode<Value, Allocator>, Traits> { |
2200 static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocato
r>& self) | 2215 template<typename VisitorDispatcher> |
| 2216 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca
tor>& self) |
2201 { | 2217 { |
2202 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu
e, typename Traits::ValueTraits>::trace(visitor, self.m_value); | 2218 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu
e, typename Traits::ValueTraits>::trace(visitor, self.m_value); |
2203 } | 2219 } |
2204 }; | 2220 }; |
2205 | 2221 |
2206 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of | 2222 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of |
2207 // these pointers). | 2223 // these pointers). |
2208 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> | 2224 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in
lineCapacity, typename Traits> |
2209 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity>>*, Traits> { | 2225 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe
tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity>>*, Traits> { |
2210 using Node = ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, i
nlineCapacity>>; | 2226 using Node = ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, i
nlineCapacity>>; |
2211 static bool trace(blink::Visitor* visitor, Node* node) | 2227 |
| 2228 template<typename VisitorDispatcher> |
| 2229 static bool trace(VisitorDispatcher visitor, Node* node) |
2212 { | 2230 { |
2213 traceListHashSetValue(visitor, node->m_value); | 2231 traceListHashSetValue(visitor, node->m_value); |
2214 // Just mark the node without tracing because we already traced the | 2232 // Just mark the node without tracing because we already traced the |
2215 // contents, and there is no need to trace the next and prev fields | 2233 // contents, and there is no need to trace the next and prev fields |
2216 // since iterating over the hash table backing will find the whole | 2234 // since iterating over the hash table backing will find the whole |
2217 // chain. | 2235 // chain. |
2218 visitor->markNoTracing(node); | 2236 visitor->markNoTracing(node); |
2219 return false; | 2237 return false; |
2220 } | 2238 } |
2221 }; | 2239 }; |
2222 | 2240 |
2223 } // namespace WTF | 2241 } // namespace WTF |
2224 | 2242 |
2225 namespace blink { | 2243 namespace blink { |
2226 | 2244 |
2227 // CollectionBackingTraceTrait. Do nothing for things in collections that don't | 2245 // CollectionBackingTraceTrait. Do nothing for things in collections that don't |
2228 // need tracing, or call TraceInCollectionTrait for those that do. | 2246 // need tracing, or call TraceInCollectionTrait for those that do. |
2229 | 2247 |
2230 // Specialization for things that don't need marking and have no weak pointers. | 2248 // Specialization for things that don't need marking and have no weak pointers. |
2231 // We do nothing, even if WTF::WeakPointersActStrong. | 2249 // We do nothing, even if WTF::WeakPointersActStrong. |
2232 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> | 2250 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> |
2233 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { | 2251 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { |
2234 static bool trace(Visitor*, T&) { return false; } | 2252 template<typename VisitorDispatcher> |
| 2253 static bool trace(VisitorDispatcher, T&) { return false; } |
2235 }; | 2254 }; |
2236 | 2255 |
2237 template<typename T> | 2256 template<typename T> |
2238 static void verifyGarbageCollectedIfMember(T*) | 2257 static void verifyGarbageCollectedIfMember(T*) |
2239 { | 2258 { |
2240 } | 2259 } |
2241 | 2260 |
2242 template<typename T> | 2261 template<typename T> |
2243 static void verifyGarbageCollectedIfMember(Member<T>* t) | 2262 static void verifyGarbageCollectedIfMember(Member<T>* t) |
2244 { | 2263 { |
2245 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "non garbage collected object in membe
r"); | 2264 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "non garbage collected object in membe
r"); |
2246 } | 2265 } |
2247 | 2266 |
2248 // Specialization for things that either need marking or have weak pointers or | 2267 // Specialization for things that either need marking or have weak pointers or |
2249 // both. | 2268 // both. |
2250 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> | 2269 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
2251 struct CollectionBackingTraceTrait { | 2270 struct CollectionBackingTraceTrait { |
2252 static bool trace(Visitor* visitor, T&t) | 2271 template<typename VisitorDispatcher> |
| 2272 static bool trace(VisitorDispatcher visitor, T&t) |
2253 { | 2273 { |
2254 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); | 2274 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); |
2255 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); | 2275 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); |
2256 } | 2276 } |
2257 }; | 2277 }; |
2258 | 2278 |
2259 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 2279 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
2260 // We want to treat the object as a weak object in the sense that it can | 2280 // We want to treat the object as a weak object in the sense that it can |
2261 // disappear from hash sets and hash maps. | 2281 // disappear from hash sets and hash maps. |
2262 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 2282 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
2263 // Normally whether or not an object needs tracing is inferred | 2283 // Normally whether or not an object needs tracing is inferred |
2264 // automatically from the presence of the trace method, but we don't | 2284 // automatically from the presence of the trace method, but we don't |
2265 // necessarily have a trace method, and we may not need one because T | 2285 // necessarily have a trace method, and we may not need one because T |
2266 // can perhaps only be allocated inside collections, never as independent | 2286 // can perhaps only be allocated inside collections, never as independent |
2267 // objects. Explicitly mark this as needing tracing and it will be traced | 2287 // objects. Explicitly mark this as needing tracing and it will be traced |
2268 // in collections using the traceInCollection method, which it must have. | 2288 // in collections using the traceInCollection method, which it must have. |
2269 template<typename U = void> struct NeedsTracingLazily { | 2289 template<typename U = void> struct NeedsTracingLazily { |
2270 static const bool value = true; | 2290 static const bool value = true; |
2271 }; | 2291 }; |
2272 // The traceInCollection method traces differently depending on whether we | 2292 // The traceInCollection method traces differently depending on whether we |
2273 // are strongifying the trace operation. We strongify the trace operation | 2293 // are strongifying the trace operation. We strongify the trace operation |
2274 // when there are active iterators on the object. In this case all | 2294 // when there are active iterators on the object. In this case all |
2275 // WeakMembers are marked like strong members so that elements do not | 2295 // WeakMembers are marked like strong members so that elements do not |
2276 // suddenly disappear during iteration. Returns true if weak pointers to | 2296 // suddenly disappear during iteration. Returns true if weak pointers to |
2277 // dead objects were found: In this case any strong pointers were not yet | 2297 // dead objects were found: In this case any strong pointers were not yet |
2278 // traced and the entry should be removed from the collection. | 2298 // traced and the entry should be removed from the collection. |
2279 static bool traceInCollection(Visitor* visitor, T& t, WTF::ShouldWeakPointer
sBeMarkedStrongly strongify) | 2299 template<typename VisitorDispatcher> |
| 2300 static bool traceInCollection(VisitorDispatcher visitor, T& t, WTF::ShouldWe
akPointersBeMarkedStrongly strongify) |
2280 { | 2301 { |
2281 return t.traceInCollection(visitor, strongify); | 2302 return t.traceInCollection(visitor, strongify); |
2282 } | 2303 } |
2283 }; | 2304 }; |
2284 | 2305 |
2285 template<typename T, typename Traits> | 2306 template<typename T, typename Traits> |
2286 struct TraceTrait<HeapVectorBacking<T, Traits>> { | 2307 struct TraceTrait<HeapVectorBacking<T, Traits>> { |
2287 using Backing = HeapVectorBacking<T, Traits>; | 2308 using Backing = HeapVectorBacking<T, Traits>; |
2288 static void trace(Visitor* visitor, void* self) | 2309 |
| 2310 template<typename VisitorDispatcher> |
| 2311 static void trace(VisitorDispatcher visitor, void* self) |
2289 { | 2312 { |
2290 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); | 2313 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); |
2291 if (WTF::ShouldBeTraced<Traits>::value) | 2314 if (WTF::ShouldBeTraced<Traits>::value) |
2292 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | 2315 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
2293 } | 2316 } |
2294 static void mark(Visitor* visitor, const Backing* backing) | 2317 |
| 2318 template<typename VisitorDispatcher> |
| 2319 static void mark(VisitorDispatcher visitor, const Backing* backing) |
2295 { | 2320 { |
2296 visitor->mark(backing, &trace); | 2321 visitor->mark(backing, &trace); |
2297 } | 2322 } |
2298 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2323 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
2299 { | 2324 { |
2300 #if ENABLE(ASSERT) | 2325 #if ENABLE(ASSERT) |
2301 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::index()); | 2326 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::index()); |
2302 #endif | 2327 #endif |
2303 } | 2328 } |
2304 }; | 2329 }; |
2305 | 2330 |
2306 // The trace trait for the heap hashtable backing is used when we find a | 2331 // The trace trait for the heap hashtable backing is used when we find a |
2307 // direct pointer to the backing from the conservative stack scanner. This | 2332 // direct pointer to the backing from the conservative stack scanner. This |
2308 // normally indicates that there is an ongoing iteration over the table, and so | 2333 // normally indicates that there is an ongoing iteration over the table, and so |
2309 // we disable weak processing of table entries. When the backing is found | 2334 // we disable weak processing of table entries. When the backing is found |
2310 // through the owning hash table we mark differently, in order to do weak | 2335 // through the owning hash table we mark differently, in order to do weak |
2311 // processing. | 2336 // processing. |
2312 template<typename Table> | 2337 template<typename Table> |
2313 struct TraceTrait<HeapHashTableBacking<Table>> { | 2338 struct TraceTrait<HeapHashTableBacking<Table>> { |
2314 using Backing = HeapHashTableBacking<Table>; | 2339 using Backing = HeapHashTableBacking<Table>; |
2315 using Traits = typename Table::ValueTraits; | 2340 using Traits = typename Table::ValueTraits; |
2316 static void trace(Visitor* visitor, void* self) | 2341 |
| 2342 template<typename VisitorDispatcher> |
| 2343 static void trace(VisitorDispatcher visitor, void* self) |
2317 { | 2344 { |
2318 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2345 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
2319 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); | 2346 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); |
2320 } | 2347 } |
2321 static void mark(Visitor* visitor, const Backing* backing) | 2348 |
| 2349 template<typename VisitorDispatcher> |
| 2350 static void mark(VisitorDispatcher visitor, const Backing* backing) |
2322 { | 2351 { |
2323 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2352 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
2324 visitor->mark(backing, &trace); | 2353 visitor->mark(backing, &trace); |
2325 else | 2354 else |
2326 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. | 2355 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. |
2327 } | 2356 } |
2328 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2357 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
2329 { | 2358 { |
2330 #if ENABLE(ASSERT) | 2359 #if ENABLE(ASSERT) |
2331 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::index()); | 2360 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing
>::index()); |
(...skipping 28 matching lines...) Expand all Loading... |
2360 template<typename T, size_t inlineCapacity> | 2389 template<typename T, size_t inlineCapacity> |
2361 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2390 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
2362 template<typename T, size_t inlineCapacity> | 2391 template<typename T, size_t inlineCapacity> |
2363 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2392 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
2364 template<typename T, typename U, typename V> | 2393 template<typename T, typename U, typename V> |
2365 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2394 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
2366 | 2395 |
2367 } // namespace blink | 2396 } // namespace blink |
2368 | 2397 |
2369 #endif // Heap_h | 2398 #endif // Heap_h |
OLD | NEW |