1a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch/*
2a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * Copyright (C) 2014 Google Inc. All rights reserved.
3a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *
4a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * Redistribution and use in source and binary forms, with or without
5a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * modification, are permitted provided that the following conditions are
6a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * met:
7a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *
8a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *     * Redistributions of source code must retain the above copyright
9a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * notice, this list of conditions and the following disclaimer.
10a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *     * Redistributions in binary form must reproduce the above
11a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
12a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * in the documentation and/or other materials provided with the
13a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * distribution.
14a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
15a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * contributors may be used to endorse or promote products derived from
16a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * this software without specific prior written permission.
17a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *
18a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch */
30a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
31a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#ifndef Handle_h
32a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define Handle_h
33a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/Heap.h"
35a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/ThreadState.h"
36a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/Visitor.h"
375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "wtf/Functional.h"
38a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "wtf/HashFunctions.h"
39a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "wtf/Locker.h"
40a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "wtf/RawPtr.h"
41a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "wtf/RefCounted.h"
42a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "wtf/TypeTraits.h"
43a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
45a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
46a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> class HeapTerminatedArray;
47a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
48f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// Template to determine if a class is a GarbageCollectedMixin by checking if it
49f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// has adjustAndMark and isAlive. We can't check directly if the class is a
50f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// GarbageCollectedMixin because casting to it is potentially ambiguous.
51f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liutemplate<typename T>
52f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustruct IsGarbageCollectedMixin {
53f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    typedef char TrueType;
54f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    struct FalseType {
55f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        char dummy[2];
56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    };
57f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#if COMPILER(MSVC)
59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static TrueType hasAdjustAndMark(char[&U::adjustAndMark != 0]);
60f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static TrueType hasIsAlive(char[&U::isAlive != 0]);
61f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#else
62f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<size_t> struct F;
63f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static TrueType hasAdjustAndMark(F<sizeof(&U::adjustAndMark)>*);
64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static TrueType hasIsAlive(F<sizeof(&U::isAlive)>*);
65f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
66f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static FalseType hasIsAlive(...);
67f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename U> static FalseType hasAdjustAndMark(...);
68f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
69f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    static bool const value = (sizeof(TrueType) == sizeof(hasAdjustAndMark<T>(0))) && (sizeof(TrueType) == sizeof(hasIsAlive<T>(0)));
70f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu};
71f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template <typename T>
735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)struct IsGarbageCollectedType {
74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    typedef char TrueType;
75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    struct FalseType {
76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        char dummy[2];
77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    };
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef typename WTF::RemoveConst<T>::Type NonConstType;
805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate<NonConstType, GarbageCollected> GarbageCollectedSubclass;
815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef IsGarbageCollectedMixin<NonConstType> GarbageCollectedMixinSubclass;
825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashSet> HeapHashSetSubclass;
835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass;
845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass;
855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate5<NonConstType, HeapHashMap> HeapHashMapSubclass;
865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass;
875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass;
885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashCountedSet> HeapHashCountedSetSubclass;
895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef WTF::IsSubclassOfTemplate<NonConstType, HeapTerminatedArray> HeapTerminatedArraySubclass;
90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename U, size_t inlineCapacity> static TrueType listHashSetNodeIsHeapAllocated(WTF::ListHashSetNode<U, HeapListHashSetAllocator<U, inlineCapacity> >*);
92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static FalseType listHashSetNodeIsHeapAllocated(...);
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static const bool isHeapAllocatedListHashSetNode = sizeof(TrueType) == sizeof(listHashSetNodeIsHeapAllocated(reinterpret_cast<NonConstType*>(0)));
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static const bool value =
965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        GarbageCollectedSubclass::value
975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || GarbageCollectedMixinSubclass::value
985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapHashSetSubclass::value
995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapLinkedHashSetSubclass::value
1005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapListHashSetSubclass::value
1015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapHashMapSubclass::value
1025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapVectorSubclass::value
1035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapDequeSubclass::value
1045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        || HeapHashCountedSetSubclass::value
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        || HeapTerminatedArraySubclass::value
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        || isHeapAllocatedListHashSetNode;
1075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)};
1085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \
1105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage)
111a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
112a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> class Member;
113a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
114a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentNode {
115a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
116a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    explicit PersistentNode(TraceCallback trace)
117a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        : m_trace(trace)
118a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
119a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
120a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
121a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool isAlive() { return m_trace; }
122a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
123a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    virtual ~PersistentNode()
124a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
125a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(isAlive());
126a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_trace = 0;
127a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
128a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
129a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // Ideally the trace method should be virtual and automatically dispatch
130a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // to the most specific implementation. However having a virtual method
131a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // on PersistentNode leads to too eager template instantiation with MSVC
132a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // which leads to include cycles.
133a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // Instead we call the constructor with a TraceCallback which knows the
134a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // type of the most specific child and calls trace directly. See
135a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // TraceMethodDelegate in Visitor.h for how this is done.
136a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    void trace(Visitor* visitor)
137a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
138a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_trace(visitor, this);
139a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
140a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
141a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprotected:
142a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    TraceCallback m_trace;
143a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
144a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
145a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentNode* m_next;
146a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentNode* m_prev;
147a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
148a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename RootsAccessor, typename Owner> friend class PersistentBase;
149a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    friend class PersistentAnchor;
150a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    friend class ThreadState;
151a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
152a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciconst int wrapperPersistentsPerRegion = 256;
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciconst size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3);
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciconst size_t wrapperPersistentLiveBitMask = 1;
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass WrapperPersistentNode {
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ALLOW_ONLY_INLINE_ALLOCATION();
1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentRegion* region()
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return reinterpret_cast<WrapperPersistentRegion*>(
1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            reinterpret_cast<Address>(this) - regionOffset());
1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void trace(Visitor* visitor) { }
1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static inline void destroy(const WrapperPersistentNode*);
1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprotected:
1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_regionOffset(regionOffset) { }
1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    size_t regionOffset() { return m_regionOffset & wrapperPersistentOffsetMask; }
1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode* takeSlot()
1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // The slot should not be alive at the point where it is allocated.
1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(!isAlive());
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode*>(m_raw);
1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_raw = 0;
1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return nextFree;
1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_regionOffset &= ~wrapperPersistentLiveBitMask;
1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_raw = nextFree;
1947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return this;
1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Don't allow delete being called on wrapper persistent nodes. We
1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // do use placement new to initialize the slot with the right vtable. See
1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // WrapperPersistent<T> below.
2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void operator delete(void*);
2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprotected:
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // and to point to the next free wrapperPersistentNode in the region when the node is
2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // unused/dead.
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void* m_raw;
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // The m_regionOffset field encodes liveness of the slot as well as being an
2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // offset from this node to the base of the containing WrapperPersistentRegion.
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    size_t m_regionOffset;
2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    friend class WrapperPersistentRegion;
2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitemplate<typename T>
2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass WrapperPersistent FINAL : public WrapperPersistentNode {
2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ALLOW_ONLY_INLINE_ALLOCATION();
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static WrapperPersistent<T>* create(T* raw);
2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void trace(Visitor* visitor) OVERRIDE
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(isAlive());
2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        visitor->mark(static_cast<T*>(m_raw));
2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistent() { }
2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // We need to use a constructor to initialize the allocated slot since it
2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // has a vtable which must be set to the WrapperPersistent<T> type.
2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistent(T* raw, size_t regionOffset) : WrapperPersistentNode(raw, regionOffset) { }
2337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Don't allow delete being called on wrapper persistents.
2357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void operator delete(void*);
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
2377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass PLATFORM_EXPORT WrapperPersistentRegion {
2397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentRegion()
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperPersistentNode* nextFree = 0;
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - reinterpret_cast<Address>(this);
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // Setup the free slot with an offset to the containing region's base and a pointer to the next
2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // free slot in the region.
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            new (&m_entries[i]) WrapperPersistentNode(nextFree, regionOffset);
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            nextFree = &m_entries[i];
2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_prev = 0;
2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_next = 0;
2547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_freeHead = nextFree;
2557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_count = 0;
2567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Address allocate()
2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!m_freeHead) {
2617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ASSERT(m_count == wrapperPersistentsPerRegion);
2627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
2637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
2647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // We have a free persistent slot in this region.
2657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperPersistentNode* freeSlot = m_freeHead;
2667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Take the slot and advance m_freeHead to the next free slot.
2677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_freeHead = freeSlot->takeSlot();
2687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(m_count < wrapperPersistentsPerRegion);
2697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_count++;
2707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return reinterpret_cast<Address>(freeSlot);
2717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void free(WrapperPersistentNode* object)
2747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(object);
2767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_freeHead = object->freeSlot(m_freeHead);
2777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(m_count > 0);
2787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_count--;
2797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!m_count)
2807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ThreadState::current()->freeWrapperPersistentRegion(this);
2817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool removeIfNotLast(WrapperPersistentRegion** headPtr);
2847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentRegion* newHead);
2857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr);
2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static Address outOfLineAllocate(ThreadState*, WrapperPersistentRegion**);
2877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void trace(WrapperPersistentRegion* head, Visitor* visitor)
2887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (WrapperPersistentRegion* current = head; current; current = current->m_next)
2907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            current->traceRegion(visitor);
2917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
2947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void traceRegion(Visitor* visitor)
2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        size_t live = 0;
2977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#ifdef NDEBUG
2997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
3007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#else
3017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // In DEBUG mode we scan all entries to validate we only have m_count
3027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // live entries.
3037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
3047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif
3057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (m_entries[i].isAlive()) {
3067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                m_entries[i].trace(visitor);
3077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                live++;
3087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            }
3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(live == m_count);
3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentRegion* m_prev;
3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentRegion* m_next;
3157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode* m_freeHead;
3167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    size_t m_count;
3177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
3187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
3197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitemplate<typename T>
3217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciWrapperPersistent<T>* WrapperPersistent<T>::create(T* raw)
3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ThreadState* state = ThreadState::current();
3247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentRegion* region = state->wrapperRoots();
3257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(region);
3267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Address persistentSlot = region->allocate();
3277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!persistentSlot)
3287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        persistentSlot = WrapperPersistentRegion::outOfLineAllocate(state, &region);
3297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(persistentSlot);
3307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(!reinterpret_cast<WrapperPersistentNode*>(persistentSlot)->isAlive());
3317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    size_t regionOffset = persistentSlot - reinterpret_cast<Address>(region);
3337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    regionOffset |= wrapperPersistentLiveBitMask;
3347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // We use placement new to call the constructor to ensure that we setup the
3367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // vtable correctly.
3377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return new (persistentSlot) WrapperPersistent<T>(raw, regionOffset);
3387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid WrapperPersistentNode::destroy(const WrapperPersistentNode* node)
3417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode* persistent = const_cast<WrapperPersistentNode*>(node);
3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    persistent->region()->free(persistent);
3447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
346a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// RootsAccessor for Persistent that provides access to thread-local list
347a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// of persistent handles. Can only be used to create handles that
348a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// are constructed and destructed on the same thread.
349a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<ThreadAffinity Affinity>
350a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass ThreadLocalPersistents {
351a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
352a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static PersistentNode* roots() { return state()->roots(); }
353a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
354a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // No locking required. Just check that we are at the right thread.
355a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    class Lock {
356a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    public:
357a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        Lock() { state()->checkThread(); }
358a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    };
359a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
360a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
361a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
362a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
363a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
364a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// RootsAccessor for Persistent that provides synchronized access to global
365a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// list of persistent handles. Can be used for persistent handles that are
366a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// passed between threads.
367a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass GlobalPersistents {
368a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
369a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static PersistentNode* roots() { return ThreadState::globalRoots(); }
370a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
371a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    class Lock {
372a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    public:
373a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        Lock() : m_locker(ThreadState::globalRootsMutex()) { }
374a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    private:
375a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        MutexLocker m_locker;
376a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    };
377a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
378a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
379a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Base class for persistent handles. RootsAccessor specifies which list to
380a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// link resulting handle into. Owner specifies the class containing trace
381a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// method.
382a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename RootsAccessor, typename Owner>
383a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentBase : public PersistentNode {
384a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
385a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ~PersistentBase()
386a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
387a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        typename RootsAccessor::Lock lock;
388a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list.
389a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(isAlive());
390a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(m_next->isAlive());
391a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(m_prev->isAlive());
392a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next->m_prev = m_prev;
393a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_prev->m_next = m_next;
394a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
395a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
396a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprotected:
397a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    inline PersistentBase()
398a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
399197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
400a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        , m_roots(RootsAccessor::roots())
401a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif
402a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
403a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        typename RootsAccessor::Lock lock;
404a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_prev = RootsAccessor::roots();
405a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next = m_prev->m_next;
406a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_prev->m_next = this;
407a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next->m_prev = this;
408a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
409a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
410a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    inline explicit PersistentBase(const PersistentBase& otherref)
411a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        : PersistentNode(otherref.m_trace)
412197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
413a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        , m_roots(RootsAccessor::roots())
414a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif
415a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
416197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // We don't support allocation of thread local Persistents while doing
417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // thread shutdown/cleanup.
418197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(!ThreadState::current()->isTerminating());
419a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        typename RootsAccessor::Lock lock;
420a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list.
421a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        PersistentBase* other = const_cast<PersistentBase*>(&otherref);
422a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_prev = other;
423a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next = other->m_next;
424a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        other->m_next = this;
425a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next->m_prev = this;
426a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
427a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
428a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; }
429a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
430197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
431a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
432a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentNode* m_roots;
433a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif
434a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
435a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
436a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// A dummy Persistent handle that ensures the list of persistents is never null.
437a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// This removes a test from a hot path.
438a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentAnchor : public PersistentNode {
439a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
440a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    void trace(Visitor* visitor)
441a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
442a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        for (PersistentNode* current = m_next; current != this; current = current->m_next)
443a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            current->trace(visitor);
444a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
445a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
446197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    int numberOfPersistents()
447197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
448197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        int numberOfPersistents = 0;
449197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for (PersistentNode* current = m_next; current != this; current = current->m_next)
450197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            ++numberOfPersistents;
451197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return numberOfPersistents;
452197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
453197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
454a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    virtual ~PersistentAnchor()
455a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
456a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a
457a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // large number of objects leaked when we tear down the main thread. Since some of these might contain a
458a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
459a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // this point.
460a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
461a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
462a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
463a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
464a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
465a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_next = this;
466a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_prev = this;
467a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
468a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
469a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    friend class ThreadState;
470a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
471a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
472197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
473a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // For global persistent handles we cannot check that the
474a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // pointer is in the heap because that would involve
475a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // inspecting the heap of running threads.
476a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \
477a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \
478a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer))
479a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#else
480a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer)
481a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif
482a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
483a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
484a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass CrossThreadPersistent;
485a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
486a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Persistent handles are used to store pointers into the
487a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// managed heap. As long as the Persistent handle is alive
488a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// the GC will keep the object pointed to alive. Persistent
489a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// handles can be stored in objects and they are not scoped.
490a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Persistent handles must not be used to contain pointers
491a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// between objects that are in the managed heap. They are only
492a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// meant to point to managed heap objects from variables/members
493a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// outside the managed heap.
494a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch//
495a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// A Persistent is always a GC root from the point of view of
496a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// the garbage collector.
497a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch//
498a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// We have to construct and destruct Persistent with default RootsAccessor in
499a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// the same thread.
500a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ >
501a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > {
502a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent);
503a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent);
504a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
505f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Persistent() : m_raw(0) { }
506a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
507f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Persistent(std::nullptr_t) : m_raw(0) { }
508a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
509a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent(T* raw) : m_raw(raw)
510a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
511a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
5125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
513a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
514a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
515a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    explicit Persistent(T& raw) : m_raw(&raw)
516a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
517a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
5185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
519a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
520a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
5215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); }
522a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
523a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
5245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); }
525a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
526a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
5275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); }
528a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
529a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
5305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); }
531a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
532a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
533a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(U* other)
534a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
535a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
5365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
537a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
538a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
539a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
540a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(std::nullptr_t)
541a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
542a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = 0;
543a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
544a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
545a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
546a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    void clear() { m_raw = 0; }
547a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
548a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    virtual ~Persistent()
549a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
550a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = 0;
551a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
552a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
553a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
554a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    U* as() const
555a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
556a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return static_cast<U*>(m_raw);
557a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
558a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
559f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    void trace(Visitor* visitor)
560f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
561f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent);
562e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILE_MARKING)
5635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName);
564f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
565f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        visitor->mark(m_raw);
566f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
567a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
5687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RawPtr<T> release()
569a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
5707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        RawPtr<T> result = m_raw;
571a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = 0;
572a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return result;
573a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
574a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
575a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T& operator*() const { return *m_raw; }
576a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
577a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool operator!() const { return !m_raw; }
578a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
579a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    operator T*() const { return m_raw; }
580a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    operator RawPtr<T>() const { return m_raw; }
581a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
582a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* operator->() const { return *this; }
583a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
584a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(const Persistent& other)
585a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
586a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
5875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
588a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
589a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
590a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
591a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
592a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(const Persistent<U, RootsAccessor>& other)
593a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
594a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
5955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
596a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
597a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
598a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
599a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
600a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(const Member<U>& other)
601a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
602a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
6035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
604a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
605a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
606a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
607a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
608a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Persistent& operator=(const RawPtr<U>& other)
609a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
610a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
6115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        recordBacktrace();
612a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
613a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
614a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
615a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* get() const { return m_raw; }
616a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
617a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
618e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILE_MARKING)
6195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void recordBacktrace()
6205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
6215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (m_raw)
6225d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_tracingName = Heap::createBacktraceString();
6235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
6245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
6255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    String m_tracingName;
6265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#else
6275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    inline void recordBacktrace() const { }
6285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
629a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* m_raw;
630a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
631a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    friend class CrossThreadPersistent<T>;
632a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
633a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
634a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
635a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// different from the construction thread.
636a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
637a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass CrossThreadPersistent : public Persistent<T, GlobalPersistents> {
638a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent);
639a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent);
640a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
641a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { }
642a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
643a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    using Persistent<T, GlobalPersistents>::operator=;
644a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
645a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
646a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// FIXME: derive affinity based on the collection.
647a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename Collection, ThreadAffinity Affinity = AnyThread>
648a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentHeapCollectionBase
649a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    : public Collection
650a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > {
651f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent
652f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // heap collections are always allocated off-heap. This allows persistent collections to be used in
653f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // DEFINE_STATIC_LOCAL et. al.
654f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
655a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
656a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapCollectionBase() { }
657a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
658a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename OtherCollection>
659a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { }
660a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
6615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void trace(Visitor* visitor)
6625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
663e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILE_MARKING)
6645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        visitor->setHostInfo(this, "PersistentHeapCollectionBase");
6655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
6665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        visitor->trace(*static_cast<Collection*>(this));
6675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
668a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
669a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
670a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<
671a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename KeyArg,
672a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename MappedArg,
673a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename HashArg = typename DefaultHash<KeyArg>::Hash,
674a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename KeyTraitsArg = HashTraits<KeyArg>,
675a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename MappedTraitsArg = HashTraits<MappedArg> >
676a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { };
677a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
678a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<
679a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename ValueArg,
680a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename HashArg = typename DefaultHash<ValueArg>::Hash,
681a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typename TraitsArg = HashTraits<ValueArg> >
682a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { };
683a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
6846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochtemplate<
6856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    typename ValueArg,
6866f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    typename HashArg = typename DefaultHash<ValueArg>::Hash,
6876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    typename TraitsArg = HashTraits<ValueArg> >
6886f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochclass PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { };
6896f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
690323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<
691323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    typename ValueArg,
692323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    size_t inlineCapacity = 0,
693323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    typename HashArg = typename DefaultHash<ValueArg>::Hash>
694323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { };
695323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
696f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liutemplate<typename T, typename U, typename V>
697f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { };
698f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
699a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, size_t inlineCapacity = 0>
700a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > {
701a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
702a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapVector() { }
703a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
704a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<size_t otherCapacity>
705a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
706a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other)
707a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
708a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
709a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
710a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
711a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, size_t inlineCapacity = 0>
712a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > {
713a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
714a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapDeque() { }
715a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
716a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<size_t otherCapacity>
717a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
718a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other)
719a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
720a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
721a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
722a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
723a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Members are used in classes to contain strong pointers to other oilpan heap
724a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// allocated objects.
725a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// All Member fields of a class must be traced in the class' trace method.
726a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// During the mark phase of the GC all live objects are marked as live and
727a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// all Member fields of a live object will be traced marked as live as well.
728a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
729a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass Member {
730a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member);
731a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_ZERO_ASSIGNMENT(Member);
732a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
733a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member() : m_raw(0)
734a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
735a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
736a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
737a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(std::nullptr_t) : m_raw(0)
738a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
739a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
740a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
741a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(T* raw) : m_raw(raw)
742a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
743a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
744a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
745a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    explicit Member(T& raw) : m_raw(&raw)
746a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
747a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
748a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
749a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
750a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(const RawPtr<U>& other) : m_raw(other.get())
751a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
752a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
753a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
754a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
755a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
756a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
757a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
758a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
759a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
760a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
761a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(const Persistent<U>& other) : m_raw(other) { }
762a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
763a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(const Member& other) : m_raw(other) { }
764a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
765a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
766a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member(const Member<U>& other) : m_raw(other) { }
767a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
768a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* release()
769a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
770a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        T* result = m_raw;
771a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = 0;
772a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return result;
773a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
774a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
775a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
776a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    U* as() const
777a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
778a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return static_cast<U*>(m_raw);
779a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
780a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
781a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool operator!() const { return !m_raw; }
782a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
783a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    operator T*() const { return m_raw; }
784a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
785a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* operator->() const { return m_raw; }
786a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T& operator*() const { return *m_raw; }
787f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    template<typename U>
788f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    operator RawPtr<U>() const { return m_raw; }
789a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
790a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
791a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member& operator=(const Persistent<U>& other)
792a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
793a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
794a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
795a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
796a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
797a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
798a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member& operator=(const Member<U>& other)
799a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
800a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
801a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
802a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
803a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
804a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
805a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member& operator=(U* other)
806a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
807a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
808a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
809a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
810a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
811a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
812a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member& operator=(RawPtr<U> other)
813a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
814a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = other;
815a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
816a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
817a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
818a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    Member& operator=(std::nullptr_t)
819a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
820a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        m_raw = 0;
821a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
822a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
823a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
824a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
825a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
826a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* get() const { return m_raw; }
827a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
828a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    void clear() { m_raw = 0; }
829a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
830323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
831a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprotected:
832f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    void verifyTypeIsGarbageCollected() const
833f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
834f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember);
835f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
836f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
837a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T* m_raw;
838a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
839197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
840f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    friend class Visitor;
841a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
842a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
843a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
844a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass TraceTrait<Member<T> > {
845a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
846a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor* visitor, void* self)
847a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
848a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
849a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
850a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
851a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
852a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// TraceTrait to allow compilation of trace method bodies when oilpan is disabled.
853a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// This should never be called, but is needed to compile.
854a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
855a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass TraceTrait<RefPtr<T> > {
856a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
857a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor*, void*)
858a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
859a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ASSERT_NOT_REACHED();
860a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
861a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
862a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
863a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
864a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass TraceTrait<OwnPtr<T> > {
865a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
866a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor* visitor, OwnPtr<T>* ptr)
867a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
868c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT_NOT_REACHED();
869a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
870a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
871a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
872c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T, bool needsTracing>
873c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct TraceIfEnabled;
874a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
875a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
876c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct TraceIfEnabled<T, false>  {
877a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor*, T*) { }
878a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
879a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
880a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
881c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct TraceIfEnabled<T, true> {
882a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor* visitor, T* t)
883a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
884a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        visitor->trace(*t);
885a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
886a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
887a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
888c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> struct RemoveHeapPointerWrapperTypes {
889c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<T, Member>::Type, WeakMember>::Type, RawPtr>::Type Type;
890c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
891c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
892c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// FIXME: Oilpan: TraceIfNeeded should be implemented ala:
893c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// NeedsTracing<T>::value || IsWeakMember<T>::value. It should not need to test
894c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// raw pointer types. To remove these tests, we may need support for
895c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// instantiating a template with a RawPtrOrMember'ish template.
896c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T>
897c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct TraceIfNeeded : public TraceIfEnabled<T, WTF::NeedsTracing<T>::value || blink::IsGarbageCollectedType<typename RemoveHeapPointerWrapperTypes<typename WTF::RemovePointer<T>::Type>::Type>::value> { };
898c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
899a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// This trace trait for std::pair will null weak members if their referent is
900a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// collected. If you have a collection that contain weakness it does not remove
901a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// entries from the collection that contain nulled weak members.
902a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U>
903a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass TraceTrait<std::pair<T, U> > {
904a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
905a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value;
906a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value;
907a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static void trace(Visitor* visitor, std::pair<T, U>* pair)
908a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
909c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TraceIfEnabled<T, firstNeedsTracing>::trace(visitor, &pair->first);
910c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TraceIfEnabled<U, secondNeedsTracing>::trace(visitor, &pair->second);
911a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
912a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
913a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
914a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// WeakMember is similar to Member in that it is used to point to other oilpan
915a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// heap allocated objects.
916a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// However instead of creating a strong pointer to the object, the WeakMember creates
917a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// a weak pointer, which does not keep the pointee alive. Hence if all pointers to
918a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// to a heap allocated object are weak the object will be garbage collected. At the
919a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// time of GC the weak pointers will automatically be set to null.
920a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
921a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass WeakMember : public Member<T> {
922a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember);
923a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember);
924a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
925f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WeakMember() : Member<T>() { }
926a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
927f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
928a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
929f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WeakMember(T* raw) : Member<T>(raw) { }
930a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
931f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
932a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
933a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
934a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember(const Persistent<U>& other) : Member<T>(other) { }
935a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
936a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
937a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember(const Member<U>& other) : Member<T>(other) { }
938a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
939a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
940a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember& operator=(const Persistent<U>& other)
941a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
942a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this->m_raw = other;
943a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
944a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
945a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
946a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
947a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember& operator=(const Member<U>& other)
948a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
949a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this->m_raw = other;
950a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
951a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
952a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
953a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
954a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember& operator=(U* other)
955a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
956a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this->m_raw = other;
957a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
958a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
959a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
960a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
961a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember& operator=(const RawPtr<U>& other)
962a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
963a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this->m_raw = other;
964a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
965a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
966a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
967a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WeakMember& operator=(std::nullptr_t)
968a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    {
969a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        this->m_raw = 0;
970a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        return *this;
971a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
972a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
973a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochprivate:
974a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    T** cell() const { return const_cast<T**>(&this->m_raw); }
975a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
976a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    friend class Visitor;
977a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
978a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
979a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Comparison operators between (Weak)Members and Persistents
980a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
981a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
982a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
983a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
984a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
985a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
986a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
987a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
988a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
989a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// CPP-defined type names for the transition period where we want to
990a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// support both reference counting and garbage collection based on a
991a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// compile-time flag.
992a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch//
993a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// C++11 template aliases were initially used (with clang only, not
994a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// with GCC nor MSVC.) However, supporting both CPP defines and
995a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// template aliases is problematic from outside a WebCore namespace
996a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// when Oilpan is disabled: e.g.,
997c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// blink::RefCountedWillBeGarbageCollected as a template alias would
998a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// uniquely resolve from within any namespace, but if it is backed by
999c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// a CPP #define, it would expand to blink::RefCounted, and not the
1000a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// required WTF::RefCounted.
1001a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch//
1002a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// Having the CPP expansion instead be fully namespace qualified, and the
1003a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// transition type be unqualified, would dually not work for template
1004a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// aliases. So, slightly unfortunately, fall back/down to the lowest
1005a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// commmon denominator of using CPP macros only.
1006a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#if ENABLE(OILPAN)
1007a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define PassRefPtrWillBeRawPtr WTF::RawPtr
1008c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefCountedWillBeGarbageCollected blink::GarbageCollected
1009c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1010c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefCountedWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
1011c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1012c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define ThreadSafeRefCountedWillBeGarbageCollected blink::GarbageCollected
1013c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1014c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected blink::ThreadSafeRefCountedGarbageCollected
1015c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentWillBeMember blink::Member
10167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#define CrossThreadPersistentWillBeMember blink::Member
1017c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefPtrWillBePersistent blink::Persistent
1018a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefPtrWillBeRawPtr WTF::RawPtr
1019c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefPtrWillBeMember blink::Member
1020c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefPtrWillBeWeakMember blink::WeakMember
1021c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent
1022c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RawPtrWillBeMember blink::Member
1023e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#define RawPtrWillBePersistent blink::Persistent
1024c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RawPtrWillBeWeakMember blink::WeakMember
1025c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define OwnPtrWillBeMember blink::Member
1026c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define OwnPtrWillBePersistent blink::Persistent
1027a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define OwnPtrWillBeRawPtr WTF::RawPtr
1028a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define PassOwnPtrWillBeRawPtr WTF::RawPtr
1029c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WeakPtrWillBeMember blink::Member
1030f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#define WeakPtrWillBeRawPtr WTF::RawPtr
1031c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WeakPtrWillBeMember blink::Member
1032c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WeakPtrWillBeWeakMember blink::WeakMember
1033c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeGarbageCollected blink::GarbageCollected
1034c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
1035c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
1036c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapHashMap blink::HeapHashMap
1037c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapHashMap blink::PersistentHeapHashMap
1038c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapHashSet blink::HeapHashSet
1039c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapHashSet blink::PersistentHeapHashSet
1040c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapLinkedHashSet blink::HeapLinkedHashSet
1041c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapLinkedHashSet blink::PersistentHeapLinkedHashSet
1042c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapListHashSet blink::HeapListHashSet
1043c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapListHashSet blink::PersistentHeapListHashSet
1044c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapVector blink::HeapVector
1045c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapVector blink::PersistentHeapVector
1046c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapDeque blink::HeapDeque
1047c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapDeque blink::PersistentHeapDeque
1048c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapHashCountedSet blink::HeapHashCountedSet
1049c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBePersistentHeapHashCountedSet blink::PersistentHeapHashCountedSet
1050c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeGarbageCollectedMixin blink::GarbageCollectedMixin
1051c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapSupplement blink::HeapSupplement
1052c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapSupplementable blink::HeapSupplementable
1053c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapTerminatedArray blink::HeapTerminatedArray
1054c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapTerminatedArrayBuilder blink::HeapTerminatedArrayBuilder
1055c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapLinkedStack blink::HeapLinkedStack
1056c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapHashSetWillBeHeapHashSet blink::HeapHashSet
1057c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapDequeWillBeHeapDeque blink::HeapDeque
1058c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapVectorWillBeHeapVector blink::HeapVector
1059a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1060a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr)
1061a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
1062d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1063d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
1064a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
1065a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    COMPILE_ASSERT(notRefCounted, youMustAdopt);
1066a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    return PassRefPtrWillBeRawPtr<T>(ptr);
1067a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
1068a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1069a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr)
1070a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
1071d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1072a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1073a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
1074a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
1075a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1076323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr)
1077323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
1078d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, ThreadSafeRefCountedGarbageCollected>::value;
1079323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1080323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
1081323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
1082323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
1083a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr)
1084a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
1085d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1086d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
1087a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
1088a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    COMPILE_ASSERT(notRefCounted, youMustAdopt);
1089a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    return PassOwnPtrWillBeRawPtr<T>(ptr);
1090a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
1091a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1092d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)template<typename T> T* adoptPtrWillBeRefCountedGarbageCollected(T* ptr)
1093d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
1094d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
1095d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
1096d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return adoptRefCountedGarbageCollected(ptr);
1097d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
1098d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
10995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
11005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
11015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
11025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
11035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected);
11045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    COMPILE_ASSERT(notRefCounted, youMustAdopt);
11055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return ptr;
11065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
11075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1108a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled.
1109a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1110a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1111a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
1112a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1113323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
1114197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static type* name = (new Persistent<type>(arguments))->get();
1115323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
1116a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#else // !ENABLE(OILPAN)
1117a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1118a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
1119a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass DummyBase {
1120a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochpublic:
1121a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    DummyBase() { }
1122a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    ~DummyBase() { }
1123a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1124a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1125a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define PassRefPtrWillBeRawPtr WTF::PassRefPtr
1126a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefCountedWillBeGarbageCollected WTF::RefCounted
1127a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted
1128a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted
1129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::RefCountedGarbageCollected
1130a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted
1131a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted
1132323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted
1133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentWillBeMember blink::Persistent
11347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#define CrossThreadPersistentWillBeMember blink::CrossThreadPersistent
1135a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefPtrWillBePersistent WTF::RefPtr
1136a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefPtrWillBeRawPtr WTF::RefPtr
1137a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefPtrWillBeMember WTF::RefPtr
1138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#define RefPtrWillBeWeakMember WTF::RefPtr
1139a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RefPtrWillBeCrossThreadPersistent WTF::RefPtr
1140a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RawPtrWillBeMember WTF::RawPtr
1141e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#define RawPtrWillBePersistent WTF::RawPtr
1142a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define RawPtrWillBeWeakMember WTF::RawPtr
1143a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define OwnPtrWillBeMember WTF::OwnPtr
1144a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define OwnPtrWillBePersistent WTF::OwnPtr
1145a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define OwnPtrWillBeRawPtr WTF::OwnPtr
1146a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr
1147f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#define WeakPtrWillBeMember WTF::WeakPtr
1148f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#define WeakPtrWillBeRawPtr WTF::WeakPtr
1149197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define WeakPtrWillBeMember WTF::WeakPtr
1150f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#define WeakPtrWillBeWeakMember WTF::WeakPtr
1151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeGarbageCollected blink::DummyBase
1152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeGarbageCollectedFinalized blink::DummyBase
1153c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define NoBaseWillBeRefCountedGarbageCollected blink::DummyBase
1154a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapHashMap WTF::HashMap
1155a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBePersistentHeapHashMap WTF::HashMap
1156a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapHashSet WTF::HashSet
1157a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBePersistentHeapHashSet WTF::HashSet
11586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#define WillBeHeapLinkedHashSet WTF::LinkedHashSet
11596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet
1160323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#define WillBeHeapListHashSet WTF::ListHashSet
1161323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#define WillBePersistentListHeapHashSet WTF::ListHashSet
1162a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapVector WTF::Vector
1163a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBePersistentHeapVector WTF::Vector
1164a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapDeque WTF::Deque
1165a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBePersistentHeapDeque WTF::Deque
1166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define WillBeHeapHashCountedSet WTF::HashCountedSet
1167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define WillBePersistentHeapHashCountedSet WTF::HashCountedSet
1168c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeGarbageCollectedMixin blink::DummyBase<void>
1169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapSupplement blink::Supplement
1170c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define WillBeHeapSupplementable blink::Supplementable
1171a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapTerminatedArray WTF::TerminatedArray
1172a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder
1173a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WillBeHeapLinkedStack WTF::LinkedStack
1174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapHashSetWillBeHeapHashSet blink::PersistentHeapHashSet
1175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapDequeWillBeHeapDeque blink::PersistentHeapDeque
1176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#define PersistentHeapVectorWillBeHeapVector blink::PersistentHeapVector
1177a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1178a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
1179a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
1180323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
1181a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
1182d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); }
1183a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
11845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr)
11855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
11865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value;
11875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop);
11885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return adoptRefCountedGarbageCollected(ptr);
11895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
11905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
11915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1192a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED
1193a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
1194a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    public:                                            \
1195a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        ~type();                                       \
1196a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    private:
1197a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \
1198a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    public:                                                    \
1199a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        virtual ~type();                                       \
1200a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    private:
1201a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1202a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
1203a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    type::~type() { }
1204a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1205323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
1206323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    DEFINE_STATIC_REF(type, name, arguments)
1207323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
1208a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif // ENABLE(OILPAN)
1209a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1211a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1212a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochnamespace WTF {
1213a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> struct VectorTraits<blink::Member<T> > : VectorTraitsBase<blink::Member<T> > {
1215a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1216a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = true;
1217a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = true;
1218a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1219a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1220c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> struct VectorTraits<blink::WeakMember<T> > : VectorTraitsBase<blink::WeakMember<T> > {
1221a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1222a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = true;
1223a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = true;
1224a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1225a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> struct VectorTraits<blink::HeapVector<T, 0> > : VectorTraitsBase<blink::HeapVector<T, 0> > {
1227a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1228a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = true;
1229a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = true;
1230a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1231a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> struct VectorTraits<blink::HeapDeque<T, 0> > : VectorTraitsBase<blink::HeapDeque<T, 0> > {
1233a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1234a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = true;
1235a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = true;
1236a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1237a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1238c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapVector<T, inlineCapacity> > : VectorTraitsBase<blink::HeapVector<T, inlineCapacity> > {
1239a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1240a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1241a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1242a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1243a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<blink::HeapDeque<T, inlineCapacity> > {
1245a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1246a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1247a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1248a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1249a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1250c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct HashTraits<blink::Member<T> > : SimpleClassHashTraits<blink::Member<T> > {
1251a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1252a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: The distinction between PeekInType and PassInType is there for
1253a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // the sake of the reference counting handles. When they are gone the two
1254a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // types can be merged into PassInType.
1255a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: Implement proper const'ness for iterator types. Requires support
1256a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // in the marking Visitor.
1257a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef RawPtr<T> PeekInType;
1258a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef RawPtr<T> PassInType;
1259c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef blink::Member<T>* IteratorGetType;
1260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef const blink::Member<T>* IteratorConstGetType;
1261c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef blink::Member<T>& IteratorReferenceType;
1262a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* const IteratorConstReferenceType;
1263a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1264a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1265a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: Similarly, there is no need for a distinction between PeekOutType
1266a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // and PassOutType without reference counting.
1267a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* PeekOutType;
1268a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* PassOutType;
1269a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1270a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
1271c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static void store(const U& value, blink::Member<T>& storage) { storage = value; }
1272a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1273c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PeekOutType peek(const blink::Member<T>& value) { return value; }
1274c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassOutType passOut(const blink::Member<T>& value) { return value; }
1275a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1276a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1277c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct HashTraits<blink::WeakMember<T> > : SimpleClassHashTraits<blink::WeakMember<T> > {
1278a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool needsDestruction = false;
1279a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: The distinction between PeekInType and PassInType is there for
1280a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // the sake of the reference counting handles. When they are gone the two
1281a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // types can be merged into PassInType.
1282a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: Implement proper const'ness for iterator types. Requires support
1283a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // in the marking Visitor.
1284a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef RawPtr<T> PeekInType;
1285a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef RawPtr<T> PassInType;
1286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef blink::WeakMember<T>* IteratorGetType;
1287c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef const blink::WeakMember<T>* IteratorConstGetType;
1288c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef blink::WeakMember<T>& IteratorReferenceType;
1289a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* const IteratorConstReferenceType;
1290a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1291a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1292a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: Similarly, there is no need for a distinction between PeekOutType
1293a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // and PassOutType without reference counting.
1294a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* PeekOutType;
1295a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    typedef T* PassOutType;
1296a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1297a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
1298c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static void store(const U& value, blink::WeakMember<T>& storage) { storage = value; }
1299a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1300c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PeekOutType peek(const blink::WeakMember<T>& value) { return value; }
1301c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassOutType passOut(const blink::WeakMember<T>& value) { return value; }
1302c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static bool traceInCollection(blink::Visitor* visitor, blink::WeakMember<T>& weakMember, ShouldWeakPointersBeMarkedStrongly strongify)
13035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
1304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (strongify == WeakPointersActStrong) {
1305c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            visitor->trace(reinterpret_cast<blink::Member<T>&>(weakMember)); // Strongified visit.
1306197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return false;
1307197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
1308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return !visitor->isAlive(weakMember);
13095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
1310a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1311a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1312c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct PtrHash<blink::Member<T> > : PtrHash<T*> {
1313a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U>
1314a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); }
1315c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static bool equal(T* a, const blink::Member<T>& b) { return a == b; }
1316c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static bool equal(const blink::Member<T>& a, T* b) { return a == b; }
1317a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    template<typename U, typename V>
1318a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static bool equal(const U& a, const V& b) { return a == b; }
1319a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1320a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1321c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct PtrHash<blink::WeakMember<T> > : PtrHash<blink::Member<T> > {
1322a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1323a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1324c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename P> struct PtrHash<blink::Persistent<P> > : PtrHash<P*> {
1325a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    using PtrHash<P*>::hash;
1326a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); }
1327a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    using PtrHash<P*>::equal;
1328a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; }
1329a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static bool equal(P* a, const RefPtr<P>& b) { return a == b; }
1330a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static bool equal(const RefPtr<P>& a, P* b) { return a == b; }
1331a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1332a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1333a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch// PtrHash is the default hash for hash tables with members.
1334c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct DefaultHash<blink::Member<T> > {
1335c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef PtrHash<blink::Member<T> > Hash;
1336a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1337a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1338c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct DefaultHash<blink::WeakMember<T> > {
1339c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef PtrHash<blink::WeakMember<T> > Hash;
1340a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1341a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1342c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> struct DefaultHash<blink::Persistent<T> > {
1343c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef PtrHash<blink::Persistent<T> > Hash;
1344a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1345a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1346a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
1347c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct NeedsTracing<blink::Member<T> > {
1348a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool value = true;
1349a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1350a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1351a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtemplate<typename T>
1352c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct IsWeak<blink::WeakMember<T> > {
1353a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    static const bool value = true;
1354a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
1355a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1356c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> inline T* getPtr(const blink::Member<T>& p)
1357a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
1358a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    return p.get();
1359a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
1360a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1361c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> inline T* getPtr(const blink::Persistent<T>& p)
1362197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1363197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return p.get();
1364197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1365a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1366323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<typename T, size_t inlineCapacity>
1367c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct NeedsTracing<ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity> > *> {
1368323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // All heap allocated node pointers need visiting to keep the nodes alive,
1369323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // regardless of whether they contain pointers to other heap allocated
1370323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // objects.
1371323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    static const bool value = true;
1372323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)};
1373323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
13745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// For wtf/Functional.h
13755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
13765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T>
13785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)struct PointerParamStorageTraits<T*, false> {
13795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    typedef T* StorageType;
13805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static StorageType wrap(T* value) { return value; }
13825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static T* unwrap(const StorageType& value) { return value; }
13835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)};
13845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T>
13865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)struct PointerParamStorageTraits<T*, true> {
1387c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef blink::CrossThreadPersistent<T> StorageType;
13885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static StorageType wrap(T* value) { return value; }
13905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    static T* unwrap(const StorageType& value) { return value.get(); }
13915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)};
13925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T>
1394c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
13955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)};
13965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
13975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)template<typename T>
1398c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
13995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)};
14005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1401a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch} // namespace WTF
1402a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
1403a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#endif
1404