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
44namespace blink {
45
46template<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.
51template<typename T>
52struct 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
72template <typename T>
73struct IsGarbageCollectedType {
74    typedef char TrueType;
75    struct FalseType {
76        char dummy[2];
77    };
78
79    typedef typename WTF::RemoveConst<T>::Type NonConstType;
80    typedef WTF::IsSubclassOfTemplate<NonConstType, GarbageCollected> GarbageCollectedSubclass;
81    typedef IsGarbageCollectedMixin<NonConstType> GarbageCollectedMixinSubclass;
82    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashSet> HeapHashSetSubclass;
83    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass;
84    typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass;
85    typedef WTF::IsSubclassOfTemplate5<NonConstType, HeapHashMap> HeapHashMapSubclass;
86    typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass;
87    typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass;
88    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashCountedSet> HeapHashCountedSetSubclass;
89    typedef WTF::IsSubclassOfTemplate<NonConstType, HeapTerminatedArray> HeapTerminatedArraySubclass;
90
91    template<typename U, size_t inlineCapacity> static TrueType listHashSetNodeIsHeapAllocated(WTF::ListHashSetNode<U, HeapListHashSetAllocator<U, inlineCapacity> >*);
92    static FalseType listHashSetNodeIsHeapAllocated(...);
93    static const bool isHeapAllocatedListHashSetNode = sizeof(TrueType) == sizeof(listHashSetNodeIsHeapAllocated(reinterpret_cast<NonConstType*>(0)));
94
95    static const bool value =
96        GarbageCollectedSubclass::value
97        || GarbageCollectedMixinSubclass::value
98        || HeapHashSetSubclass::value
99        || HeapLinkedHashSetSubclass::value
100        || HeapListHashSetSubclass::value
101        || HeapHashMapSubclass::value
102        || HeapVectorSubclass::value
103        || HeapDequeSubclass::value
104        || HeapHashCountedSetSubclass::value
105        || HeapTerminatedArraySubclass::value
106        || isHeapAllocatedListHashSetNode;
107};
108
109#define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \
110    COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage)
111
112template<typename T> class Member;
113
114class PersistentNode {
115public:
116    explicit PersistentNode(TraceCallback trace)
117        : m_trace(trace)
118    {
119    }
120
121    bool isAlive() { return m_trace; }
122
123    virtual ~PersistentNode()
124    {
125        ASSERT(isAlive());
126        m_trace = 0;
127    }
128
129    // Ideally the trace method should be virtual and automatically dispatch
130    // to the most specific implementation. However having a virtual method
131    // on PersistentNode leads to too eager template instantiation with MSVC
132    // which leads to include cycles.
133    // Instead we call the constructor with a TraceCallback which knows the
134    // type of the most specific child and calls trace directly. See
135    // TraceMethodDelegate in Visitor.h for how this is done.
136    void trace(Visitor* visitor)
137    {
138        m_trace(visitor, this);
139    }
140
141protected:
142    TraceCallback m_trace;
143
144private:
145    PersistentNode* m_next;
146    PersistentNode* m_prev;
147
148    template<typename RootsAccessor, typename Owner> friend class PersistentBase;
149    friend class PersistentAnchor;
150    friend class ThreadState;
151};
152
153
154const int wrapperPersistentsPerRegion = 256;
155const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3);
156const size_t wrapperPersistentLiveBitMask = 1;
157
158class WrapperPersistentNode {
159    ALLOW_ONLY_INLINE_ALLOCATION();
160    WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
161public:
162    bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
163
164    WrapperPersistentRegion* region()
165    {
166        return reinterpret_cast<WrapperPersistentRegion*>(
167            reinterpret_cast<Address>(this) - regionOffset());
168    }
169
170    virtual void trace(Visitor* visitor) { }
171
172    static inline void destroy(const WrapperPersistentNode*);
173
174protected:
175    WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
176    WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_regionOffset(regionOffset) { }
177
178private:
179    size_t regionOffset() { return m_regionOffset & wrapperPersistentOffsetMask; }
180
181    WrapperPersistentNode* takeSlot()
182    {
183        // The slot should not be alive at the point where it is allocated.
184        ASSERT(!isAlive());
185        WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode*>(m_raw);
186        m_raw = 0;
187        return nextFree;
188    }
189
190    WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
191    {
192        m_regionOffset &= ~wrapperPersistentLiveBitMask;
193        m_raw = nextFree;
194        return this;
195    }
196
197    // Don't allow delete being called on wrapper persistent nodes. We
198    // do use placement new to initialize the slot with the right vtable. See
199    // WrapperPersistent<T> below.
200    void operator delete(void*);
201
202protected:
203    // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
204    // and to point to the next free wrapperPersistentNode in the region when the node is
205    // unused/dead.
206    void* m_raw;
207
208    // The m_regionOffset field encodes liveness of the slot as well as being an
209    // offset from this node to the base of the containing WrapperPersistentRegion.
210    size_t m_regionOffset;
211
212    friend class WrapperPersistentRegion;
213};
214
215template<typename T>
216class WrapperPersistent FINAL : public WrapperPersistentNode {
217    ALLOW_ONLY_INLINE_ALLOCATION();
218public:
219    static WrapperPersistent<T>* create(T* raw);
220
221    virtual void trace(Visitor* visitor) OVERRIDE
222    {
223        ASSERT(isAlive());
224        visitor->mark(static_cast<T*>(m_raw));
225    }
226
227private:
228    WrapperPersistent() { }
229
230    // We need to use a constructor to initialize the allocated slot since it
231    // has a vtable which must be set to the WrapperPersistent<T> type.
232    WrapperPersistent(T* raw, size_t regionOffset) : WrapperPersistentNode(raw, regionOffset) { }
233
234    // Don't allow delete being called on wrapper persistents.
235    void operator delete(void*);
236};
237
238class PLATFORM_EXPORT WrapperPersistentRegion {
239    WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
240public:
241    WrapperPersistentRegion()
242    {
243        WrapperPersistentNode* nextFree = 0;
244        for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
245            size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - reinterpret_cast<Address>(this);
246            // Setup the free slot with an offset to the containing region's base and a pointer to the next
247            // free slot in the region.
248            ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
249            new (&m_entries[i]) WrapperPersistentNode(nextFree, regionOffset);
250            nextFree = &m_entries[i];
251        }
252        m_prev = 0;
253        m_next = 0;
254        m_freeHead = nextFree;
255        m_count = 0;
256    }
257
258    Address allocate()
259    {
260        if (!m_freeHead) {
261            ASSERT(m_count == wrapperPersistentsPerRegion);
262            return 0;
263        }
264        // We have a free persistent slot in this region.
265        WrapperPersistentNode* freeSlot = m_freeHead;
266        // Take the slot and advance m_freeHead to the next free slot.
267        m_freeHead = freeSlot->takeSlot();
268        ASSERT(m_count < wrapperPersistentsPerRegion);
269        m_count++;
270        return reinterpret_cast<Address>(freeSlot);
271    }
272
273    void free(WrapperPersistentNode* object)
274    {
275        ASSERT(object);
276        m_freeHead = object->freeSlot(m_freeHead);
277        ASSERT(m_count > 0);
278        m_count--;
279        if (!m_count)
280            ThreadState::current()->freeWrapperPersistentRegion(this);
281    }
282
283    bool removeIfNotLast(WrapperPersistentRegion** headPtr);
284    static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentRegion* newHead);
285    static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr);
286    static Address outOfLineAllocate(ThreadState*, WrapperPersistentRegion**);
287    static void trace(WrapperPersistentRegion* head, Visitor* visitor)
288    {
289        for (WrapperPersistentRegion* current = head; current; current = current->m_next)
290            current->traceRegion(visitor);
291    }
292
293private:
294    void traceRegion(Visitor* visitor)
295    {
296        size_t live = 0;
297
298#ifdef NDEBUG
299        for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
300#else
301        // In DEBUG mode we scan all entries to validate we only have m_count
302        // live entries.
303        for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
304#endif
305            if (m_entries[i].isAlive()) {
306                m_entries[i].trace(visitor);
307                live++;
308            }
309        }
310        ASSERT(live == m_count);
311    }
312
313    WrapperPersistentRegion* m_prev;
314    WrapperPersistentRegion* m_next;
315    WrapperPersistentNode* m_freeHead;
316    size_t m_count;
317    WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
318};
319
320template<typename T>
321WrapperPersistent<T>* WrapperPersistent<T>::create(T* raw)
322{
323    ThreadState* state = ThreadState::current();
324    WrapperPersistentRegion* region = state->wrapperRoots();
325    ASSERT(region);
326    Address persistentSlot = region->allocate();
327    if (!persistentSlot)
328        persistentSlot = WrapperPersistentRegion::outOfLineAllocate(state, &region);
329    ASSERT(persistentSlot);
330    ASSERT(!reinterpret_cast<WrapperPersistentNode*>(persistentSlot)->isAlive());
331
332    size_t regionOffset = persistentSlot - reinterpret_cast<Address>(region);
333    regionOffset |= wrapperPersistentLiveBitMask;
334
335    // We use placement new to call the constructor to ensure that we setup the
336    // vtable correctly.
337    return new (persistentSlot) WrapperPersistent<T>(raw, regionOffset);
338}
339
340void WrapperPersistentNode::destroy(const WrapperPersistentNode* node)
341{
342    WrapperPersistentNode* persistent = const_cast<WrapperPersistentNode*>(node);
343    persistent->region()->free(persistent);
344}
345
346// RootsAccessor for Persistent that provides access to thread-local list
347// of persistent handles. Can only be used to create handles that
348// are constructed and destructed on the same thread.
349template<ThreadAffinity Affinity>
350class ThreadLocalPersistents {
351public:
352    static PersistentNode* roots() { return state()->roots(); }
353
354    // No locking required. Just check that we are at the right thread.
355    class Lock {
356    public:
357        Lock() { state()->checkThread(); }
358    };
359
360private:
361    static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
362};
363
364// RootsAccessor for Persistent that provides synchronized access to global
365// list of persistent handles. Can be used for persistent handles that are
366// passed between threads.
367class GlobalPersistents {
368public:
369    static PersistentNode* roots() { return ThreadState::globalRoots(); }
370
371    class Lock {
372    public:
373        Lock() : m_locker(ThreadState::globalRootsMutex()) { }
374    private:
375        MutexLocker m_locker;
376    };
377};
378
379// Base class for persistent handles. RootsAccessor specifies which list to
380// link resulting handle into. Owner specifies the class containing trace
381// method.
382template<typename RootsAccessor, typename Owner>
383class PersistentBase : public PersistentNode {
384public:
385    ~PersistentBase()
386    {
387        typename RootsAccessor::Lock lock;
388        ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list.
389        ASSERT(isAlive());
390        ASSERT(m_next->isAlive());
391        ASSERT(m_prev->isAlive());
392        m_next->m_prev = m_prev;
393        m_prev->m_next = m_next;
394    }
395
396protected:
397    inline PersistentBase()
398        : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
399#if ENABLE(ASSERT)
400        , m_roots(RootsAccessor::roots())
401#endif
402    {
403        typename RootsAccessor::Lock lock;
404        m_prev = RootsAccessor::roots();
405        m_next = m_prev->m_next;
406        m_prev->m_next = this;
407        m_next->m_prev = this;
408    }
409
410    inline explicit PersistentBase(const PersistentBase& otherref)
411        : PersistentNode(otherref.m_trace)
412#if ENABLE(ASSERT)
413        , m_roots(RootsAccessor::roots())
414#endif
415    {
416        // We don't support allocation of thread local Persistents while doing
417        // thread shutdown/cleanup.
418        ASSERT(!ThreadState::current()->isTerminating());
419        typename RootsAccessor::Lock lock;
420        ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list.
421        PersistentBase* other = const_cast<PersistentBase*>(&otherref);
422        m_prev = other;
423        m_next = other->m_next;
424        other->m_next = this;
425        m_next->m_prev = this;
426    }
427
428    inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; }
429
430#if ENABLE(ASSERT)
431private:
432    PersistentNode* m_roots;
433#endif
434};
435
436// A dummy Persistent handle that ensures the list of persistents is never null.
437// This removes a test from a hot path.
438class PersistentAnchor : public PersistentNode {
439public:
440    void trace(Visitor* visitor)
441    {
442        for (PersistentNode* current = m_next; current != this; current = current->m_next)
443            current->trace(visitor);
444    }
445
446    int numberOfPersistents()
447    {
448        int numberOfPersistents = 0;
449        for (PersistentNode* current = m_next; current != this; current = current->m_next)
450            ++numberOfPersistents;
451        return numberOfPersistents;
452    }
453
454    virtual ~PersistentAnchor()
455    {
456        // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a
457        // large number of objects leaked when we tear down the main thread. Since some of these might contain a
458        // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
459        // this point.
460    }
461
462private:
463    PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
464    {
465        m_next = this;
466        m_prev = this;
467    }
468
469    friend class ThreadState;
470};
471
472#if ENABLE(ASSERT)
473    // For global persistent handles we cannot check that the
474    // pointer is in the heap because that would involve
475    // inspecting the heap of running threads.
476#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \
477    bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \
478    ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer))
479#else
480#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer)
481#endif
482
483template<typename T>
484class CrossThreadPersistent;
485
486// Persistent handles are used to store pointers into the
487// managed heap. As long as the Persistent handle is alive
488// the GC will keep the object pointed to alive. Persistent
489// handles can be stored in objects and they are not scoped.
490// Persistent handles must not be used to contain pointers
491// between objects that are in the managed heap. They are only
492// meant to point to managed heap objects from variables/members
493// outside the managed heap.
494//
495// A Persistent is always a GC root from the point of view of
496// the garbage collector.
497//
498// We have to construct and destruct Persistent with default RootsAccessor in
499// the same thread.
500template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ >
501class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > {
502    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent);
503    WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent);
504public:
505    Persistent() : m_raw(0) { }
506
507    Persistent(std::nullptr_t) : m_raw(0) { }
508
509    Persistent(T* raw) : m_raw(raw)
510    {
511        ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
512        recordBacktrace();
513    }
514
515    explicit Persistent(T& raw) : m_raw(&raw)
516    {
517        ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
518        recordBacktrace();
519    }
520
521    Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); }
522
523    template<typename U>
524    Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); }
525
526    template<typename U>
527    Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); }
528
529    template<typename U>
530    Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); }
531
532    template<typename U>
533    Persistent& operator=(U* other)
534    {
535        m_raw = other;
536        recordBacktrace();
537        return *this;
538    }
539
540    Persistent& operator=(std::nullptr_t)
541    {
542        m_raw = 0;
543        return *this;
544    }
545
546    void clear() { m_raw = 0; }
547
548    virtual ~Persistent()
549    {
550        m_raw = 0;
551    }
552
553    template<typename U>
554    U* as() const
555    {
556        return static_cast<U*>(m_raw);
557    }
558
559    void trace(Visitor* visitor)
560    {
561        COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent);
562#if ENABLE(GC_PROFILE_MARKING)
563        visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName);
564#endif
565        visitor->mark(m_raw);
566    }
567
568    RawPtr<T> release()
569    {
570        RawPtr<T> result = m_raw;
571        m_raw = 0;
572        return result;
573    }
574
575    T& operator*() const { return *m_raw; }
576
577    bool operator!() const { return !m_raw; }
578
579    operator T*() const { return m_raw; }
580    operator RawPtr<T>() const { return m_raw; }
581
582    T* operator->() const { return *this; }
583
584    Persistent& operator=(const Persistent& other)
585    {
586        m_raw = other;
587        recordBacktrace();
588        return *this;
589    }
590
591    template<typename U>
592    Persistent& operator=(const Persistent<U, RootsAccessor>& other)
593    {
594        m_raw = other;
595        recordBacktrace();
596        return *this;
597    }
598
599    template<typename U>
600    Persistent& operator=(const Member<U>& other)
601    {
602        m_raw = other;
603        recordBacktrace();
604        return *this;
605    }
606
607    template<typename U>
608    Persistent& operator=(const RawPtr<U>& other)
609    {
610        m_raw = other;
611        recordBacktrace();
612        return *this;
613    }
614
615    T* get() const { return m_raw; }
616
617private:
618#if ENABLE(GC_PROFILE_MARKING)
619    void recordBacktrace()
620    {
621        if (m_raw)
622            m_tracingName = Heap::createBacktraceString();
623    }
624
625    String m_tracingName;
626#else
627    inline void recordBacktrace() const { }
628#endif
629    T* m_raw;
630
631    friend class CrossThreadPersistent<T>;
632};
633
634// Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
635// different from the construction thread.
636template<typename T>
637class CrossThreadPersistent : public Persistent<T, GlobalPersistents> {
638    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent);
639    WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent);
640public:
641    CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { }
642
643    using Persistent<T, GlobalPersistents>::operator=;
644};
645
646// FIXME: derive affinity based on the collection.
647template<typename Collection, ThreadAffinity Affinity = AnyThread>
648class PersistentHeapCollectionBase
649    : public Collection
650    , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > {
651    // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent
652    // heap collections are always allocated off-heap. This allows persistent collections to be used in
653    // DEFINE_STATIC_LOCAL et. al.
654    WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
655public:
656    PersistentHeapCollectionBase() { }
657
658    template<typename OtherCollection>
659    PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { }
660
661    void trace(Visitor* visitor)
662    {
663#if ENABLE(GC_PROFILE_MARKING)
664        visitor->setHostInfo(this, "PersistentHeapCollectionBase");
665#endif
666        visitor->trace(*static_cast<Collection*>(this));
667    }
668};
669
670template<
671    typename KeyArg,
672    typename MappedArg,
673    typename HashArg = typename DefaultHash<KeyArg>::Hash,
674    typename KeyTraitsArg = HashTraits<KeyArg>,
675    typename MappedTraitsArg = HashTraits<MappedArg> >
676class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { };
677
678template<
679    typename ValueArg,
680    typename HashArg = typename DefaultHash<ValueArg>::Hash,
681    typename TraitsArg = HashTraits<ValueArg> >
682class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { };
683
684template<
685    typename ValueArg,
686    typename HashArg = typename DefaultHash<ValueArg>::Hash,
687    typename TraitsArg = HashTraits<ValueArg> >
688class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { };
689
690template<
691    typename ValueArg,
692    size_t inlineCapacity = 0,
693    typename HashArg = typename DefaultHash<ValueArg>::Hash>
694class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { };
695
696template<typename T, typename U, typename V>
697class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { };
698
699template<typename T, size_t inlineCapacity = 0>
700class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > {
701public:
702    PersistentHeapVector() { }
703
704    template<size_t otherCapacity>
705    PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
706        : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other)
707    {
708    }
709};
710
711template<typename T, size_t inlineCapacity = 0>
712class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > {
713public:
714    PersistentHeapDeque() { }
715
716    template<size_t otherCapacity>
717    PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
718        : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other)
719    {
720    }
721};
722
723// Members are used in classes to contain strong pointers to other oilpan heap
724// allocated objects.
725// All Member fields of a class must be traced in the class' trace method.
726// During the mark phase of the GC all live objects are marked as live and
727// all Member fields of a live object will be traced marked as live as well.
728template<typename T>
729class Member {
730    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member);
731    WTF_DISALLOW_ZERO_ASSIGNMENT(Member);
732public:
733    Member() : m_raw(0)
734    {
735    }
736
737    Member(std::nullptr_t) : m_raw(0)
738    {
739    }
740
741    Member(T* raw) : m_raw(raw)
742    {
743    }
744
745    explicit Member(T& raw) : m_raw(&raw)
746    {
747    }
748
749    template<typename U>
750    Member(const RawPtr<U>& other) : m_raw(other.get())
751    {
752    }
753
754    Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
755    {
756    }
757
758    bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
759
760    template<typename U>
761    Member(const Persistent<U>& other) : m_raw(other) { }
762
763    Member(const Member& other) : m_raw(other) { }
764
765    template<typename U>
766    Member(const Member<U>& other) : m_raw(other) { }
767
768    T* release()
769    {
770        T* result = m_raw;
771        m_raw = 0;
772        return result;
773    }
774
775    template<typename U>
776    U* as() const
777    {
778        return static_cast<U*>(m_raw);
779    }
780
781    bool operator!() const { return !m_raw; }
782
783    operator T*() const { return m_raw; }
784
785    T* operator->() const { return m_raw; }
786    T& operator*() const { return *m_raw; }
787    template<typename U>
788    operator RawPtr<U>() const { return m_raw; }
789
790    template<typename U>
791    Member& operator=(const Persistent<U>& other)
792    {
793        m_raw = other;
794        return *this;
795    }
796
797    template<typename U>
798    Member& operator=(const Member<U>& other)
799    {
800        m_raw = other;
801        return *this;
802    }
803
804    template<typename U>
805    Member& operator=(U* other)
806    {
807        m_raw = other;
808        return *this;
809    }
810
811    template<typename U>
812    Member& operator=(RawPtr<U> other)
813    {
814        m_raw = other;
815        return *this;
816    }
817
818    Member& operator=(std::nullptr_t)
819    {
820        m_raw = 0;
821        return *this;
822    }
823
824    void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
825
826    T* get() const { return m_raw; }
827
828    void clear() { m_raw = 0; }
829
830
831protected:
832    void verifyTypeIsGarbageCollected() const
833    {
834        COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember);
835    }
836
837    T* m_raw;
838
839    template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
840    friend class Visitor;
841};
842
843template<typename T>
844class TraceTrait<Member<T> > {
845public:
846    static void trace(Visitor* visitor, void* self)
847    {
848        TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
849    }
850};
851
852// TraceTrait to allow compilation of trace method bodies when oilpan is disabled.
853// This should never be called, but is needed to compile.
854template<typename T>
855class TraceTrait<RefPtr<T> > {
856public:
857    static void trace(Visitor*, void*)
858    {
859        ASSERT_NOT_REACHED();
860    }
861};
862
863template<typename T>
864class TraceTrait<OwnPtr<T> > {
865public:
866    static void trace(Visitor* visitor, OwnPtr<T>* ptr)
867    {
868        ASSERT_NOT_REACHED();
869    }
870};
871
872template<typename T, bool needsTracing>
873struct TraceIfEnabled;
874
875template<typename T>
876struct TraceIfEnabled<T, false>  {
877    static void trace(Visitor*, T*) { }
878};
879
880template<typename T>
881struct TraceIfEnabled<T, true> {
882    static void trace(Visitor* visitor, T* t)
883    {
884        visitor->trace(*t);
885    }
886};
887
888template <typename T> struct RemoveHeapPointerWrapperTypes {
889    typedef typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<T, Member>::Type, WeakMember>::Type, RawPtr>::Type Type;
890};
891
892// FIXME: Oilpan: TraceIfNeeded should be implemented ala:
893// NeedsTracing<T>::value || IsWeakMember<T>::value. It should not need to test
894// raw pointer types. To remove these tests, we may need support for
895// instantiating a template with a RawPtrOrMember'ish template.
896template<typename T>
897struct TraceIfNeeded : public TraceIfEnabled<T, WTF::NeedsTracing<T>::value || blink::IsGarbageCollectedType<typename RemoveHeapPointerWrapperTypes<typename WTF::RemovePointer<T>::Type>::Type>::value> { };
898
899// This trace trait for std::pair will null weak members if their referent is
900// collected. If you have a collection that contain weakness it does not remove
901// entries from the collection that contain nulled weak members.
902template<typename T, typename U>
903class TraceTrait<std::pair<T, U> > {
904public:
905    static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value;
906    static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value;
907    static void trace(Visitor* visitor, std::pair<T, U>* pair)
908    {
909        TraceIfEnabled<T, firstNeedsTracing>::trace(visitor, &pair->first);
910        TraceIfEnabled<U, secondNeedsTracing>::trace(visitor, &pair->second);
911    }
912};
913
914// WeakMember is similar to Member in that it is used to point to other oilpan
915// heap allocated objects.
916// However instead of creating a strong pointer to the object, the WeakMember creates
917// a weak pointer, which does not keep the pointee alive. Hence if all pointers to
918// to a heap allocated object are weak the object will be garbage collected. At the
919// time of GC the weak pointers will automatically be set to null.
920template<typename T>
921class WeakMember : public Member<T> {
922    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember);
923    WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember);
924public:
925    WeakMember() : Member<T>() { }
926
927    WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
928
929    WeakMember(T* raw) : Member<T>(raw) { }
930
931    WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
932
933    template<typename U>
934    WeakMember(const Persistent<U>& other) : Member<T>(other) { }
935
936    template<typename U>
937    WeakMember(const Member<U>& other) : Member<T>(other) { }
938
939    template<typename U>
940    WeakMember& operator=(const Persistent<U>& other)
941    {
942        this->m_raw = other;
943        return *this;
944    }
945
946    template<typename U>
947    WeakMember& operator=(const Member<U>& other)
948    {
949        this->m_raw = other;
950        return *this;
951    }
952
953    template<typename U>
954    WeakMember& operator=(U* other)
955    {
956        this->m_raw = other;
957        return *this;
958    }
959
960    template<typename U>
961    WeakMember& operator=(const RawPtr<U>& other)
962    {
963        this->m_raw = other;
964        return *this;
965    }
966
967    WeakMember& operator=(std::nullptr_t)
968    {
969        this->m_raw = 0;
970        return *this;
971    }
972
973private:
974    T** cell() const { return const_cast<T**>(&this->m_raw); }
975
976    friend class Visitor;
977};
978
979// Comparison operators between (Weak)Members and Persistents
980template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
981template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
982template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
983template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
984template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
985template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
986template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
987template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
988
989// CPP-defined type names for the transition period where we want to
990// support both reference counting and garbage collection based on a
991// compile-time flag.
992//
993// C++11 template aliases were initially used (with clang only, not
994// with GCC nor MSVC.) However, supporting both CPP defines and
995// template aliases is problematic from outside a WebCore namespace
996// when Oilpan is disabled: e.g.,
997// blink::RefCountedWillBeGarbageCollected as a template alias would
998// uniquely resolve from within any namespace, but if it is backed by
999// a CPP #define, it would expand to blink::RefCounted, and not the
1000// required WTF::RefCounted.
1001//
1002// Having the CPP expansion instead be fully namespace qualified, and the
1003// transition type be unqualified, would dually not work for template
1004// aliases. So, slightly unfortunately, fall back/down to the lowest
1005// commmon denominator of using CPP macros only.
1006#if ENABLE(OILPAN)
1007#define PassRefPtrWillBeRawPtr WTF::RawPtr
1008#define RefCountedWillBeGarbageCollected blink::GarbageCollected
1009#define RefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1010#define RefCountedWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
1011#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1012#define ThreadSafeRefCountedWillBeGarbageCollected blink::GarbageCollected
1013#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1014#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected blink::ThreadSafeRefCountedGarbageCollected
1015#define PersistentWillBeMember blink::Member
1016#define CrossThreadPersistentWillBeMember blink::Member
1017#define RefPtrWillBePersistent blink::Persistent
1018#define RefPtrWillBeRawPtr WTF::RawPtr
1019#define RefPtrWillBeMember blink::Member
1020#define RefPtrWillBeWeakMember blink::WeakMember
1021#define RefPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent
1022#define RawPtrWillBeMember blink::Member
1023#define RawPtrWillBePersistent blink::Persistent
1024#define RawPtrWillBeWeakMember blink::WeakMember
1025#define OwnPtrWillBeMember blink::Member
1026#define OwnPtrWillBePersistent blink::Persistent
1027#define OwnPtrWillBeRawPtr WTF::RawPtr
1028#define PassOwnPtrWillBeRawPtr WTF::RawPtr
1029#define WeakPtrWillBeMember blink::Member
1030#define WeakPtrWillBeRawPtr WTF::RawPtr
1031#define WeakPtrWillBeMember blink::Member
1032#define WeakPtrWillBeWeakMember blink::WeakMember
1033#define NoBaseWillBeGarbageCollected blink::GarbageCollected
1034#define NoBaseWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1035#define NoBaseWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
1036#define WillBeHeapHashMap blink::HeapHashMap
1037#define WillBePersistentHeapHashMap blink::PersistentHeapHashMap
1038#define WillBeHeapHashSet blink::HeapHashSet
1039#define WillBePersistentHeapHashSet blink::PersistentHeapHashSet
1040#define WillBeHeapLinkedHashSet blink::HeapLinkedHashSet
1041#define WillBePersistentHeapLinkedHashSet blink::PersistentHeapLinkedHashSet
1042#define WillBeHeapListHashSet blink::HeapListHashSet
1043#define WillBePersistentHeapListHashSet blink::PersistentHeapListHashSet
1044#define WillBeHeapVector blink::HeapVector
1045#define WillBePersistentHeapVector blink::PersistentHeapVector
1046#define WillBeHeapDeque blink::HeapDeque
1047#define WillBePersistentHeapDeque blink::PersistentHeapDeque
1048#define WillBeHeapHashCountedSet blink::HeapHashCountedSet
1049#define WillBePersistentHeapHashCountedSet blink::PersistentHeapHashCountedSet
1050#define WillBeGarbageCollectedMixin blink::GarbageCollectedMixin
1051#define WillBeHeapSupplement blink::HeapSupplement
1052#define WillBeHeapSupplementable blink::HeapSupplementable
1053#define WillBeHeapTerminatedArray blink::HeapTerminatedArray
1054#define WillBeHeapTerminatedArrayBuilder blink::HeapTerminatedArrayBuilder
1055#define WillBeHeapLinkedStack blink::HeapLinkedStack
1056#define PersistentHeapHashSetWillBeHeapHashSet blink::HeapHashSet
1057#define PersistentHeapDequeWillBeHeapDeque blink::HeapDeque
1058#define PersistentHeapVectorWillBeHeapVector blink::HeapVector
1059
1060template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr)
1061{
1062    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1063    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
1064    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
1065    COMPILE_ASSERT(notRefCounted, youMustAdopt);
1066    return PassRefPtrWillBeRawPtr<T>(ptr);
1067}
1068
1069template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr)
1070{
1071    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1072    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1073    return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
1074}
1075
1076template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr)
1077{
1078    static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, ThreadSafeRefCountedGarbageCollected>::value;
1079    COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1080    return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
1081}
1082
1083template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr)
1084{
1085    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1086    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
1087    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
1088    COMPILE_ASSERT(notRefCounted, youMustAdopt);
1089    return PassOwnPtrWillBeRawPtr<T>(ptr);
1090}
1091
1092template<typename T> T* adoptPtrWillBeRefCountedGarbageCollected(T* ptr)
1093{
1094    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1095    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1096    return adoptRefCountedGarbageCollected(ptr);
1097}
1098
1099template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
1100{
1101    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1102    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
1103    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
1104    COMPILE_ASSERT(notRefCounted, youMustAdopt);
1105    return ptr;
1106}
1107
1108#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled.
1109#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1110#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1111#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1112
1113#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
1114    static type* name = (new Persistent<type>(arguments))->get();
1115
1116#else // !ENABLE(OILPAN)
1117
1118template<typename T>
1119class DummyBase {
1120public:
1121    DummyBase() { }
1122    ~DummyBase() { }
1123};
1124
1125#define PassRefPtrWillBeRawPtr WTF::PassRefPtr
1126#define RefCountedWillBeGarbageCollected WTF::RefCounted
1127#define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted
1128#define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted
1129#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::RefCountedGarbageCollected
1130#define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted
1131#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted
1132#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted
1133#define PersistentWillBeMember blink::Persistent
1134#define CrossThreadPersistentWillBeMember blink::CrossThreadPersistent
1135#define RefPtrWillBePersistent WTF::RefPtr
1136#define RefPtrWillBeRawPtr WTF::RefPtr
1137#define RefPtrWillBeMember WTF::RefPtr
1138#define RefPtrWillBeWeakMember WTF::RefPtr
1139#define RefPtrWillBeCrossThreadPersistent WTF::RefPtr
1140#define RawPtrWillBeMember WTF::RawPtr
1141#define RawPtrWillBePersistent WTF::RawPtr
1142#define RawPtrWillBeWeakMember WTF::RawPtr
1143#define OwnPtrWillBeMember WTF::OwnPtr
1144#define OwnPtrWillBePersistent WTF::OwnPtr
1145#define OwnPtrWillBeRawPtr WTF::OwnPtr
1146#define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr
1147#define WeakPtrWillBeMember WTF::WeakPtr
1148#define WeakPtrWillBeRawPtr WTF::WeakPtr
1149#define WeakPtrWillBeMember WTF::WeakPtr
1150#define WeakPtrWillBeWeakMember WTF::WeakPtr
1151#define NoBaseWillBeGarbageCollected blink::DummyBase
1152#define NoBaseWillBeGarbageCollectedFinalized blink::DummyBase
1153#define NoBaseWillBeRefCountedGarbageCollected blink::DummyBase
1154#define WillBeHeapHashMap WTF::HashMap
1155#define WillBePersistentHeapHashMap WTF::HashMap
1156#define WillBeHeapHashSet WTF::HashSet
1157#define WillBePersistentHeapHashSet WTF::HashSet
1158#define WillBeHeapLinkedHashSet WTF::LinkedHashSet
1159#define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet
1160#define WillBeHeapListHashSet WTF::ListHashSet
1161#define WillBePersistentListHeapHashSet WTF::ListHashSet
1162#define WillBeHeapVector WTF::Vector
1163#define WillBePersistentHeapVector WTF::Vector
1164#define WillBeHeapDeque WTF::Deque
1165#define WillBePersistentHeapDeque WTF::Deque
1166#define WillBeHeapHashCountedSet WTF::HashCountedSet
1167#define WillBePersistentHeapHashCountedSet WTF::HashCountedSet
1168#define WillBeGarbageCollectedMixin blink::DummyBase<void>
1169#define WillBeHeapSupplement blink::Supplement
1170#define WillBeHeapSupplementable blink::Supplementable
1171#define WillBeHeapTerminatedArray WTF::TerminatedArray
1172#define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder
1173#define WillBeHeapLinkedStack WTF::LinkedStack
1174#define PersistentHeapHashSetWillBeHeapHashSet blink::PersistentHeapHashSet
1175#define PersistentHeapDequeWillBeHeapDeque blink::PersistentHeapDeque
1176#define PersistentHeapVectorWillBeHeapVector blink::PersistentHeapVector
1177
1178template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
1179template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
1180template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
1181template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
1182template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); }
1183
1184template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
1185{
1186    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1187    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1188    return adoptRefCountedGarbageCollected(ptr);
1189}
1190
1191
1192#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED
1193#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
1194    public:                                            \
1195        ~type();                                       \
1196    private:
1197#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \
1198    public:                                                    \
1199        virtual ~type();                                       \
1200    private:
1201
1202#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
1203    type::~type() { }
1204
1205#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
1206    DEFINE_STATIC_REF(type, name, arguments)
1207
1208#endif // ENABLE(OILPAN)
1209
1210} // namespace blink
1211
1212namespace WTF {
1213
1214template <typename T> struct VectorTraits<blink::Member<T> > : VectorTraitsBase<blink::Member<T> > {
1215    static const bool needsDestruction = false;
1216    static const bool canInitializeWithMemset = true;
1217    static const bool canMoveWithMemcpy = true;
1218};
1219
1220template <typename T> struct VectorTraits<blink::WeakMember<T> > : VectorTraitsBase<blink::WeakMember<T> > {
1221    static const bool needsDestruction = false;
1222    static const bool canInitializeWithMemset = true;
1223    static const bool canMoveWithMemcpy = true;
1224};
1225
1226template <typename T> struct VectorTraits<blink::HeapVector<T, 0> > : VectorTraitsBase<blink::HeapVector<T, 0> > {
1227    static const bool needsDestruction = false;
1228    static const bool canInitializeWithMemset = true;
1229    static const bool canMoveWithMemcpy = true;
1230};
1231
1232template <typename T> struct VectorTraits<blink::HeapDeque<T, 0> > : VectorTraitsBase<blink::HeapDeque<T, 0> > {
1233    static const bool needsDestruction = false;
1234    static const bool canInitializeWithMemset = true;
1235    static const bool canMoveWithMemcpy = true;
1236};
1237
1238template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapVector<T, inlineCapacity> > : VectorTraitsBase<blink::HeapVector<T, inlineCapacity> > {
1239    static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1240    static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1241    static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1242};
1243
1244template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<blink::HeapDeque<T, inlineCapacity> > {
1245    static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1246    static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1247    static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1248};
1249
1250template<typename T> struct HashTraits<blink::Member<T> > : SimpleClassHashTraits<blink::Member<T> > {
1251    static const bool needsDestruction = false;
1252    // FIXME: The distinction between PeekInType and PassInType is there for
1253    // the sake of the reference counting handles. When they are gone the two
1254    // types can be merged into PassInType.
1255    // FIXME: Implement proper const'ness for iterator types. Requires support
1256    // in the marking Visitor.
1257    typedef RawPtr<T> PeekInType;
1258    typedef RawPtr<T> PassInType;
1259    typedef blink::Member<T>* IteratorGetType;
1260    typedef const blink::Member<T>* IteratorConstGetType;
1261    typedef blink::Member<T>& IteratorReferenceType;
1262    typedef T* const IteratorConstReferenceType;
1263    static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1264    static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1265    // FIXME: Similarly, there is no need for a distinction between PeekOutType
1266    // and PassOutType without reference counting.
1267    typedef T* PeekOutType;
1268    typedef T* PassOutType;
1269
1270    template<typename U>
1271    static void store(const U& value, blink::Member<T>& storage) { storage = value; }
1272
1273    static PeekOutType peek(const blink::Member<T>& value) { return value; }
1274    static PassOutType passOut(const blink::Member<T>& value) { return value; }
1275};
1276
1277template<typename T> struct HashTraits<blink::WeakMember<T> > : SimpleClassHashTraits<blink::WeakMember<T> > {
1278    static const bool needsDestruction = false;
1279    // FIXME: The distinction between PeekInType and PassInType is there for
1280    // the sake of the reference counting handles. When they are gone the two
1281    // types can be merged into PassInType.
1282    // FIXME: Implement proper const'ness for iterator types. Requires support
1283    // in the marking Visitor.
1284    typedef RawPtr<T> PeekInType;
1285    typedef RawPtr<T> PassInType;
1286    typedef blink::WeakMember<T>* IteratorGetType;
1287    typedef const blink::WeakMember<T>* IteratorConstGetType;
1288    typedef blink::WeakMember<T>& IteratorReferenceType;
1289    typedef T* const IteratorConstReferenceType;
1290    static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1291    static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1292    // FIXME: Similarly, there is no need for a distinction between PeekOutType
1293    // and PassOutType without reference counting.
1294    typedef T* PeekOutType;
1295    typedef T* PassOutType;
1296
1297    template<typename U>
1298    static void store(const U& value, blink::WeakMember<T>& storage) { storage = value; }
1299
1300    static PeekOutType peek(const blink::WeakMember<T>& value) { return value; }
1301    static PassOutType passOut(const blink::WeakMember<T>& value) { return value; }
1302    static bool traceInCollection(blink::Visitor* visitor, blink::WeakMember<T>& weakMember, ShouldWeakPointersBeMarkedStrongly strongify)
1303    {
1304        if (strongify == WeakPointersActStrong) {
1305            visitor->trace(reinterpret_cast<blink::Member<T>&>(weakMember)); // Strongified visit.
1306            return false;
1307        }
1308        return !visitor->isAlive(weakMember);
1309    }
1310};
1311
1312template<typename T> struct PtrHash<blink::Member<T> > : PtrHash<T*> {
1313    template<typename U>
1314    static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); }
1315    static bool equal(T* a, const blink::Member<T>& b) { return a == b; }
1316    static bool equal(const blink::Member<T>& a, T* b) { return a == b; }
1317    template<typename U, typename V>
1318    static bool equal(const U& a, const V& b) { return a == b; }
1319};
1320
1321template<typename T> struct PtrHash<blink::WeakMember<T> > : PtrHash<blink::Member<T> > {
1322};
1323
1324template<typename P> struct PtrHash<blink::Persistent<P> > : PtrHash<P*> {
1325    using PtrHash<P*>::hash;
1326    static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); }
1327    using PtrHash<P*>::equal;
1328    static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; }
1329    static bool equal(P* a, const RefPtr<P>& b) { return a == b; }
1330    static bool equal(const RefPtr<P>& a, P* b) { return a == b; }
1331};
1332
1333// PtrHash is the default hash for hash tables with members.
1334template<typename T> struct DefaultHash<blink::Member<T> > {
1335    typedef PtrHash<blink::Member<T> > Hash;
1336};
1337
1338template<typename T> struct DefaultHash<blink::WeakMember<T> > {
1339    typedef PtrHash<blink::WeakMember<T> > Hash;
1340};
1341
1342template<typename T> struct DefaultHash<blink::Persistent<T> > {
1343    typedef PtrHash<blink::Persistent<T> > Hash;
1344};
1345
1346template<typename T>
1347struct NeedsTracing<blink::Member<T> > {
1348    static const bool value = true;
1349};
1350
1351template<typename T>
1352struct IsWeak<blink::WeakMember<T> > {
1353    static const bool value = true;
1354};
1355
1356template<typename T> inline T* getPtr(const blink::Member<T>& p)
1357{
1358    return p.get();
1359}
1360
1361template<typename T> inline T* getPtr(const blink::Persistent<T>& p)
1362{
1363    return p.get();
1364}
1365
1366template<typename T, size_t inlineCapacity>
1367struct NeedsTracing<ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity> > *> {
1368    // All heap allocated node pointers need visiting to keep the nodes alive,
1369    // regardless of whether they contain pointers to other heap allocated
1370    // objects.
1371    static const bool value = true;
1372};
1373
1374// For wtf/Functional.h
1375template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
1376
1377template<typename T>
1378struct PointerParamStorageTraits<T*, false> {
1379    typedef T* StorageType;
1380
1381    static StorageType wrap(T* value) { return value; }
1382    static T* unwrap(const StorageType& value) { return value; }
1383};
1384
1385template<typename T>
1386struct PointerParamStorageTraits<T*, true> {
1387    typedef blink::CrossThreadPersistent<T> StorageType;
1388
1389    static StorageType wrap(T* value) { return value; }
1390    static T* unwrap(const StorageType& value) { return value.get(); }
1391};
1392
1393template<typename T>
1394struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
1395};
1396
1397template<typename T>
1398struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
1399};
1400
1401} // namespace WTF
1402
1403#endif
1404