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