• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef Handle_h
32 #define Handle_h
33 
34 #include "platform/heap/Heap.h"
35 #include "platform/heap/ThreadState.h"
36 #include "platform/heap/Visitor.h"
37 #include "wtf/Functional.h"
38 #include "wtf/HashFunctions.h"
39 #include "wtf/Locker.h"
40 #include "wtf/RawPtr.h"
41 #include "wtf/RefCounted.h"
42 #include "wtf/TypeTraits.h"
43 
44 namespace WebCore {
45 
46 template<typename T> class HeapTerminatedArray;
47 
48 // Template to determine if a class is a GarbageCollectedMixin by checking if it
49 // has adjustAndMark and isAlive. We can't check directly if the class is a
50 // GarbageCollectedMixin because casting to it is potentially ambiguous.
51 template<typename T>
52 struct IsGarbageCollectedMixin {
53     typedef char TrueType;
54     struct FalseType {
55         char dummy[2];
56     };
57 
58 #if COMPILER(MSVC)
59     template<typename U> static TrueType hasAdjustAndMark(char[&U::adjustAndMark != 0]);
60     template<typename U> static TrueType hasIsAlive(char[&U::isAlive != 0]);
61 #else
62     template<size_t> struct F;
63     template<typename U> static TrueType hasAdjustAndMark(F<sizeof(&U::adjustAndMark)>*);
64     template<typename U> static TrueType hasIsAlive(F<sizeof(&U::isAlive)>*);
65 #endif
66     template<typename U> static FalseType hasIsAlive(...);
67     template<typename U> static FalseType hasAdjustAndMark(...);
68 
69     static bool const value = (sizeof(TrueType) == sizeof(hasAdjustAndMark<T>(0))) && (sizeof(TrueType) == sizeof(hasIsAlive<T>(0)));
70 };
71 
72 template <typename T>
73 struct IsGarbageCollectedType {
74     typedef typename WTF::RemoveConst<T>::Type NonConstType;
75     typedef WTF::IsSubclassOfTemplate<NonConstType, GarbageCollected> GarbageCollectedSubclass;
76     typedef IsGarbageCollectedMixin<NonConstType> GarbageCollectedMixinSubclass;
77     typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashSet> HeapHashSetSubclass;
78     typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass;
79     typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass;
80     typedef WTF::IsSubclassOfTemplate5<NonConstType, HeapHashMap> HeapHashMapSubclass;
81     typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass;
82     typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass;
83     typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashCountedSet> HeapHashCountedSetSubclass;
84     typedef WTF::IsSubclassOfTemplate<NonConstType, HeapTerminatedArray> HeapTerminatedArraySubclass;
85     static const bool value =
86         GarbageCollectedSubclass::value
87         || GarbageCollectedMixinSubclass::value
88         || HeapHashSetSubclass::value
89         || HeapLinkedHashSetSubclass::value
90         || HeapListHashSetSubclass::value
91         || HeapHashMapSubclass::value
92         || HeapVectorSubclass::value
93         || HeapDequeSubclass::value
94         || HeapHashCountedSetSubclass::value
95         || HeapTerminatedArraySubclass::value;
96 };
97 
98 #define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \
99     COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage)
100 
101 template<typename T> class Member;
102 
103 class PersistentNode {
104 public:
PersistentNode(TraceCallback trace)105     explicit PersistentNode(TraceCallback trace)
106         : m_trace(trace)
107     {
108     }
109 
isAlive()110     bool isAlive() { return m_trace; }
111 
~PersistentNode()112     virtual ~PersistentNode()
113     {
114         ASSERT(isAlive());
115         m_trace = 0;
116     }
117 
118     // Ideally the trace method should be virtual and automatically dispatch
119     // to the most specific implementation. However having a virtual method
120     // on PersistentNode leads to too eager template instantiation with MSVC
121     // which leads to include cycles.
122     // Instead we call the constructor with a TraceCallback which knows the
123     // type of the most specific child and calls trace directly. See
124     // TraceMethodDelegate in Visitor.h for how this is done.
trace(Visitor * visitor)125     void trace(Visitor* visitor)
126     {
127         m_trace(visitor, this);
128     }
129 
130 protected:
131     TraceCallback m_trace;
132 
133 private:
134     PersistentNode* m_next;
135     PersistentNode* m_prev;
136 
137     template<typename RootsAccessor, typename Owner> friend class PersistentBase;
138     friend class PersistentAnchor;
139     friend class ThreadState;
140 };
141 
142 // RootsAccessor for Persistent that provides access to thread-local list
143 // of persistent handles. Can only be used to create handles that
144 // are constructed and destructed on the same thread.
145 template<ThreadAffinity Affinity>
146 class ThreadLocalPersistents {
147 public:
roots()148     static PersistentNode* roots() { return state()->roots(); }
149 
150     // No locking required. Just check that we are at the right thread.
151     class Lock {
152     public:
Lock()153         Lock() { state()->checkThread(); }
154     };
155 
156 private:
state()157     static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
158 };
159 
160 // RootsAccessor for Persistent that provides synchronized access to global
161 // list of persistent handles. Can be used for persistent handles that are
162 // passed between threads.
163 class GlobalPersistents {
164 public:
roots()165     static PersistentNode* roots() { return ThreadState::globalRoots(); }
166 
167     class Lock {
168     public:
Lock()169         Lock() : m_locker(ThreadState::globalRootsMutex()) { }
170     private:
171         MutexLocker m_locker;
172     };
173 };
174 
175 // Base class for persistent handles. RootsAccessor specifies which list to
176 // link resulting handle into. Owner specifies the class containing trace
177 // method.
178 template<typename RootsAccessor, typename Owner>
179 class PersistentBase : public PersistentNode {
180 public:
~PersistentBase()181     ~PersistentBase()
182     {
183         typename RootsAccessor::Lock lock;
184         ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list.
185         ASSERT(isAlive());
186         ASSERT(m_next->isAlive());
187         ASSERT(m_prev->isAlive());
188         m_next->m_prev = m_prev;
189         m_prev->m_next = m_next;
190     }
191 
192 protected:
PersistentBase()193     inline PersistentBase()
194         : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
195 #ifndef NDEBUG
196         , m_roots(RootsAccessor::roots())
197 #endif
198     {
199         typename RootsAccessor::Lock lock;
200         m_prev = RootsAccessor::roots();
201         m_next = m_prev->m_next;
202         m_prev->m_next = this;
203         m_next->m_prev = this;
204     }
205 
PersistentBase(const PersistentBase & otherref)206     inline explicit PersistentBase(const PersistentBase& otherref)
207         : PersistentNode(otherref.m_trace)
208 #ifndef NDEBUG
209         , m_roots(RootsAccessor::roots())
210 #endif
211     {
212         typename RootsAccessor::Lock lock;
213         ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list.
214         PersistentBase* other = const_cast<PersistentBase*>(&otherref);
215         m_prev = other;
216         m_next = other->m_next;
217         other->m_next = this;
218         m_next->m_prev = this;
219     }
220 
221     inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; }
222 
223 #ifndef NDEBUG
224 private:
225     PersistentNode* m_roots;
226 #endif
227 };
228 
229 // A dummy Persistent handle that ensures the list of persistents is never null.
230 // This removes a test from a hot path.
231 class PersistentAnchor : public PersistentNode {
232 public:
trace(Visitor * visitor)233     void trace(Visitor* visitor)
234     {
235         for (PersistentNode* current = m_next; current != this; current = current->m_next)
236             current->trace(visitor);
237     }
238 
~PersistentAnchor()239     virtual ~PersistentAnchor()
240     {
241         // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a
242         // large number of objects leaked when we tear down the main thread. Since some of these might contain a
243         // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
244         // this point.
245     }
246 
247 private:
PersistentAnchor()248     PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
249     {
250         m_next = this;
251         m_prev = this;
252     }
253 
254     friend class ThreadState;
255 };
256 
257 #ifndef NDEBUG
258     // For global persistent handles we cannot check that the
259     // pointer is in the heap because that would involve
260     // inspecting the heap of running threads.
261 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \
262     bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \
263     ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer))
264 #else
265 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer)
266 #endif
267 
268 template<typename T>
269 class CrossThreadPersistent;
270 
271 // Persistent handles are used to store pointers into the
272 // managed heap. As long as the Persistent handle is alive
273 // the GC will keep the object pointed to alive. Persistent
274 // handles can be stored in objects and they are not scoped.
275 // Persistent handles must not be used to contain pointers
276 // between objects that are in the managed heap. They are only
277 // meant to point to managed heap objects from variables/members
278 // outside the managed heap.
279 //
280 // A Persistent is always a GC root from the point of view of
281 // the garbage collector.
282 //
283 // We have to construct and destruct Persistent with default RootsAccessor in
284 // the same thread.
285 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ >
286 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > {
287     WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent);
288     WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent);
289 public:
Persistent()290     Persistent() : m_raw(0) { }
291 
Persistent(std::nullptr_t)292     Persistent(std::nullptr_t) : m_raw(0) { }
293 
Persistent(T * raw)294     Persistent(T* raw) : m_raw(raw)
295     {
296         ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
297         recordBacktrace();
298     }
299 
Persistent(T & raw)300     explicit Persistent(T& raw) : m_raw(&raw)
301     {
302         ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
303         recordBacktrace();
304     }
305 
Persistent(const Persistent & other)306     Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); }
307 
308     template<typename U>
Persistent(const Persistent<U,RootsAccessor> & other)309     Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); }
310 
311     template<typename U>
Persistent(const Member<U> & other)312     Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); }
313 
314     template<typename U>
Persistent(const RawPtr<U> & other)315     Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); }
316 
317     template<typename U>
318     Persistent& operator=(U* other)
319     {
320         m_raw = other;
321         recordBacktrace();
322         return *this;
323     }
324 
325     Persistent& operator=(std::nullptr_t)
326     {
327         m_raw = 0;
328         return *this;
329     }
330 
clear()331     void clear() { m_raw = 0; }
332 
~Persistent()333     virtual ~Persistent()
334     {
335         m_raw = 0;
336     }
337 
338     template<typename U>
as()339     U* as() const
340     {
341         return static_cast<U*>(m_raw);
342     }
343 
trace(Visitor * visitor)344     void trace(Visitor* visitor)
345     {
346         COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent);
347 #if ENABLE(GC_TRACING)
348         visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName);
349 #endif
350         visitor->mark(m_raw);
351     }
352 
release()353     T* release()
354     {
355         T* result = m_raw;
356         m_raw = 0;
357         return result;
358     }
359 
360     T& operator*() const { return *m_raw; }
361 
362     bool operator!() const { return !m_raw; }
363 
364     operator T*() const { return m_raw; }
365     operator RawPtr<T>() const { return m_raw; }
366 
367     T* operator->() const { return *this; }
368 
369     Persistent& operator=(const Persistent& other)
370     {
371         m_raw = other;
372         recordBacktrace();
373         return *this;
374     }
375 
376     template<typename U>
377     Persistent& operator=(const Persistent<U, RootsAccessor>& other)
378     {
379         m_raw = other;
380         recordBacktrace();
381         return *this;
382     }
383 
384     template<typename U>
385     Persistent& operator=(const Member<U>& other)
386     {
387         m_raw = other;
388         recordBacktrace();
389         return *this;
390     }
391 
392     template<typename U>
393     Persistent& operator=(const RawPtr<U>& other)
394     {
395         m_raw = other;
396         recordBacktrace();
397         return *this;
398     }
399 
get()400     T* get() const { return m_raw; }
401 
402 private:
403 #if ENABLE(GC_TRACING)
recordBacktrace()404     void recordBacktrace()
405     {
406         if (m_raw)
407             m_tracingName = Heap::createBacktraceString();
408     }
409 
410     String m_tracingName;
411 #else
412     inline void recordBacktrace() const { }
413 #endif
414     T* m_raw;
415 
416     friend class CrossThreadPersistent<T>;
417 };
418 
419 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
420 // different from the construction thread.
421 template<typename T>
422 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> {
423     WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent);
424     WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent);
425 public:
CrossThreadPersistent(T * raw)426     CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { }
427 
428     using Persistent<T, GlobalPersistents>::operator=;
429 };
430 
431 // FIXME: derive affinity based on the collection.
432 template<typename Collection, ThreadAffinity Affinity = AnyThread>
433 class PersistentHeapCollectionBase
434     : public Collection
435     , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > {
436     // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent
437     // heap collections are always allocated off-heap. This allows persistent collections to be used in
438     // DEFINE_STATIC_LOCAL et. al.
439     WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
440 public:
PersistentHeapCollectionBase()441     PersistentHeapCollectionBase() { }
442 
443     template<typename OtherCollection>
PersistentHeapCollectionBase(const OtherCollection & other)444     PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { }
445 
trace(Visitor * visitor)446     void trace(Visitor* visitor)
447     {
448 #if ENABLE(GC_TRACING)
449         visitor->setHostInfo(this, "PersistentHeapCollectionBase");
450 #endif
451         visitor->trace(*static_cast<Collection*>(this));
452     }
453 };
454 
455 template<
456     typename KeyArg,
457     typename MappedArg,
458     typename HashArg = typename DefaultHash<KeyArg>::Hash,
459     typename KeyTraitsArg = HashTraits<KeyArg>,
460     typename MappedTraitsArg = HashTraits<MappedArg> >
461 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { };
462 
463 template<
464     typename ValueArg,
465     typename HashArg = typename DefaultHash<ValueArg>::Hash,
466     typename TraitsArg = HashTraits<ValueArg> >
467 class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { };
468 
469 template<
470     typename ValueArg,
471     typename HashArg = typename DefaultHash<ValueArg>::Hash,
472     typename TraitsArg = HashTraits<ValueArg> >
473 class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { };
474 
475 template<
476     typename ValueArg,
477     size_t inlineCapacity = 0,
478     typename HashArg = typename DefaultHash<ValueArg>::Hash>
479 class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { };
480 
481 template<typename T, typename U, typename V>
482 class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { };
483 
484 template<typename T, size_t inlineCapacity = 0>
485 class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > {
486 public:
PersistentHeapVector()487     PersistentHeapVector() { }
488 
489     template<size_t otherCapacity>
PersistentHeapVector(const HeapVector<T,otherCapacity> & other)490     PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
491         : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other)
492     {
493     }
494 };
495 
496 template<typename T, size_t inlineCapacity = 0>
497 class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > {
498 public:
PersistentHeapDeque()499     PersistentHeapDeque() { }
500 
501     template<size_t otherCapacity>
PersistentHeapDeque(const HeapDeque<T,otherCapacity> & other)502     PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
503         : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other)
504     {
505     }
506 };
507 
508 // Members are used in classes to contain strong pointers to other oilpan heap
509 // allocated objects.
510 // All Member fields of a class must be traced in the class' trace method.
511 // During the mark phase of the GC all live objects are marked as live and
512 // all Member fields of a live object will be traced marked as live as well.
513 template<typename T>
514 class Member {
515     WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member);
516     WTF_DISALLOW_ZERO_ASSIGNMENT(Member);
517 public:
Member()518     Member() : m_raw(0)
519     {
520     }
521 
Member(std::nullptr_t)522     Member(std::nullptr_t) : m_raw(0)
523     {
524     }
525 
Member(T * raw)526     Member(T* raw) : m_raw(raw)
527     {
528     }
529 
Member(T & raw)530     explicit Member(T& raw) : m_raw(&raw)
531     {
532     }
533 
534     template<typename U>
Member(const RawPtr<U> & other)535     Member(const RawPtr<U>& other) : m_raw(other.get())
536     {
537     }
538 
Member(WTF::HashTableDeletedValueType)539     Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
540     {
541     }
542 
isHashTableDeletedValue()543     bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
544 
545     template<typename U>
Member(const Persistent<U> & other)546     Member(const Persistent<U>& other) : m_raw(other) { }
547 
Member(const Member & other)548     Member(const Member& other) : m_raw(other) { }
549 
550     template<typename U>
Member(const Member<U> & other)551     Member(const Member<U>& other) : m_raw(other) { }
552 
release()553     T* release()
554     {
555         T* result = m_raw;
556         m_raw = 0;
557         return result;
558     }
559 
560     template<typename U>
as()561     U* as() const
562     {
563         return static_cast<U*>(m_raw);
564     }
565 
566     bool operator!() const { return !m_raw; }
567 
568     operator T*() const { return m_raw; }
569 
570     T* operator->() const { return m_raw; }
571     T& operator*() const { return *m_raw; }
572     template<typename U>
573     operator RawPtr<U>() const { return m_raw; }
574 
575     template<typename U>
576     Member& operator=(const Persistent<U>& other)
577     {
578         m_raw = other;
579         return *this;
580     }
581 
582     template<typename U>
583     Member& operator=(const Member<U>& other)
584     {
585         m_raw = other;
586         return *this;
587     }
588 
589     template<typename U>
590     Member& operator=(U* other)
591     {
592         m_raw = other;
593         return *this;
594     }
595 
596     template<typename U>
597     Member& operator=(RawPtr<U> other)
598     {
599         m_raw = other;
600         return *this;
601     }
602 
603     Member& operator=(std::nullptr_t)
604     {
605         m_raw = 0;
606         return *this;
607     }
608 
swap(Member<T> & other)609     void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
610 
get()611     T* get() const { return m_raw; }
612 
clear()613     void clear() { m_raw = 0; }
614 
615 
616 protected:
verifyTypeIsGarbageCollected()617     void verifyTypeIsGarbageCollected() const
618     {
619         COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember);
620     }
621 
622     T* m_raw;
623 
624     template<bool x, WTF::WeakHandlingFlag y, ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
625     friend class Visitor;
626 };
627 
628 template<typename T>
629 class TraceTrait<Member<T> > {
630 public:
trace(Visitor * visitor,void * self)631     static void trace(Visitor* visitor, void* self)
632     {
633         TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
634     }
635 };
636 
637 // TraceTrait to allow compilation of trace method bodies when oilpan is disabled.
638 // This should never be called, but is needed to compile.
639 template<typename T>
640 class TraceTrait<RefPtr<T> > {
641 public:
trace(Visitor *,void *)642     static void trace(Visitor*, void*)
643     {
644         ASSERT_NOT_REACHED();
645     }
646 };
647 
648 template<typename T>
649 class TraceTrait<OwnPtr<T> > {
650 public:
trace(Visitor * visitor,OwnPtr<T> * ptr)651     static void trace(Visitor* visitor, OwnPtr<T>* ptr)
652     {
653         TraceTrait<T>::trace(visitor, ptr->get());
654     }
655 };
656 
657 template<bool needsTracing, typename T>
658 struct StdPairHelper;
659 
660 template<typename T>
661 struct StdPairHelper<false, T>  {
662     static void trace(Visitor*, T*) { }
663 };
664 
665 template<typename T>
666 struct StdPairHelper<true, T> {
667     static void trace(Visitor* visitor, T* t)
668     {
669         visitor->trace(*t);
670     }
671 };
672 
673 // This trace trait for std::pair will null weak members if their referent is
674 // collected. If you have a collection that contain weakness it does not remove
675 // entries from the collection that contain nulled weak members.
676 template<typename T, typename U>
677 class TraceTrait<std::pair<T, U> > {
678 public:
679     static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value;
680     static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value;
681     static void trace(Visitor* visitor, std::pair<T, U>* pair)
682     {
683         StdPairHelper<firstNeedsTracing, T>::trace(visitor, &pair->first);
684         StdPairHelper<secondNeedsTracing, U>::trace(visitor, &pair->second);
685     }
686 };
687 
688 // WeakMember is similar to Member in that it is used to point to other oilpan
689 // heap allocated objects.
690 // However instead of creating a strong pointer to the object, the WeakMember creates
691 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to
692 // to a heap allocated object are weak the object will be garbage collected. At the
693 // time of GC the weak pointers will automatically be set to null.
694 template<typename T>
695 class WeakMember : public Member<T> {
696     WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember);
697     WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember);
698 public:
699     WeakMember() : Member<T>() { }
700 
701     WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
702 
703     WeakMember(T* raw) : Member<T>(raw) { }
704 
705     WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
706 
707     template<typename U>
708     WeakMember(const Persistent<U>& other) : Member<T>(other) { }
709 
710     template<typename U>
711     WeakMember(const Member<U>& other) : Member<T>(other) { }
712 
713     template<typename U>
714     WeakMember& operator=(const Persistent<U>& other)
715     {
716         this->m_raw = other;
717         return *this;
718     }
719 
720     template<typename U>
721     WeakMember& operator=(const Member<U>& other)
722     {
723         this->m_raw = other;
724         return *this;
725     }
726 
727     template<typename U>
728     WeakMember& operator=(U* other)
729     {
730         this->m_raw = other;
731         return *this;
732     }
733 
734     template<typename U>
735     WeakMember& operator=(const RawPtr<U>& other)
736     {
737         this->m_raw = other;
738         return *this;
739     }
740 
741     WeakMember& operator=(std::nullptr_t)
742     {
743         this->m_raw = 0;
744         return *this;
745     }
746 
747 private:
748     T** cell() const { return const_cast<T**>(&this->m_raw); }
749 
750     friend class Visitor;
751 };
752 
753 // Comparison operators between (Weak)Members and Persistents
754 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
755 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
756 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
757 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
758 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
759 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
760 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
761 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
762 
763 // CPP-defined type names for the transition period where we want to
764 // support both reference counting and garbage collection based on a
765 // compile-time flag.
766 //
767 // C++11 template aliases were initially used (with clang only, not
768 // with GCC nor MSVC.) However, supporting both CPP defines and
769 // template aliases is problematic from outside a WebCore namespace
770 // when Oilpan is disabled: e.g.,
771 // WebCore::RefCountedWillBeGarbageCollected as a template alias would
772 // uniquely resolve from within any namespace, but if it is backed by
773 // a CPP #define, it would expand to WebCore::RefCounted, and not the
774 // required WTF::RefCounted.
775 //
776 // Having the CPP expansion instead be fully namespace qualified, and the
777 // transition type be unqualified, would dually not work for template
778 // aliases. So, slightly unfortunately, fall back/down to the lowest
779 // commmon denominator of using CPP macros only.
780 #if ENABLE(OILPAN)
781 #define PassRefPtrWillBeRawPtr WTF::RawPtr
782 #define RefCountedWillBeGarbageCollected WebCore::GarbageCollected
783 #define RefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized
784 #define RefCountedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected
785 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized
786 #define ThreadSafeRefCountedWillBeGarbageCollected WebCore::GarbageCollected
787 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized
788 #define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WebCore::ThreadSafeRefCountedGarbageCollected
789 #define PersistentWillBeMember WebCore::Member
790 #define RefPtrWillBePersistent WebCore::Persistent
791 #define RefPtrWillBeRawPtr WTF::RawPtr
792 #define RefPtrWillBeMember WebCore::Member
793 #define RefPtrWillBeWeakMember WebCore::WeakMember
794 #define RefPtrWillBeCrossThreadPersistent WebCore::CrossThreadPersistent
795 #define RawPtrWillBeMember WebCore::Member
796 #define RawPtrWillBeWeakMember WebCore::WeakMember
797 #define OwnPtrWillBeMember WebCore::Member
798 #define OwnPtrWillBePersistent WebCore::Persistent
799 #define OwnPtrWillBeRawPtr WTF::RawPtr
800 #define PassOwnPtrWillBeRawPtr WTF::RawPtr
801 #define WeakPtrWillBeMember WebCore::Member
802 #define WeakPtrWillBeRawPtr WTF::RawPtr
803 #define WeakPtrWillBeWeakMember WebCore::WeakMember
804 #define NoBaseWillBeGarbageCollected WebCore::GarbageCollected
805 #define NoBaseWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized
806 #define NoBaseWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected
807 #define WillBeHeapHashMap WebCore::HeapHashMap
808 #define WillBePersistentHeapHashMap WebCore::PersistentHeapHashMap
809 #define WillBeHeapHashSet WebCore::HeapHashSet
810 #define WillBePersistentHeapHashSet WebCore::PersistentHeapHashSet
811 #define WillBeHeapLinkedHashSet WebCore::HeapLinkedHashSet
812 #define WillBePersistentHeapLinkedHashSet WebCore::PersistentHeapLinkedHashSet
813 #define WillBeHeapListHashSet WebCore::HeapListHashSet
814 #define WillBePersistentHeapListHashSet WebCore::PersistentHeapListHashSet
815 #define WillBeHeapVector WebCore::HeapVector
816 #define WillBePersistentHeapVector WebCore::PersistentHeapVector
817 #define WillBeHeapDeque WebCore::HeapDeque
818 #define WillBePersistentHeapDeque WebCore::PersistentHeapDeque
819 #define WillBeHeapHashCountedSet WebCore::HeapHashCountedSet
820 #define WillBePersistentHeapHashCountedSet WebCore::PersistentHeapHashCountedSet
821 #define WillBeGarbageCollectedMixin WebCore::GarbageCollectedMixin
822 #define WillBeHeapSupplement WebCore::HeapSupplement
823 #define WillBeHeapSupplementable WebCore::HeapSupplementable
824 #define WillBePersistentHeapSupplementable WebCore::PersistentHeapSupplementable
825 #define WillBeHeapTerminatedArray WebCore::HeapTerminatedArray
826 #define WillBeHeapTerminatedArrayBuilder WebCore::HeapTerminatedArrayBuilder
827 #define WillBeHeapLinkedStack WebCore::HeapLinkedStack
828 #define PersistentHeapHashSetWillBeHeapHashSet WebCore::HeapHashSet
829 
830 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr)
831 {
832     static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
833     static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
834     COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
835     COMPILE_ASSERT(notRefCounted, youMustAdopt);
836     return PassRefPtrWillBeRawPtr<T>(ptr);
837 }
838 
839 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr)
840 {
841     static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
842     COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
843     return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
844 }
845 
846 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr)
847 {
848     static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, ThreadSafeRefCountedGarbageCollected>::value;
849     COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop);
850     return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
851 }
852 
853 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr)
854 {
855     static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
856     static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
857     COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
858     COMPILE_ASSERT(notRefCounted, youMustAdopt);
859     return PassOwnPtrWillBeRawPtr<T>(ptr);
860 }
861 
862 template<typename T> T* adoptPtrWillBeRefCountedGarbageCollected(T* ptr)
863 {
864     static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
865     COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
866     return adoptRefCountedGarbageCollected(ptr);
867 }
868 
869 template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
870 {
871     static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
872     static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
873     COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
874     COMPILE_ASSERT(notRefCounted, youMustAdopt);
875     return ptr;
876 }
877 
878 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled.
879 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
880 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
881 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
882 
883 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
884     DEFINE_STATIC_LOCAL(Persistent<type>, name, arguments)
885 
886 #else // !ENABLE(OILPAN)
887 
888 template<typename T>
889 class DummyBase {
890 public:
891     DummyBase() { }
892     ~DummyBase() { }
893 };
894 
895 // Export this instance to support WillBeGarbageCollectedMixin
896 // uses by code residing in non-webcore components.
897 template class PLATFORM_EXPORT DummyBase<void>;
898 
899 #define PassRefPtrWillBeRawPtr WTF::PassRefPtr
900 #define RefCountedWillBeGarbageCollected WTF::RefCounted
901 #define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted
902 #define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted
903 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized WebCore::RefCountedGarbageCollected
904 #define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted
905 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted
906 #define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted
907 #define PersistentWillBeMember WebCore::Persistent
908 #define RefPtrWillBePersistent WTF::RefPtr
909 #define RefPtrWillBeRawPtr WTF::RefPtr
910 #define RefPtrWillBeMember WTF::RefPtr
911 #define RefPtrWillBeWeakMember WTF::RefPtr
912 #define RefPtrWillBeCrossThreadPersistent WTF::RefPtr
913 #define RawPtrWillBeMember WTF::RawPtr
914 #define RawPtrWillBeWeakMember WTF::RawPtr
915 #define OwnPtrWillBeMember WTF::OwnPtr
916 #define OwnPtrWillBePersistent WTF::OwnPtr
917 #define OwnPtrWillBeRawPtr WTF::OwnPtr
918 #define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr
919 #define WeakPtrWillBeMember WTF::WeakPtr
920 #define WeakPtrWillBeRawPtr WTF::WeakPtr
921 #define WeakPtrWillBeWeakMember WTF::WeakPtr
922 #define NoBaseWillBeGarbageCollected WebCore::DummyBase
923 #define NoBaseWillBeGarbageCollectedFinalized WebCore::DummyBase
924 #define NoBaseWillBeRefCountedGarbageCollected WebCore::DummyBase
925 #define WillBeHeapHashMap WTF::HashMap
926 #define WillBePersistentHeapHashMap WTF::HashMap
927 #define WillBeHeapHashSet WTF::HashSet
928 #define WillBePersistentHeapHashSet WTF::HashSet
929 #define WillBeHeapLinkedHashSet WTF::LinkedHashSet
930 #define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet
931 #define WillBeHeapListHashSet WTF::ListHashSet
932 #define WillBePersistentListHeapHashSet WTF::ListHashSet
933 #define WillBeHeapVector WTF::Vector
934 #define WillBePersistentHeapVector WTF::Vector
935 #define WillBeHeapDeque WTF::Deque
936 #define WillBePersistentHeapDeque WTF::Deque
937 #define WillBeHeapHeapCountedSet WTF::HeapCountedSet
938 #define WillBePersistentHeapHeapCountedSet WTF::HeapCountedSet
939 #define WillBeGarbageCollectedMixin WebCore::DummyBase<void>
940 #define WillBeHeapSupplement WebCore::Supplement
941 #define WillBeHeapSupplementable WebCore::Supplementable
942 #define WillBePersistentHeapSupplementable WebCore::Supplementable
943 #define WillBeHeapTerminatedArray WTF::TerminatedArray
944 #define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder
945 #define WillBeHeapLinkedStack WTF::LinkedStack
946 #define PersistentHeapHashSetWillBeHeapHashSet WebCore::PersistentHeapHashSet
947 
948 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
949 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
950 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
951 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
952 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); }
953 
954 template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
955 {
956     static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
957     COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
958     return adoptRefCountedGarbageCollected(ptr);
959 }
960 
961 
962 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED
963 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
964     public:                                            \
965         ~type();                                       \
966     private:
967 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \
968     public:                                                    \
969         virtual ~type();                                       \
970     private:
971 
972 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
973     type::~type() { }
974 
975 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
976     DEFINE_STATIC_REF(type, name, arguments)
977 
978 #endif // ENABLE(OILPAN)
979 
980 } // namespace WebCore
981 
982 namespace WTF {
983 
984 template <typename T> struct VectorTraits<WebCore::Member<T> > : VectorTraitsBase<WebCore::Member<T> > {
985     static const bool needsDestruction = false;
986     static const bool canInitializeWithMemset = true;
987     static const bool canMoveWithMemcpy = true;
988 };
989 
990 template <typename T> struct VectorTraits<WebCore::WeakMember<T> > : VectorTraitsBase<WebCore::WeakMember<T> > {
991     static const bool needsDestruction = false;
992     static const bool canInitializeWithMemset = true;
993     static const bool canMoveWithMemcpy = true;
994 };
995 
996 template <typename T> struct VectorTraits<WebCore::HeapVector<T, 0> > : VectorTraitsBase<WebCore::HeapVector<T, 0> > {
997     static const bool needsDestruction = false;
998     static const bool canInitializeWithMemset = true;
999     static const bool canMoveWithMemcpy = true;
1000 };
1001 
1002 template <typename T> struct VectorTraits<WebCore::HeapDeque<T, 0> > : VectorTraitsBase<WebCore::HeapDeque<T, 0> > {
1003     static const bool needsDestruction = false;
1004     static const bool canInitializeWithMemset = true;
1005     static const bool canMoveWithMemcpy = true;
1006 };
1007 
1008 template <typename T, size_t inlineCapacity> struct VectorTraits<WebCore::HeapVector<T, inlineCapacity> > : VectorTraitsBase<WebCore::HeapVector<T, inlineCapacity> > {
1009     static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1010     static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1011     static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1012 };
1013 
1014 template <typename T, size_t inlineCapacity> struct VectorTraits<WebCore::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<WebCore::HeapDeque<T, inlineCapacity> > {
1015     static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1016     static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1017     static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1018 };
1019 
1020 template<typename T> struct HashTraits<WebCore::Member<T> > : SimpleClassHashTraits<WebCore::Member<T> > {
1021     static const bool needsDestruction = false;
1022     // FIXME: The distinction between PeekInType and PassInType is there for
1023     // the sake of the reference counting handles. When they are gone the two
1024     // types can be merged into PassInType.
1025     // FIXME: Implement proper const'ness for iterator types. Requires support
1026     // in the marking Visitor.
1027     typedef RawPtr<T> PeekInType;
1028     typedef RawPtr<T> PassInType;
1029     typedef WebCore::Member<T>* IteratorGetType;
1030     typedef const WebCore::Member<T>* IteratorConstGetType;
1031     typedef WebCore::Member<T>& IteratorReferenceType;
1032     typedef T* const IteratorConstReferenceType;
1033     static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1034     static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1035     // FIXME: Similarly, there is no need for a distinction between PeekOutType
1036     // and PassOutType without reference counting.
1037     typedef T* PeekOutType;
1038     typedef T* PassOutType;
1039 
1040     template<typename U>
1041     static void store(const U& value, WebCore::Member<T>& storage) { storage = value; }
1042 
1043     static PeekOutType peek(const WebCore::Member<T>& value) { return value; }
1044     static PassOutType passOut(const WebCore::Member<T>& value) { return value; }
1045 };
1046 
1047 template<typename T> struct HashTraits<WebCore::WeakMember<T> > : SimpleClassHashTraits<WebCore::WeakMember<T> > {
1048     static const bool needsDestruction = false;
1049     // FIXME: The distinction between PeekInType and PassInType is there for
1050     // the sake of the reference counting handles. When they are gone the two
1051     // types can be merged into PassInType.
1052     // FIXME: Implement proper const'ness for iterator types. Requires support
1053     // in the marking Visitor.
1054     typedef RawPtr<T> PeekInType;
1055     typedef RawPtr<T> PassInType;
1056     typedef WebCore::WeakMember<T>* IteratorGetType;
1057     typedef const WebCore::WeakMember<T>* IteratorConstGetType;
1058     typedef WebCore::WeakMember<T>& IteratorReferenceType;
1059     typedef T* const IteratorConstReferenceType;
1060     static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1061     static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1062     // FIXME: Similarly, there is no need for a distinction between PeekOutType
1063     // and PassOutType without reference counting.
1064     typedef T* PeekOutType;
1065     typedef T* PassOutType;
1066 
1067     template<typename U>
1068     static void store(const U& value, WebCore::WeakMember<T>& storage) { storage = value; }
1069 
1070     static PeekOutType peek(const WebCore::WeakMember<T>& value) { return value; }
1071     static PassOutType passOut(const WebCore::WeakMember<T>& value) { return value; }
1072     static bool shouldRemoveFromCollection(WebCore::Visitor* visitor, WebCore::WeakMember<T>& value) { return !visitor->isAlive(value); }
1073     static void traceInCollection(WebCore::Visitor* visitor, WebCore::WeakMember<T>& weakMember, WebCore::ShouldWeakPointersBeMarkedStrongly strongify)
1074     {
1075         if (strongify == WebCore::WeakPointersActStrong)
1076             visitor->trace(reinterpret_cast<WebCore::Member<T>&>(weakMember)); // Strongified visit.
1077     }
1078 };
1079 
1080 template<typename T> struct PtrHash<WebCore::Member<T> > : PtrHash<T*> {
1081     template<typename U>
1082     static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); }
1083     static bool equal(T* a, const WebCore::Member<T>& b) { return a == b; }
1084     static bool equal(const WebCore::Member<T>& a, T* b) { return a == b; }
1085     template<typename U, typename V>
1086     static bool equal(const U& a, const V& b) { return a == b; }
1087 };
1088 
1089 template<typename T> struct PtrHash<WebCore::WeakMember<T> > : PtrHash<WebCore::Member<T> > {
1090 };
1091 
1092 template<typename P> struct PtrHash<WebCore::Persistent<P> > : PtrHash<P*> {
1093     using PtrHash<P*>::hash;
1094     static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); }
1095     using PtrHash<P*>::equal;
1096     static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; }
1097     static bool equal(P* a, const RefPtr<P>& b) { return a == b; }
1098     static bool equal(const RefPtr<P>& a, P* b) { return a == b; }
1099 };
1100 
1101 // PtrHash is the default hash for hash tables with members.
1102 template<typename T> struct DefaultHash<WebCore::Member<T> > {
1103     typedef PtrHash<WebCore::Member<T> > Hash;
1104 };
1105 
1106 template<typename T> struct DefaultHash<WebCore::WeakMember<T> > {
1107     typedef PtrHash<WebCore::WeakMember<T> > Hash;
1108 };
1109 
1110 template<typename T> struct DefaultHash<WebCore::Persistent<T> > {
1111     typedef PtrHash<WebCore::Persistent<T> > Hash;
1112 };
1113 
1114 template<typename T>
1115 struct NeedsTracing<WebCore::Member<T> > {
1116     static const bool value = true;
1117 };
1118 
1119 template<typename T>
1120 struct IsWeak<WebCore::WeakMember<T> > {
1121     static const bool value = true;
1122 };
1123 
1124 template<typename T> inline T* getPtr(const WebCore::Member<T>& p)
1125 {
1126     return p.get();
1127 }
1128 
1129 template<typename T, typename U>
1130 struct NeedsTracing<std::pair<T, U> > {
1131     static const bool value = NeedsTracing<T>::value || NeedsTracing<U>::value || IsWeak<T>::value || IsWeak<U>::value;
1132 };
1133 
1134 template<typename T>
1135 struct NeedsTracing<OwnPtr<T> > {
1136     static const bool value = NeedsTracing<T>::value;
1137 };
1138 
1139 // We define specialization of the NeedsTracing trait for off heap collections
1140 // since we don't support tracing them.
1141 template<typename T, size_t N>
1142 struct NeedsTracing<Vector<T, N> > {
1143     static const bool value = false;
1144 };
1145 
1146 template<typename T, size_t N>
1147 struct NeedsTracing<Deque<T, N> > {
1148     static const bool value = false;
1149 };
1150 
1151 template<typename T, typename U, typename V>
1152 struct NeedsTracing<HashCountedSet<T, U, V> > {
1153     static const bool value = false;
1154 };
1155 
1156 template<typename T, typename U, typename V>
1157 struct NeedsTracing<HashSet<T, U, V> > {
1158     static const bool value = false;
1159 };
1160 
1161 template<typename T, size_t U, typename V>
1162 struct NeedsTracing<ListHashSet<T, U, V> > {
1163     static const bool value = false;
1164 };
1165 
1166 template<typename T, typename U, typename V>
1167 struct NeedsTracing<LinkedHashSet<T, U, V> > {
1168     static const bool value = false;
1169 };
1170 
1171 template<typename T, typename U, typename V, typename W, typename X>
1172 struct NeedsTracing<HashMap<T, U, V, W, X> > {
1173     static const bool value = false;
1174 };
1175 
1176 template<typename T, size_t inlineCapacity>
1177 struct NeedsTracing<ListHashSetNode<T, WebCore::HeapListHashSetAllocator<T, inlineCapacity> > *> {
1178     // All heap allocated node pointers need visiting to keep the nodes alive,
1179     // regardless of whether they contain pointers to other heap allocated
1180     // objects.
1181     static const bool value = true;
1182 };
1183 
1184 // For wtf/Functional.h
1185 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
1186 
1187 template<typename T>
1188 struct PointerParamStorageTraits<T*, false> {
1189     typedef T* StorageType;
1190 
1191     static StorageType wrap(T* value) { return value; }
1192     static T* unwrap(const StorageType& value) { return value; }
1193 };
1194 
1195 template<typename T>
1196 struct PointerParamStorageTraits<T*, true> {
1197     typedef WebCore::CrossThreadPersistent<T> StorageType;
1198 
1199     static StorageType wrap(T* value) { return value; }
1200     static T* unwrap(const StorageType& value) { return value.get(); }
1201 };
1202 
1203 template<typename T>
1204 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, WebCore::IsGarbageCollectedType<T>::value> {
1205 };
1206 
1207 template<typename T>
1208 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, WebCore::IsGarbageCollectedType<T>::value> {
1209 };
1210 
1211 } // namespace WTF
1212 
1213 #endif
1214