Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(523)

Side by Side Diff: Source/platform/heap/Heap.h

Issue 827723002: Reland: Templatize visitor arguments for TraceTrait mark and trace methods. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebased Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Source/platform/heap/HeapTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/HeapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698