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

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

Issue 1120893003: Oilpan: Put all TraceTraits into TraceTraits.h (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/InlinedGlobalMarkingVisitor.h ('k') | Source/platform/heap/Visitor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef TraceTraits_h
6 #define TraceTraits_h
7
8 #include "platform/heap/GCInfo.h"
9 #include "platform/heap/Heap.h"
10 #include "platform/heap/Visitor.h"
11 #include "wtf/Assertions.h"
12 #include "wtf/Deque.h"
13 #include "wtf/HashCountedSet.h"
14 #include "wtf/HashMap.h"
15 #include "wtf/HashSet.h"
16 #include "wtf/HashTable.h"
17 #include "wtf/LinkedHashSet.h"
18 #include "wtf/ListHashSet.h"
19 #include "wtf/TypeTraits.h"
20 #include "wtf/Vector.h"
21
22 namespace blink {
23
24 template<typename T> class CrossThreadPersistent;
25 template<typename T> struct GCInfoTrait;
26 class HeapObjectHeader;
27 template<typename T> class Member;
28 template<typename T, bool> class NeedsAdjustAndMark;
29 template<typename T> class TraceTrait;
30 template<typename T> class WeakMember;
31
32 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrai t;
33
34 template<typename T>
35 class DefaultTraceTrait<T, false> {
36 public:
37 template<typename VisitorDispatcher>
38 static void mark(VisitorDispatcher visitor, const T* t)
39 {
40 // Default mark method of the trait just calls the two-argument mark
41 // method on the visitor. The second argument is the static trace method
42 // of the trait, which by default calls the instance method
43 // trace(Visitor*) on the object.
44 //
45 // If the trait allows it, invoke the trace callback right here on the
46 // not-yet-marked object.
47 if (TraceEagerlyTrait<T>::value) {
48 // Protect against too deep trace call chains, and the
49 // unbounded system stack usage they can bring about.
50 //
51 // Assert against deep stacks so as to flush them out,
52 // but test and appropriately handle them should they occur
53 // in release builds.
54 //
55 // ASan adds extra stack usage, so disable the assert when it is
56 // enabled so as to avoid testing against a much lower & too low,
57 // stack depth threshold.
58 #if !defined(ADDRESS_SANITIZER)
59 ASSERT(StackFrameDepth::isSafeToRecurse());
60 #endif
61 if (LIKELY(StackFrameDepth::isSafeToRecurse())) {
62 if (visitor->ensureMarked(t)) {
63 TraceTrait<T>::trace(visitor, const_cast<T*>(t));
64 }
65 return;
66 }
67 }
68 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace);
69 }
70
71 #if ENABLE(ASSERT)
72 static void checkGCInfo(const T* t)
73 {
74 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index());
75 }
76 #endif
77 };
78
79 template<typename T>
80 class DefaultTraceTrait<T, true> {
81 public:
82 template<typename VisitorDispatcher>
83 static void mark(VisitorDispatcher visitor, const T* self)
84 {
85 if (!self)
86 return;
87
88 // If you hit this ASSERT, it means that there is a dangling pointer
89 // from a live thread heap to a dead thread heap. We must eliminate
90 // the dangling pointer.
91 // Release builds don't have the ASSERT, but it is OK because
92 // release builds will crash at the following self->adjustAndMark
93 // because all the entries of the orphaned heaps are zeroed out and
94 // thus the item does not have a valid vtable.
95 ASSERT(!pageFromObject(self)->orphaned());
96 self->adjustAndMark(visitor);
97 }
98
99 #if ENABLE(ASSERT)
100 static void checkGCInfo(const T*) { }
101 #endif
102 };
103
104 template<typename T, bool needsTracing>
105 struct TraceIfEnabled;
106
107 template<typename T>
108 struct TraceIfEnabled<T, false> {
109 template<typename VisitorDispatcher>
110 static void trace(VisitorDispatcher, T*) { }
111 };
112
113 template<typename T>
114 struct TraceIfEnabled<T, true> {
115 template<typename VisitorDispatcher>
116 static void trace(VisitorDispatcher visitor, T* t)
117 {
118 visitor->trace(*t);
119 }
120 };
121
122 // The TraceTrait is used to specify how to mark an object pointer and
123 // how to trace all of the pointers in the object.
124 //
125 // By default, the 'trace' method implemented on an object itself is
126 // used to trace the pointers to other heap objects inside the object.
127 //
128 // However, the TraceTrait can be specialized to use a different
129 // implementation. A common case where a TraceTrait specialization is
130 // needed is when multiple inheritance leads to pointers that are not
131 // to the start of the object in the Blink garbage-collected heap. In
132 // that case the pointer has to be adjusted before marking.
133 template<typename T>
134 class TraceTrait {
135 public:
136 static void trace(Visitor*, void* self);
137 static void trace(InlinedGlobalMarkingVisitor, void* self);
138
139 template<typename VisitorDispatcher>
140 static void mark(VisitorDispatcher visitor, const T* t)
141 {
142 DefaultTraceTrait<T>::mark(visitor, t);
143 }
144
145 #if ENABLE(ASSERT)
146 static void checkGCInfo(const T* t)
147 {
148 DefaultTraceTrait<T>::checkGCInfo(t);
149 }
150 #endif
151 };
152
153 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
154
155 template<typename T>
156 void TraceTrait<T>::trace(Visitor* visitor, void* self)
157 {
158 if (visitor->isGlobalMarkingVisitor()) {
159 // Switch to inlined global marking dispatch.
160 static_cast<T*>(self)->trace(InlinedGlobalMarkingVisitor(visitor));
161 } else {
162 static_cast<T*>(self)->trace(visitor);
163 }
164 }
165
166 template<typename T>
167 void TraceTrait<T>::trace(InlinedGlobalMarkingVisitor visitor, void* self)
168 {
169 static_cast<T*>(self)->trace(visitor);
170 }
171
172 template<typename T, typename Traits>
173 struct TraceTrait<HeapVectorBacking<T, Traits>> {
174 using Backing = HeapVectorBacking<T, Traits>;
175
176 template<typename VisitorDispatcher>
177 static void trace(VisitorDispatcher visitor, void* self)
178 {
179 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque s are not supported");
180 if (WTF::ShouldBeTraced<Traits>::value)
181 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self);
182 }
183
184 template<typename VisitorDispatcher>
185 static void mark(VisitorDispatcher visitor, const Backing* backing)
186 {
187 visitor->mark(backing, &trace);
188 }
189 static void checkGCInfo(Visitor* visitor, const Backing* backing)
190 {
191 #if ENABLE(ASSERT)
192 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index());
193 #endif
194 }
195 };
196
197 // The trace trait for the heap hashtable backing is used when we find a
198 // direct pointer to the backing from the conservative stack scanner. This
199 // normally indicates that there is an ongoing iteration over the table, and so
200 // we disable weak processing of table entries. When the backing is found
201 // through the owning hash table we mark differently, in order to do weak
202 // processing.
203 template<typename Table>
204 struct TraceTrait<HeapHashTableBacking<Table>> {
205 using Backing = HeapHashTableBacking<Table>;
206 using Traits = typename Table::ValueTraits;
207
208 template<typename VisitorDispatcher>
209 static void trace(VisitorDispatcher visitor, void* self)
210 {
211 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT F::WeakHandlingInCollections)
212 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W eakPointersActStrong, Backing, void>::trace(visitor, self);
213 }
214
215 template<typename VisitorDispatcher>
216 static void mark(VisitorDispatcher visitor, const Backing* backing)
217 {
218 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT F::WeakHandlingInCollections)
219 visitor->mark(backing, &trace);
220 else
221 visitor->markNoTracing(backing); // If we know the trace function wi ll do nothing there is no need to call it.
222 }
223 static void checkGCInfo(Visitor* visitor, const Backing* backing)
224 {
225 #if ENABLE(ASSERT)
226 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index());
227 #endif
228 }
229 };
230
231 // This trace trait for std::pair will null weak members if their referent is
232 // collected. If you have a collection that contain weakness it does not remove
233 // entries from the collection that contain nulled weak members.
234 template<typename T, typename U>
235 class TraceTrait<std::pair<T, U>> {
236 public:
237 static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::Is Weak<T>::value;
238 static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::I sWeak<U>::value;
239 template<typename VisitorDispatcher>
240 static void trace(VisitorDispatcher visitor, std::pair<T, U>* pair)
241 {
242 TraceIfEnabled<T, firstNeedsTracing>::trace(visitor, &pair->first);
243 TraceIfEnabled<U, secondNeedsTracing>::trace(visitor, &pair->second);
244 }
245 };
246
247 // If eager tracing leads to excessively deep |trace()| call chains (and
248 // the system stack usage that this brings), the marker implementation will
249 // switch to using an explicit mark stack. Recursive and deep object graphs
250 // are uncommon for Blink objects.
251 //
252 // A class type can opt out of eager tracing by declaring a TraceEagerlyTrait<>
253 // specialization, mapping the trait's |value| to |false| (see the
254 // WILL_NOT_BE_EAGERLY_TRACED_CLASS() macros below.) For Blink, this is done for
255 // the small set of GCed classes that are directly recursive.
256 //
257 // The TraceEagerlyTrait<T> trait controls whether or not a class
258 // (and its subclasses) should be eagerly traced or not.
259 //
260 // If |TraceEagerlyTrait<T>::value| is |true|, then the marker thread
261 // should invoke |trace()| on not-yet-marked objects deriving from class T
262 // right away, and not queue their trace callbacks on its marker stack,
263 // which it will do if |value| is |false|.
264 //
265 // The trait can be declared to enable/disable eager tracing for a class T
266 // and any of its subclasses, or just to the class T, but none of its
267 // subclasses.
268 //
269 template<typename T>
270 class TraceEagerlyTrait {
271 public:
272 static const bool value = true;
273 };
274
275 // Disable eager tracing for TYPE, but not any of its subclasses.
276 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \
277 template<> \
278 class TraceEagerlyTrait<TYPE> { \
279 public: \
280 static const bool value = false; \
281 }
282
283 template<typename T>
284 class TraceEagerlyTrait<Member<T>> {
285 public:
286 static const bool value = TraceEagerlyTrait<T>::value;
287 };
288
289 template<typename T>
290 class TraceEagerlyTrait<WeakMember<T>> {
291 public:
292 static const bool value = TraceEagerlyTrait<T>::value;
293 };
294
295 template<typename T>
296 class TraceEagerlyTrait<Persistent<T>> {
297 public:
298 static const bool value = TraceEagerlyTrait<T>::value;
299 };
300
301 template<typename T>
302 class TraceEagerlyTrait<CrossThreadPersistent<T>> {
303 public:
304 static const bool value = TraceEagerlyTrait<T>::value;
305 };
306
307 template<typename ValueArg, size_t inlineCapacity> class HeapListHashSetAllocato r;
308 template<typename T, size_t inlineCapacity>
309 class TraceEagerlyTrait<WTF::ListHashSetNode<T, HeapListHashSetAllocator<T, inli neCapacity>>> {
310 public:
311 static const bool value = false;
312 };
313
314 template <typename T> struct RemoveHeapPointerWrapperTypes {
315 using Type = typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<typen ame WTF::RemoveTemplate<T, Member>::Type, WeakMember>::Type, RawPtr>::Type;
316 };
317
318 // FIXME: Oilpan: TraceIfNeeded should be implemented ala:
319 // NeedsTracing<T>::value || IsWeakMember<T>::value. It should not need to test
320 // raw pointer types. To remove these tests, we may need support for
321 // instantiating a template with a RawPtrOrMember'ish template.
322 template<typename T>
323 struct TraceIfNeeded : public TraceIfEnabled<T, WTF::NeedsTracing<T>::value || I sGarbageCollectedType<typename RemoveHeapPointerWrapperTypes<typename WTF::Remov ePointer<T>::Type>::Type>::value> { };
324
325 } // namespace blink
326
327 namespace WTF {
328
329 // Catch-all for types that have a way to trace that don't have special
330 // handling for weakness in collections. This means that if this type
331 // contains WeakMember fields, they will simply be zeroed, but the entry
332 // will not be removed from the collection. This always happens for
333 // things in vectors, which don't currently support special handling of
334 // weak elements.
335 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
336 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits> {
337 template<typename VisitorDispatcher>
338 static bool trace(VisitorDispatcher visitor, T& t)
339 {
340 blink::TraceTrait<T>::trace(visitor, &t);
341 return false;
342 }
343 };
344
345 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
346 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem ber<T>, Traits> {
347 template<typename VisitorDispatcher>
348 static bool trace(VisitorDispatcher visitor, blink::Member<T>& t)
349 {
350 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>:: Type*>(t.get()));
351 return false;
352 }
353 };
354
355 // Catch-all for things that have HashTrait support for tracing with weakness.
356 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
357 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> {
358 template<typename VisitorDispatcher>
359 static bool trace(VisitorDispatcher visitor, T& t)
360 {
361 return Traits::traceInCollection(visitor, t, strongify);
362 }
363 };
364
365 // Vector backing that needs marking. We don't support weak members in vectors.
366 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
367 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pVectorBacking<T, Traits>, void> {
368 template<typename VisitorDispatcher>
369 static bool trace(VisitorDispatcher visitor, void* self)
370 {
371 // HeapVectorBacking does not know the exact size of the vector
372 // and just knows the capacity of the vector. Due to the constraint,
373 // HeapVectorBacking can support only the following objects:
374 //
375 // - An object that has a vtable. In this case, HeapVectorBacking
376 // traces only slots that are not zeroed out. This is because if
377 // the object has a vtable, the zeroed slot means that it is
378 // an unused slot (Remember that the unused slots are guaranteed
379 // to be zeroed out by VectorUnusedSlotClearer).
380 //
381 // - An object that can be initialized with memset. In this case,
382 // HeapVectorBacking traces all slots including unused slots.
383 // This is fine because the fact that the object can be initialized
384 // with memset indicates that it is safe to treat the zerod slot
385 // as a valid object.
386 static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWit hMemset || WTF::IsPolymorphic<T>::value, "HeapVectorBacking doesn't support obje cts that cannot be initialized with memset.");
387
388 T* array = reinterpret_cast<T*>(self);
389 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf);
390 // Use the payload size as recorded by the heap to determine how many
391 // elements to trace.
392 size_t length = header->payloadSize() / sizeof(T);
393 if (WTF::IsPolymorphic<T>::value) {
394 for (size_t i = 0; i < length; ++i) {
395 if (blink::vTableInitialized(&array[i]))
396 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::v alue, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor , array[i]);
397 }
398 } else {
399 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER
400 // As commented above, HeapVectorBacking can trace unused slots
401 // (which are already zeroed out).
402 ANNOTATE_CHANGE_SIZE(array, length, 0, length);
403 #endif
404 for (size_t i = 0; i < length; ++i)
405 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value , Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, ar ray[i]);
406 }
407 return false;
408 }
409 };
410
411 // Almost all hash table backings are visited with this specialization.
412 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table>
413 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pHashTableBacking<Table>, void> {
414 using Value = typename Table::ValueType;
415 using Traits = typename Table::ValueTraits;
416
417 template<typename VisitorDispatcher>
418 static bool trace(VisitorDispatcher visitor, void* self)
419 {
420 Value* array = reinterpret_cast<Value*>(self);
421 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf);
422 size_t length = header->payloadSize() / sizeof(Value);
423 for (size_t i = 0; i < length; ++i) {
424 if (!HashTableHelper<Value, typename Table::ExtractorType, typename Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i]))
425 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value , Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]);
426 }
427 return false;
428 }
429 };
430
431 // This specialization of TraceInCollectionTrait is for the backing of
432 // HeapListHashSet. This is for the case that we find a reference to the
433 // backing from the stack. That probably means we have a GC while we are in a
434 // ListHashSet method since normal API use does not put pointers to the backing
435 // on the stack.
436 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X, typename Y>
437 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSet Allocator<T, inlineCapacity>>*, U, V, W, X, Y, blink::HeapAllocator>>, void> {
438 using Node = ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T , inlineCapacity>>;
439 using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>;
440
441 template<typename VisitorDispatcher>
442 static bool trace(VisitorDispatcher visitor, void* self)
443 {
444 Node** array = reinterpret_cast<Node**>(self);
445 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf);
446 size_t length = header->payloadSize() / sizeof(Node*);
447 for (size_t i = 0; i < length; ++i) {
448 if (!HashTableHelper<Node*, typename Table::ExtractorType, typename Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) {
449 traceListHashSetValue(visitor, array[i]->m_value);
450 // Just mark the node without tracing because we already traced
451 // the contents, and there is no need to trace the next and
452 // prev fields since iterating over the hash table backing will
453 // find the whole chain.
454 visitor->markNoTracing(array[i]);
455 }
456 }
457 return false;
458 }
459 };
460
461 // Key value pairs, as used in HashMap. To disambiguate template choice we have
462 // to have two versions, first the one with no special weak handling, then the
463 // one with weak handling.
464 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va lue, typename Traits>
465 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePa ir<Key, Value>, Traits> {
466 template<typename VisitorDispatcher>
467 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self)
468 {
469 ASSERT(ShouldBeTraced<Traits>::value);
470 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTr aits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyT raits>::trace(visitor, self.key);
471 blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::Value Traits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits:: ValueTraits>::trace(visitor, self.value);
472 return false;
473 }
474 };
475
476 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va lue, typename Traits>
477 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair <Key, Value>, Traits> {
478 template<typename VisitorDispatcher>
479 static bool trace(VisitorDispatcher visitor, KeyValuePair<Key, Value>& self)
480 {
481 // This is the core of the ephemeron-like functionality. If there is
482 // weakness on the key side then we first check whether there are
483 // dead weak pointers on that side, and if there are we don't mark the
484 // value side (yet). Conversely if there is weakness on the value side
485 // we check that first and don't mark the key side yet if we find dead
486 // weak pointers.
487 // Corner case: If there is weakness on both the key and value side,
488 // and there are also strong pointers on the both sides then we could
489 // unexpectedly leak. The scenario is that the weak pointer on the key
490 // side is alive, which causes the strong pointer on the key side to be
491 // marked. If that then results in the object pointed to by the weak
492 // pointer on the value side being marked live, then the whole
493 // key-value entry is leaked. To avoid unexpected leaking, we disallow
494 // this case, but if you run into this assert, please reach out to Blink
495 // reviewers, and we may relax it.
496 const bool keyIsWeak = Traits::KeyTraits::weakHandlingFlag == WeakHandli ngInCollections;
497 const bool valueIsWeak = Traits::ValueTraits::weakHandlingFlag == WeakHa ndlingInCollections;
498 const bool keyHasStrongRefs = ShouldBeTraced<typename Traits::KeyTraits> ::value;
499 const bool valueHasStrongRefs = ShouldBeTraced<typename Traits::ValueTra its>::value;
500 static_assert(!keyIsWeak || !valueIsWeak || !keyHasStrongRefs || !valueH asStrongRefs, "this configuration is disallowed to avoid unexpected leaks");
501 if ((valueIsWeak && !keyIsWeak) || (valueIsWeak && keyIsWeak && !valueHa sStrongRefs)) {
502 // Check value first.
503 bool deadWeakObjectsFoundOnValueSide = blink::CollectionBackingTrace Trait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits:: weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor , self.value);
504 if (deadWeakObjectsFoundOnValueSide)
505 return true;
506 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Tr aits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, ty pename Traits::KeyTraits>::trace(visitor, self.key);
507 }
508 // Check key first.
509 bool deadWeakObjectsFoundOnKeySide = blink::CollectionBackingTraceTrait< ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandli ngFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key);
510 if (deadWeakObjectsFoundOnKeySide)
511 return true;
512 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits ::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor, self.value);
513 }
514 };
515
516 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the
517 // template.
518 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Allocator, typename Traits>
519 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHash SetNode<Value, Allocator>, Traits> {
520 template<typename VisitorDispatcher>
521 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca tor>& self)
522 {
523 ASSERT(ShouldBeTraced<Traits>::value);
524 return TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, Va lue, typename Traits::ValueTraits>::trace(visitor, self.m_value);
525 }
526 };
527
528 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Allocator, typename Traits>
529 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSe tNode<Value, Allocator>, Traits> {
530 template<typename VisitorDispatcher>
531 static bool trace(VisitorDispatcher visitor, LinkedHashSetNode<Value, Alloca tor>& self)
532 {
533 return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Valu e, typename Traits::ValueTraits>::trace(visitor, self.m_value);
534 }
535 };
536
537 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of
538 // these pointers).
539 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in lineCapacity, typename Traits>
540 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSe tNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity>>*, Traits> {
541 using Node = ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, i nlineCapacity>>;
542
543 template<typename VisitorDispatcher>
544 static bool trace(VisitorDispatcher visitor, Node* node)
545 {
546 traceListHashSetValue(visitor, node->m_value);
547 // Just mark the node without tracing because we already traced the
548 // contents, and there is no need to trace the next and prev fields
549 // since iterating over the hash table backing will find the whole
550 // chain.
551 visitor->markNoTracing(node);
552 return false;
553 }
554 };
555
556 } // namespace WTF
557
558 #endif
OLDNEW
« no previous file with comments | « Source/platform/heap/InlinedGlobalMarkingVisitor.h ('k') | Source/platform/heap/Visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698