109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/*
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * modification, are permitted provided that the following conditions are
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * met:
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * in the documentation and/or other materials provided with the
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * distribution.
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * this software without specific prior written permission.
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#ifndef Visitor_h
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#define Visitor_h
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/PlatformExport.h"
35a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/ThreadState.h"
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/Assertions.h"
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/Deque.h"
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/Forward.h"
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/HashMap.h"
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/HashTraits.h"
41f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "wtf/InstanceCounter.h"
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/OwnPtr.h"
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/RefPtr.h"
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/TypeTraits.h"
45f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "wtf/WeakPtr.h"
46e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILING)
47f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "wtf/text/WTFString.h"
48f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#define DEBUG_ONLY(x) x
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#else
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#define DEBUG_ONLY(x)
5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class FinalizedHeapObjectHeader;
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T> class GarbageCollectedFinalized;
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class HeapObjectHeader;
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T> class Member;
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T> class WeakMember;
6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class Visitor;
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct CollectionBackingTraceTrait;
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// The TraceMethodDelegate is used to convert a trace method for type T to a TraceCallback.
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// This allows us to pass a type's trace method as a parameter to the PersistentNode
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// constructor. The PersistentNode constructor needs the specific trace method due an issue
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// with the Windows compiler which instantiates even unused variables. This causes problems
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// in header files where we have only forward declarations of classes.
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T, void (T::*method)(Visitor*)>
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct TraceMethodDelegate {
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*>(self)->*method)(visitor); }
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// GCInfo contains meta-data associated with objects allocated in the
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Blink heap. This meta-data consists of a function pointer used to
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// trace the pointers in the object during garbage collection, an
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// indication of whether or not the object needs a finalization
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// callback, and a function pointer used to finalize the object when
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// the garbage collector determines that the object is no longer
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// reachable. There is a GCInfo struct for each class that directly
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// inherits from GarbageCollected or GarbageCollectedFinalized.
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct GCInfo {
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool hasFinalizer() const { return m_nonTrivialFinalizer; }
87a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool hasVTable() const { return m_hasVTable; }
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    TraceCallback m_trace;
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    FinalizationCallback m_finalize;
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool m_nonTrivialFinalizer;
91a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    bool m_hasVTable;
92e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILING)
93f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // |m_className| is held as a reference to prevent dtor being called at exit.
94f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const String& m_className;
95f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// The FinalizerTraitImpl specifies how to finalize objects. Object
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// that inherit from GarbageCollectedFinalized are finalized by
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// calling their 'finalize' method which by default will call the
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// destructor on the object.
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T, bool isGarbageCollectedFinalized>
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct FinalizerTraitImpl;
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct FinalizerTraitImpl<T, true> {
10743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    static void finalize(void* obj) { static_cast<T*>(obj)->finalizeGarbageCollectedObject(); };
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct FinalizerTraitImpl<T, false> {
11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void finalize(void* obj) { };
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// The FinalizerTrait is used to determine if a type requires
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// finalization and what finalization means.
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)//
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// By default classes that inherit from GarbageCollectedFinalized need
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// finalization and finalization means calling the 'finalize' method
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// of the object. The FinalizerTrait can be specialized if the default
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// behavior is not desired.
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct FinalizerTrait {
124d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool nonTrivialFinalizer = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollectedFinalized>::value;
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void finalize(void* obj) { FinalizerTraitImpl<T, nonTrivialFinalizer>::finalize(obj); }
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Trait to get the GCInfo structure for types that have their
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// instances allocated in the Blink garbage-collected heap.
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T> struct GCInfoTrait;
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T> class GarbageCollected;
133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class GarbageCollectedMixin;
134d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollected>::value> class NeedsAdjustAndMark;
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class NeedsAdjustAndMark<T, true> {
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static const bool value = false;
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
142c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> const bool NeedsAdjustAndMark<T, true>::value;
143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class NeedsAdjustAndMark<T, false> {
146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
147d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    static const bool value = WTF::IsSubclass<typename WTF::RemoveConst<T>::Type, GarbageCollectedMixin>::value;
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
150c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename T> const bool NeedsAdjustAndMark<T, false>::value;
151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrait;
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// The TraceTrait is used to specify how to mark an object pointer and
15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// how to trace all of the pointers in the object.
15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)//
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// By default, the 'trace' method implemented on an object itself is
15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// used to trace the pointers to other heap objects inside the object.
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)//
16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// However, the TraceTrait can be specialized to use a different
16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// implementation. A common case where a TraceTrait specialization is
16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// needed is when multiple inheritance leads to pointers that are not
16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// to the start of the object in the Blink garbage-collected heap. In
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// that case the pointer has to be adjusted before marking.
16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class TraceTrait {
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public:
16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Default implementation of TraceTrait<T>::trace just statically
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // dispatches to the trace method of the class T.
17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void trace(Visitor* visitor, void* self)
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        static_cast<T*>(self)->trace(visitor);
17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void mark(Visitor* visitor, const T* t)
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        DefaultTraceTrait<T>::mark(visitor, t);
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void checkGCInfo(Visitor* visitor, const T* t)
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        DefaultTraceTrait<T>::checkGCInfo(visitor, t);
184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
18509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename Collection>
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct OffHeapCollectionTraceTrait;
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T>
19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct ObjectAliveTrait {
195aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    static bool isAlive(Visitor*, T*);
19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Visitor is used to traverse the Blink object graph. Used for the
19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// marking phase of the mark-sweep garbage collector.
20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)//
20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Pointers are marked and pushed on the marking stack by calling the
20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// |mark| method with the pointer as an argument.
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)//
20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Pointers within objects are traced by calling the |trace| methods
20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// with the object as an argument. Tracing objects will mark all of the
20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// contained pointers and push them on the marking stack.
207a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochclass PLATFORM_EXPORT Visitor {
20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public:
209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual ~Visitor() { }
210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T>
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static void verifyGarbageCollectedIfMember(T*)
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
214197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T>
217197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static void verifyGarbageCollectedIfMember(Member<T>* t)
218197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
219197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        t->verifyTypeIsGarbageCollected();
220197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
221197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // One-argument templated mark method. This uses the static type of
22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // the argument to get the TraceTrait. By default, the mark method
22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // of the TraceTrait just calls the virtual two-argument mark method on this
22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // visitor, where the second argument is the static trace method of the trait.
22609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void mark(T* t)
22809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!t)
23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        TraceTrait<T>::checkGCInfo(this, t);
23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        TraceTrait<T>::mark(this, t);
235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
236197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected();
23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Member version of the one-argument templated trace method.
24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void trace(const Member<T>& t)
24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        mark(t.get());
24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Fallback method used only when we need to trace raw pointers of T.
24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // This is the case when a member is a union where we do not support members.
24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
2495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void trace(const T* t)
2505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
2515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        mark(const_cast<T*>(t));
2525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
2535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
2545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    template<typename T>
25509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void trace(T* t)
25609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
25709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        mark(t);
25809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
25909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
26009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // WeakMember version of the templated trace method. It doesn't keep
26109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // the traced thing alive, but will write null to the WeakMember later
2625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // if the pointed-to object is dead. It's lying for this to be const,
2635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // but the overloading resolver prioritizes constness too high when
2645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // picking the correct overload, so all these trace methods have to have
2655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // the same constness on their argument to allow the type to decide.
26609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
26709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void trace(const WeakMember<T>& t)
26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
26976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // Check that we actually know the definition of T when tracing.
27076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing);
2715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        registerWeakCell(const_cast<WeakMember<T>&>(t).cell());
272197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected();
27309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
2755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    template<typename T>
276197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void traceInCollection(T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongify)
2775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
2785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        HashTraits<T>::traceInCollection(this, t, strongify);
2795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
2805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
2815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // Fallback trace method for part objects to allow individual trace methods
2825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // to trace through a part object with visitor->trace(m_partObject). This
2835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // takes a const argument, because otherwise it will match too eagerly: a
2845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // non-const argument would match a non-const Vector<T>& argument better
2855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // than the specialization that takes const Vector<T>&. For a similar reason,
2865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // the other specializations take a const argument even though they are
2875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // usually used with non-const arguments, otherwise this function would match
2885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // too well.
28909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
29009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void trace(const T& t)
29109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
292e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (WTF::IsPolymorphic<T>::value) {
293e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
294e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            if (!vtable)
295e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                return;
296e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        }
29709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const_cast<T&>(t).trace(this);
29809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
29909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
300323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // The following trace methods are for off-heap collections.
30109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T, size_t inlineCapacity>
3025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void trace(const Vector<T, inlineCapacity>& vector)
30309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
30409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::DefaultAllocator> >::trace(this, vector);
30509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
30709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T, size_t N>
30809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void trace(const Deque<T, N>& deque)
30909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
31009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        OffHeapCollectionTraceTrait<Deque<T, N> >::trace(this, deque);
31109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
31209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
31309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#if !ENABLE(OILPAN)
314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // These trace methods are needed to allow compiling and calling trace on
315197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // transition types. We need to support calls in the non-oilpan build
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // because a fully transitioned type (which will have its trace method
317197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // called) might trace a field that is in transition. Once transition types
318197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // are removed these can be removed.
319197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T> void trace(const OwnPtr<T>&) { }
320197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T> void trace(const RefPtr<T>&) { }
321197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T> void trace(const RawPtr<T>&) { }
322197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename T> void trace(const WeakPtr<T>&) { }
323f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
324f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
32509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // This method marks an object and adds it to the set of objects
32609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // that should have their trace method called. Since not all
32709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // objects have vtables we have to have the callback as an
32809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // explicit argument, but we can use the templated one-argument
32909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // mark method above to automatically provide the callback
33009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // function.
33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void mark(const void*, TraceCallback) = 0;
332323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    virtual void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<TraceCallback>(0)); }
3339e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    virtual void markNoTracing(HeapObjectHeader* header) { mark(header, reinterpret_cast<TraceCallback>(0)); }
3349e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    virtual void markNoTracing(FinalizedHeapObjectHeader* header) { mark(header, reinterpret_cast<TraceCallback>(0)); }
33509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
33609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Used to mark objects during conservative scanning.
33709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void mark(HeapObjectHeader*, TraceCallback) = 0;
33809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0;
33909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Used to delay the marking of objects until the usual marking
3417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // including emphemeron iteration is done. This is used to delay
3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // the marking of collection backing stores until we know if they
3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // are reachable from locations other than the collection front
3447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // object. If collection backings are reachable from other
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // locations we strongify them to avoid issues with iterators and
3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // weak processing.
3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void registerDelayedMarkNoTracing(const void*) = 0;
3487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
34909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // If the object calls this during the regular trace callback, then the
35009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // WeakPointerCallback argument may be called later, when the strong roots
35109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // have all been found. The WeakPointerCallback will normally use isAlive
35209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // to find out whether some pointers are pointing to dying objects. When
35309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // the WeakPointerCallback is done the object must have purged all pointers
35409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // to objects where isAlive returned false. In the weak callback it is not
35509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // allowed to touch other objects (except using isAlive) or to allocate on
35609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // the GC heap. Note that even removing things from HeapHashSet or
35709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // HeapHashMap can cause an allocation if the backing store resizes, but
35809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // these collections know to remove WeakMember elements safely.
359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // The weak pointer callbacks are run on the thread that owns the
361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // object and other threads are not stopped during the
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // callbacks. Since isAlive is used in the callback to determine
363d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // if objects pointed to are alive it is crucial that the object
364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // pointed to belong to the same thread as the object receiving
365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // the weak callback. Since other threads have been resumed the
366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // mark bits are not valid for objects from other threads.
367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual void registerWeakMembers(const void* object, WeakPointerCallback callback) { registerWeakMembers(object, object, callback); }
368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual void registerWeakMembers(const void*, const void*, WeakPointerCallback) = 0;
36909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
37009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T, void (T::*method)(Visitor*)>
37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void registerWeakMembers(const T* obj)
37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
37309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        registerWeakMembers(obj, &TraceMethodDelegate<T, method>::trampoline);
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
37509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // For simple cases where you just want to zero out a cell when the thing
37709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // it is pointing at is garbage, you can use this. This will register a
37809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // callback for each cell that needs to be zeroed, so if you have a lot of
37909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // weak cells in your object you should still consider using
38009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // registerWeakMembers above.
381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // In contrast to registerWeakMembers, the weak cell callbacks are
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // run on the thread performing garbage collection. Therefore, all
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // threads are stopped during weak cell callbacks.
38509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void registerWeakCell(T** cell)
38709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>);
38909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
39009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
391197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCallback) = 0;
392197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
393197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual bool weakTableRegistered(const void*) = 0;
394197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
395197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
39609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual bool isMarked(const void*) = 0;
39709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
398aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    template<typename T> inline bool isAlive(T* obj)
399aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    {
400197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Check that we actually know the definition of T when tracing.
401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing);
402e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // The strongification of collections relies on the fact that once a
403e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // collection has been strongified, there is no way that it can contain
404e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // non-live entries, so no entries will be removed. Since you can't set
405e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // the mark bit on a null pointer, that means that null pointers are
406e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // always 'alive'.
407e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (!obj)
408e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            return true;
409e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return ObjectAliveTrait<T>::isAlive(this, obj);
410aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
41109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T> inline bool isAlive(const Member<T>& member)
41209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
41309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return isAlive(member.get());
41409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
415f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    template<typename T> inline bool isAlive(RawPtr<T> ptr)
416f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
417f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return isAlive(ptr.get());
418f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
41909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
420197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void checkGCInfo(const void*, const GCInfo*);
42209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
42309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
42409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Macro to declare methods needed for each typed heap.
42509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#define DECLARE_VISITOR_METHODS(Type)                                  \
426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);)          \
42709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void mark(const Type*, TraceCallback) = 0;                 \
42809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual bool isMarked(const Type*) = 0;
42909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
43009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS)
43109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#undef DECLARE_VISITOR_METHODS
43209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
433e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILE_MARKING)
434f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    void setHostInfo(void* object, const String& name)
435f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
436f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        m_hostObject = object;
437f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        m_hostName = name;
438f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
439f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
440f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)protected:
442d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual void registerWeakCell(void**, WeakPointerCallback) = 0;
443e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILE_MARKING)
444f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    void* m_hostObject;
445f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    String m_hostName;
446f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
44809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)private:
44909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<typename T>
45009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void handleWeakCell(Visitor* self, void* obj)
45109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
45209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        T** cell = reinterpret_cast<T**>(obj);
45309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (*cell && !self->isAlive(*cell))
45409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            *cell = 0;
45509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
45609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
45709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
45809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// We trace vectors by using the trace trait on each element, which means you
45909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// can have vectors of general objects (not just pointers to objects) that can
46009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// be traced.
46109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T, size_t N>
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > {
46309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector;
46409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
46509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void trace(Visitor* visitor, const Vector& vector)
46609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
46709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (vector.isEmpty())
46809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
46909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (typename Vector::const_iterator it = vector.begin(), end = vector.end(); it != end; ++it)
47009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            TraceTrait<T>::trace(visitor, const_cast<T*>(it));
47109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
47209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
47309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
47409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T, size_t N>
47509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct OffHeapCollectionTraceTrait<WTF::Deque<T, N> > {
47609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    typedef WTF::Deque<T, N> Deque;
47709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
47809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static void trace(Visitor* visitor, const Deque& deque)
47909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
48009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (deque.isEmpty())
48109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
48209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (typename Deque::const_iterator it = deque.begin(), end = deque.end(); it != end; ++it)
48309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            TraceTrait<T>::trace(visitor, const_cast<T*>(&(*it)));
48409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
48509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
48609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
48709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename T, typename Traits = WTF::VectorTraits<T> >
48809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class HeapVectorBacking;
489aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
490aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochtemplate<typename Table>
491aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochclass HeapHashTableBacking {
492aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochpublic:
493aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    static void finalize(void* pointer);
494aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch};
49509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class DefaultTraceTrait<T, false> {
498d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
499d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void mark(Visitor* visitor, const T* t)
500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
501d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Default mark method of the trait just calls the two-argument mark
502d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // method on the visitor. The second argument is the static trace method
503d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // of the trait, which by default calls the instance method
504d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // trace(Visitor*) on the object.
505d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace);
506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
507d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
508197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
509d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void checkGCInfo(Visitor* visitor, const T* t)
510d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get());
512d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
513d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#endif
514d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
515d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
516d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
517d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class DefaultTraceTrait<T, true> {
518d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
519d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void mark(Visitor* visitor, const T* self)
520d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
521197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!self)
522197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return;
523197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
524197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Before doing adjustAndMark we need to check if the page is orphaned
525197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // since we cannot call adjustAndMark if so, as there will be no vtable.
526197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // If orphaned just mark the page as traced.
527197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        BaseHeapPage* heapPage = pageHeaderFromObject(self);
528197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (heapPage->orphaned()) {
529197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            heapPage->setTracedAfterOrphaned();
530197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return;
531197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
532197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        self->adjustAndMark(visitor);
533d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
534d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
535197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
536d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static void checkGCInfo(Visitor*, const T*) { }
53709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
538d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
53909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAliveTrait;
541d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
542d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
543d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class DefaultObjectAliveTrait<T, false> {
544d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
545aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    static bool isAlive(Visitor* visitor, T* obj)
546d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return visitor->isMarked(obj);
548d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
549d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
550d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
551d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
552d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class DefaultObjectAliveTrait<T, true> {
553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
554aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    static bool isAlive(Visitor* visitor, T* obj)
555d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
556d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return obj->isAlive(visitor);
557d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
558d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
55909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
560aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochtemplate<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T* obj)
56109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
562d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return DefaultObjectAliveTrait<T>::isAlive(visitor, obj);
56309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
56409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
565d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// The GarbageCollectedMixin interface and helper macro
566d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define
567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// TraceTrait/ObjectAliveTrait on non-leftmost deriving classes
568d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// which need to be garbage collected.
569d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
570d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Consider the following case:
571d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// class B {};
572d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// class A : public GarbageCollected, public B {};
573d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
574d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// We can't correctly handle "Member<B> p = &a" as we can't compute addr of
575d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// object header statically. This can be solved by using GarbageCollectedMixin:
576d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// class B : public GarbageCollectedMixin {};
577d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// class A : public GarbageCollected, public B {
578d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//   USING_GARBAGE_COLLECTED_MIXIN(A)
579d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// };
580d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
581d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// With the helper, as long as we are using Member<B>, TypeTrait<B> will
582d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// dispatch adjustAndMark dynamically to find collect addr of the object header.
583d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Note that this is only enabled for Member<B>. For Member<A> which we can
584d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// compute the object header addr statically, this dynamic dispatch is not used.
585d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
586c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class PLATFORM_EXPORT GarbageCollectedMixin {
587d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public:
588c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void adjustAndMark(Visitor*) const { };
589c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool isAlive(Visitor*) const { return true; };
590c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void trace(Visitor*) { }
591d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
592d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
594d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public: \
595c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void adjustAndMark(blink::Visitor* visitor) const OVERRIDE    \
596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    { \
597c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, blink::GarbageCollected> IsSubclassOfGarbageCollected; \
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollectedObjectsCanHaveGarbageCollectedMixins); \
599c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::trace); \
600d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } \
601c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool isAlive(blink::Visitor* visitor) const OVERRIDE  \
602d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    { \
603d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return visitor->isAlive(this); \
604d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    } \
605d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)private:
606d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
607d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#if ENABLE(OILPAN)
608d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXIN(TYPE)
609d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#else
610d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE)
611d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#endif
612d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
613e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILING)
614f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liutemplate<typename T>
615f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustruct TypenameStringTrait {
616f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    static const String& get()
617f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
618f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFunctionName(WTF::extractNameFunction<T>())));
619f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return typenameString;
620f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
621f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu};
622f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
623f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)struct GCInfoAtBase {
626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static const GCInfo* get()
627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
628d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        static const GCInfo gcInfo = {
629d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            TraceTrait<T>::trace,
630d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            FinalizerTrait<T>::finalize,
631d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            FinalizerTrait<T>::nonTrivialFinalizer,
632d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            WTF::IsPolymorphic<T>::value,
633e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(GC_PROFILING)
634f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            TypenameStringTrait<T>::get()
635f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
636d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        };
637d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return &gcInfo;
638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
639d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T> class GarbageCollected;
642d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollected>::value> struct GetGarbageCollectedBase;
643d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
644d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
645d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)struct GetGarbageCollectedBase<T, true> {
646d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    typedef typename T::GarbageCollectedBase type;
647d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
648d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
649d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
650d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)struct GetGarbageCollectedBase<T, false> {
651d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    typedef T type;
652d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
653d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
654d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T>
655d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)struct GCInfoTrait {
656d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static const GCInfo* get()
657d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
658d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get();
659d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
660d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)};
661d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
66209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
66309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
66409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
665