Home | History | Annotate | Download | only in heap
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef Visitor_h
     32 #define Visitor_h
     33 
     34 #include "platform/PlatformExport.h"
     35 #include "platform/heap/ThreadState.h"
     36 #include "wtf/Assertions.h"
     37 #include "wtf/Deque.h"
     38 #include "wtf/Forward.h"
     39 #include "wtf/HashCountedSet.h"
     40 #include "wtf/HashMap.h"
     41 #include "wtf/HashSet.h"
     42 #include "wtf/HashTraits.h"
     43 #include "wtf/InstanceCounter.h"
     44 #include "wtf/LinkedHashSet.h"
     45 #include "wtf/ListHashSet.h"
     46 #include "wtf/OwnPtr.h"
     47 #include "wtf/RefPtr.h"
     48 #include "wtf/TypeTraits.h"
     49 #include "wtf/WeakPtr.h"
     50 #if ENABLE(GC_TRACING)
     51 #include "wtf/text/WTFString.h"
     52 #endif
     53 
     54 #ifndef NDEBUG
     55 #define DEBUG_ONLY(x) x
     56 #else
     57 #define DEBUG_ONLY(x)
     58 #endif
     59 
     60 namespace WebCore {
     61 
     62 class FinalizedHeapObjectHeader;
     63 template<typename T> class GarbageCollectedFinalized;
     64 class HeapObjectHeader;
     65 template<typename T> class Member;
     66 template<typename T> class WeakMember;
     67 class Visitor;
     68 
     69 enum ShouldWeakPointersBeMarkedStrongly {
     70     WeakPointersActStrong,
     71     WeakPointersActWeak
     72 };
     73 
     74 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct CollectionBackingTraceTrait;
     75 
     76 // The TraceMethodDelegate is used to convert a trace method for type T to a TraceCallback.
     77 // This allows us to pass a type's trace method as a parameter to the PersistentNode
     78 // constructor. The PersistentNode constructor needs the specific trace method due an issue
     79 // with the Windows compiler which instantiates even unused variables. This causes problems
     80 // in header files where we have only forward declarations of classes.
     81 template<typename T, void (T::*method)(Visitor*)>
     82 struct TraceMethodDelegate {
     83     static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*>(self)->*method)(visitor); }
     84 };
     85 
     86 // GCInfo contains meta-data associated with objects allocated in the
     87 // Blink heap. This meta-data consists of a function pointer used to
     88 // trace the pointers in the object during garbage collection, an
     89 // indication of whether or not the object needs a finalization
     90 // callback, and a function pointer used to finalize the object when
     91 // the garbage collector determines that the object is no longer
     92 // reachable. There is a GCInfo struct for each class that directly
     93 // inherits from GarbageCollected or GarbageCollectedFinalized.
     94 struct GCInfo {
     95     bool hasFinalizer() const { return m_nonTrivialFinalizer; }
     96     bool hasVTable() const { return m_hasVTable; }
     97     TraceCallback m_trace;
     98     FinalizationCallback m_finalize;
     99     bool m_nonTrivialFinalizer;
    100     bool m_hasVTable;
    101 #if ENABLE(GC_TRACING)
    102     // |m_className| is held as a reference to prevent dtor being called at exit.
    103     const String& m_className;
    104 #endif
    105 };
    106 
    107 // The FinalizerTraitImpl specifies how to finalize objects. Object
    108 // that inherit from GarbageCollectedFinalized are finalized by
    109 // calling their 'finalize' method which by default will call the
    110 // destructor on the object.
    111 template<typename T, bool isGarbageCollectedFinalized>
    112 struct FinalizerTraitImpl;
    113 
    114 template<typename T>
    115 struct FinalizerTraitImpl<T, true> {
    116     static void finalize(void* obj) { static_cast<T*>(obj)->finalizeGarbageCollectedObject(); };
    117 };
    118 
    119 template<typename T>
    120 struct FinalizerTraitImpl<T, false> {
    121     static void finalize(void* obj) { };
    122 };
    123 
    124 // The FinalizerTrait is used to determine if a type requires
    125 // finalization and what finalization means.
    126 //
    127 // By default classes that inherit from GarbageCollectedFinalized need
    128 // finalization and finalization means calling the 'finalize' method
    129 // of the object. The FinalizerTrait can be specialized if the default
    130 // behavior is not desired.
    131 template<typename T>
    132 struct FinalizerTrait {
    133     static const bool nonTrivialFinalizer = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollectedFinalized>::value;
    134     static void finalize(void* obj) { FinalizerTraitImpl<T, nonTrivialFinalizer>::finalize(obj); }
    135 };
    136 
    137 // Trait to get the GCInfo structure for types that have their
    138 // instances allocated in the Blink garbage-collected heap.
    139 template<typename T> struct GCInfoTrait;
    140 
    141 template<typename T> class GarbageCollected;
    142 class GarbageCollectedMixin;
    143 template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollected>::value> class NeedsAdjustAndMark;
    144 
    145 template<typename T>
    146 class NeedsAdjustAndMark<T, true> {
    147 public:
    148     static const bool value = false;
    149 };
    150 
    151 template<typename T>
    152 class NeedsAdjustAndMark<T, false> {
    153 public:
    154     static const bool value = WTF::IsSubclass<typename WTF::RemoveConst<T>::Type, GarbageCollectedMixin>::value;
    155 };
    156 
    157 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrait;
    158 
    159 // The TraceTrait is used to specify how to mark an object pointer and
    160 // how to trace all of the pointers in the object.
    161 //
    162 // By default, the 'trace' method implemented on an object itself is
    163 // used to trace the pointers to other heap objects inside the object.
    164 //
    165 // However, the TraceTrait can be specialized to use a different
    166 // implementation. A common case where a TraceTrait specialization is
    167 // needed is when multiple inheritance leads to pointers that are not
    168 // to the start of the object in the Blink garbage-collected heap. In
    169 // that case the pointer has to be adjusted before marking.
    170 template<typename T>
    171 class TraceTrait {
    172 public:
    173     // Default implementation of TraceTrait<T>::trace just statically
    174     // dispatches to the trace method of the class T.
    175     static void trace(Visitor* visitor, void* self)
    176     {
    177         static_cast<T*>(self)->trace(visitor);
    178     }
    179 
    180     static void mark(Visitor* visitor, const T* t)
    181     {
    182         DefaultTraceTrait<T>::mark(visitor, t);
    183     }
    184 
    185 #ifndef NDEBUG
    186     static void checkGCInfo(Visitor* visitor, const T* t)
    187     {
    188         DefaultTraceTrait<T>::checkGCInfo(visitor, t);
    189     }
    190 #endif
    191 };
    192 
    193 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
    194 
    195 template<typename Collection>
    196 struct OffHeapCollectionTraceTrait;
    197 
    198 template<typename T>
    199 struct ObjectAliveTrait {
    200     static bool isAlive(Visitor*, T*);
    201 };
    202 
    203 // Visitor is used to traverse the Blink object graph. Used for the
    204 // marking phase of the mark-sweep garbage collector.
    205 //
    206 // Pointers are marked and pushed on the marking stack by calling the
    207 // |mark| method with the pointer as an argument.
    208 //
    209 // Pointers within objects are traced by calling the |trace| methods
    210 // with the object as an argument. Tracing objects will mark all of the
    211 // contained pointers and push them on the marking stack.
    212 class PLATFORM_EXPORT Visitor {
    213 public:
    214     virtual ~Visitor() { }
    215 
    216     // One-argument templated mark method. This uses the static type of
    217     // the argument to get the TraceTrait. By default, the mark method
    218     // of the TraceTrait just calls the virtual two-argument mark method on this
    219     // visitor, where the second argument is the static trace method of the trait.
    220     template<typename T>
    221     void mark(T* t)
    222     {
    223         if (!t)
    224             return;
    225 #ifndef NDEBUG
    226         TraceTrait<T>::checkGCInfo(this, t);
    227 #endif
    228         TraceTrait<T>::mark(this, t);
    229     }
    230 
    231     // Member version of the one-argument templated trace method.
    232     template<typename T>
    233     void trace(const Member<T>& t)
    234     {
    235         t.verifyTypeIsGarbageCollected();
    236         mark(t.get());
    237     }
    238 
    239     // Fallback method used only when we need to trace raw pointers of T.
    240     // This is the case when a member is a union where we do not support members.
    241     template<typename T>
    242     void trace(const T* t)
    243     {
    244         mark(const_cast<T*>(t));
    245     }
    246 
    247     template<typename T>
    248     void trace(T* t)
    249     {
    250         mark(t);
    251     }
    252 
    253     // WeakMember version of the templated trace method. It doesn't keep
    254     // the traced thing alive, but will write null to the WeakMember later
    255     // if the pointed-to object is dead. It's lying for this to be const,
    256     // but the overloading resolver prioritizes constness too high when
    257     // picking the correct overload, so all these trace methods have to have
    258     // the same constness on their argument to allow the type to decide.
    259     template<typename T>
    260     void trace(const WeakMember<T>& t)
    261     {
    262         // Check that we actually know the definition of T when tracing.
    263         COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing);
    264         registerWeakCell(const_cast<WeakMember<T>&>(t).cell());
    265     }
    266 
    267     template<typename T>
    268     void traceInCollection(T& t, ShouldWeakPointersBeMarkedStrongly strongify)
    269     {
    270         HashTraits<T>::traceInCollection(this, t, strongify);
    271     }
    272 
    273     // Fallback trace method for part objects to allow individual trace methods
    274     // to trace through a part object with visitor->trace(m_partObject). This
    275     // takes a const argument, because otherwise it will match too eagerly: a
    276     // non-const argument would match a non-const Vector<T>& argument better
    277     // than the specialization that takes const Vector<T>&. For a similar reason,
    278     // the other specializations take a const argument even though they are
    279     // usually used with non-const arguments, otherwise this function would match
    280     // too well.
    281     template<typename T>
    282     void trace(const T& t)
    283     {
    284         const_cast<T&>(t).trace(this);
    285     }
    286 
    287     // The following trace methods are for off-heap collections.
    288     template<typename T, size_t inlineCapacity>
    289     void trace(const Vector<T, inlineCapacity>& vector)
    290     {
    291         OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::DefaultAllocator> >::trace(this, vector);
    292     }
    293 
    294     template<typename T, typename U, typename V>
    295     void trace(const HashSet<T, U, V>& hashSet)
    296     {
    297         OffHeapCollectionTraceTrait<HashSet<T, U, V> >::trace(this, hashSet);
    298     }
    299 
    300     template<typename T, size_t inlineCapacity, typename U>
    301     void trace(const ListHashSet<T, inlineCapacity, U>& hashSet)
    302     {
    303         OffHeapCollectionTraceTrait<ListHashSet<T, inlineCapacity, U> >::trace(this, hashSet);
    304     }
    305 
    306     template<typename T, typename U>
    307     void trace(const LinkedHashSet<T, U>& hashSet)
    308     {
    309         OffHeapCollectionTraceTrait<LinkedHashSet<T, U> >::trace(this, hashSet);
    310     }
    311 
    312     template<typename T, size_t N>
    313     void trace(const Deque<T, N>& deque)
    314     {
    315         OffHeapCollectionTraceTrait<Deque<T, N> >::trace(this, deque);
    316     }
    317 
    318     template<typename T, typename U, typename V>
    319     void trace(const HashCountedSet<T, U, V>& set)
    320     {
    321         OffHeapCollectionTraceTrait<HashCountedSet<T, U, V> >::trace(this, set);
    322     }
    323 
    324     template<typename T, typename U, typename V, typename W, typename X>
    325     void trace(const HashMap<T, U, V, W, X, WTF::DefaultAllocator>& map)
    326     {
    327         OffHeapCollectionTraceTrait<HashMap<T, U, V, W, X, WTF::DefaultAllocator> >::trace(this, map);
    328     }
    329 
    330     // OwnPtrs that are traced are treated as part objects and the
    331     // trace method of the owned object is called.
    332     template<typename T>
    333     void trace(const OwnPtr<T>& t)
    334     {
    335         if (t)
    336             t->trace(this);
    337     }
    338 
    339     // This trace method is to trace a RefPtrWillBeMember when ENABLE(OILPAN)
    340     // is not enabled.
    341     // Remove this once we remove RefPtrWillBeMember.
    342     template<typename T>
    343     void trace(const RefPtr<T>&)
    344     {
    345 #if ENABLE(OILPAN)
    346         // RefPtrs should never be traced.
    347         ASSERT_NOT_REACHED();
    348 #endif
    349     }
    350 
    351 #if !ENABLE(OILPAN)
    352     // Similarly, this trace method is to trace a RawPtrWillBeMember
    353     // when ENABLE(OILPAN) is not enabled.
    354     // Remove this once we remove RawPtrWillBeMember.
    355     template<typename T>
    356     void trace(const RawPtr<T>&)
    357     {
    358     }
    359 #endif
    360 
    361     // This trace method is to trace a WeakPtrWillBeMember when ENABLE(OILPAN)
    362     // is not enabled.
    363     // Remove this once we remove WeakPtrWillBeMember.
    364     template<typename T>
    365     void trace(const WeakPtr<T>&)
    366     {
    367 #if ENABLE(OILPAN)
    368         // WeakPtrs should never be traced.
    369         ASSERT_NOT_REACHED();
    370 #endif
    371     }
    372 
    373     // This method marks an object and adds it to the set of objects
    374     // that should have their trace method called. Since not all
    375     // objects have vtables we have to have the callback as an
    376     // explicit argument, but we can use the templated one-argument
    377     // mark method above to automatically provide the callback
    378     // function.
    379     virtual void mark(const void*, TraceCallback) = 0;
    380     virtual void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<TraceCallback>(0)); }
    381 
    382     // Used to mark objects during conservative scanning.
    383     virtual void mark(HeapObjectHeader*, TraceCallback) = 0;
    384     virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0;
    385     virtual void markConservatively(HeapObjectHeader*) = 0;
    386     virtual void markConservatively(FinalizedHeapObjectHeader*) = 0;
    387 
    388     // If the object calls this during the regular trace callback, then the
    389     // WeakPointerCallback argument may be called later, when the strong roots
    390     // have all been found. The WeakPointerCallback will normally use isAlive
    391     // to find out whether some pointers are pointing to dying objects. When
    392     // the WeakPointerCallback is done the object must have purged all pointers
    393     // to objects where isAlive returned false. In the weak callback it is not
    394     // allowed to touch other objects (except using isAlive) or to allocate on
    395     // the GC heap. Note that even removing things from HeapHashSet or
    396     // HeapHashMap can cause an allocation if the backing store resizes, but
    397     // these collections know to remove WeakMember elements safely.
    398     //
    399     // The weak pointer callbacks are run on the thread that owns the
    400     // object and other threads are not stopped during the
    401     // callbacks. Since isAlive is used in the callback to determine
    402     // if objects pointed to are alive it is crucial that the object
    403     // pointed to belong to the same thread as the object receiving
    404     // the weak callback. Since other threads have been resumed the
    405     // mark bits are not valid for objects from other threads.
    406     virtual void registerWeakMembers(const void* object, WeakPointerCallback callback) { registerWeakMembers(object, object, callback); }
    407     virtual void registerWeakMembers(const void*, const void*, WeakPointerCallback) = 0;
    408 
    409     template<typename T, void (T::*method)(Visitor*)>
    410     void registerWeakMembers(const T* obj)
    411     {
    412         registerWeakMembers(obj, &TraceMethodDelegate<T, method>::trampoline);
    413     }
    414 
    415     // For simple cases where you just want to zero out a cell when the thing
    416     // it is pointing at is garbage, you can use this. This will register a
    417     // callback for each cell that needs to be zeroed, so if you have a lot of
    418     // weak cells in your object you should still consider using
    419     // registerWeakMembers above.
    420     //
    421     // In contrast to registerWeakMembers, the weak cell callbacks are
    422     // run on the thread performing garbage collection. Therefore, all
    423     // threads are stopped during weak cell callbacks.
    424     template<typename T>
    425     void registerWeakCell(T** cell)
    426     {
    427         registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>);
    428     }
    429 
    430     virtual bool isMarked(const void*) = 0;
    431 
    432     template<typename T> inline bool isAlive(T* obj)
    433     {
    434         return !!obj && ObjectAliveTrait<T>::isAlive(this, obj);
    435     }
    436     template<typename T> inline bool isAlive(const Member<T>& member)
    437     {
    438         return isAlive(member.get());
    439     }
    440     template<typename T> inline bool isAlive(RawPtr<T> ptr)
    441     {
    442         return isAlive(ptr.get());
    443     }
    444 
    445 #ifndef NDEBUG
    446     void checkGCInfo(const void*, const GCInfo*);
    447 #endif
    448 
    449     // Macro to declare methods needed for each typed heap.
    450 #define DECLARE_VISITOR_METHODS(Type)                                  \
    451     DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);)          \
    452     virtual void mark(const Type*, TraceCallback) = 0;                 \
    453     virtual bool isMarked(const Type*) = 0;
    454 
    455     FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS)
    456 #undef DECLARE_VISITOR_METHODS
    457 
    458 #if ENABLE(GC_TRACING)
    459     void setHostInfo(void* object, const String& name)
    460     {
    461         m_hostObject = object;
    462         m_hostName = name;
    463     }
    464 #endif
    465 
    466 protected:
    467     virtual void registerWeakCell(void**, WeakPointerCallback) = 0;
    468 #if ENABLE(GC_TRACING)
    469     void* m_hostObject;
    470     String m_hostName;
    471 #endif
    472 
    473 private:
    474     template<typename T>
    475     static void handleWeakCell(Visitor* self, void* obj)
    476     {
    477         T** cell = reinterpret_cast<T**>(obj);
    478         if (*cell && !self->isAlive(*cell))
    479             *cell = 0;
    480     }
    481 };
    482 
    483 template<typename T, typename HashFunctions, typename Traits>
    484 struct OffHeapCollectionTraceTrait<WTF::HashSet<T, HashFunctions, Traits, WTF::DefaultAllocator> > {
    485     typedef WTF::HashSet<T, HashFunctions, Traits, WTF::DefaultAllocator> HashSet;
    486 
    487     static void trace(Visitor* visitor, const HashSet& set)
    488     {
    489         if (set.isEmpty())
    490             return;
    491         if (WTF::ShouldBeTraced<Traits>::value) {
    492             HashSet& iterSet = const_cast<HashSet&>(set);
    493             for (typename HashSet::iterator it = iterSet.begin(), end = iterSet.end(); it != end; ++it) {
    494                 const T& t = *it;
    495                 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WeakPointersActWeak, T, Traits>::trace(visitor, const_cast<T&>(t));
    496             }
    497         }
    498         COMPILE_ASSERT(Traits::weakHandlingFlag == WTF::NoWeakHandlingInCollections, WeakOffHeapCollectionsConsideredDangerous0);
    499     }
    500 };
    501 
    502 template<typename T, size_t inlineCapacity, typename HashFunctions>
    503 struct OffHeapCollectionTraceTrait<ListHashSet<T, inlineCapacity, HashFunctions> > {
    504     typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet;
    505 
    506     static void trace(Visitor* visitor, const ListHashSet& set)
    507     {
    508         if (set.isEmpty())
    509             return;
    510         ListHashSet& iterSet = const_cast<ListHashSet&>(set);
    511         for (typename ListHashSet::iterator it = iterSet.begin(), end = iterSet.end(); it != end; ++it)
    512             visitor->trace(*it);
    513     }
    514 };
    515 
    516 template<typename T, typename HashFunctions>
    517 struct OffHeapCollectionTraceTrait<WTF::LinkedHashSet<T, HashFunctions> > {
    518     typedef WTF::LinkedHashSet<T, HashFunctions> LinkedHashSet;
    519 
    520     static void trace(Visitor* visitor, const LinkedHashSet& set)
    521     {
    522         if (set.isEmpty())
    523             return;
    524         LinkedHashSet& iterSet = const_cast<LinkedHashSet&>(set);
    525         for (typename LinkedHashSet::iterator it = iterSet.begin(), end = iterSet.end(); it != end; ++it)
    526             visitor->trace(*it);
    527     }
    528 };
    529 
    530 template<typename Key, typename Value, typename HashFunctions, typename KeyTraits, typename ValueTraits>
    531 struct OffHeapCollectionTraceTrait<WTF::HashMap<Key, Value, HashFunctions, KeyTraits, ValueTraits, WTF::DefaultAllocator> > {
    532     typedef WTF::HashMap<Key, Value, HashFunctions, KeyTraits, ValueTraits, WTF::DefaultAllocator> HashMap;
    533 
    534     static void trace(Visitor* visitor, const HashMap& map)
    535     {
    536         if (map.isEmpty())
    537             return;
    538         if (WTF::ShouldBeTraced<KeyTraits>::value || WTF::ShouldBeTraced<ValueTraits>::value) {
    539             HashMap& iterMap = const_cast<HashMap&>(map);
    540             for (typename HashMap::iterator it = iterMap.begin(), end = iterMap.end(); it != end; ++it) {
    541                 CollectionBackingTraceTrait<WTF::ShouldBeTraced<KeyTraits>::value, KeyTraits::weakHandlingFlag, WeakPointersActWeak, typename HashMap::KeyType, KeyTraits>::trace(visitor, it->key);
    542                 CollectionBackingTraceTrait<WTF::ShouldBeTraced<ValueTraits>::value, ValueTraits::weakHandlingFlag, WeakPointersActWeak, typename HashMap::MappedType, ValueTraits>::trace(visitor, it->value);
    543             }
    544         }
    545         COMPILE_ASSERT(KeyTraits::weakHandlingFlag == WTF::NoWeakHandlingInCollections, WeakOffHeapCollectionsConsideredDangerous1);
    546         COMPILE_ASSERT(ValueTraits::weakHandlingFlag == WTF::NoWeakHandlingInCollections, WeakOffHeapCollectionsConsideredDangerous2);
    547     }
    548 };
    549 
    550 // We trace vectors by using the trace trait on each element, which means you
    551 // can have vectors of general objects (not just pointers to objects) that can
    552 // be traced.
    553 template<typename T, size_t N>
    554 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > {
    555     typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector;
    556 
    557     static void trace(Visitor* visitor, const Vector& vector)
    558     {
    559         if (vector.isEmpty())
    560             return;
    561         for (typename Vector::const_iterator it = vector.begin(), end = vector.end(); it != end; ++it)
    562             TraceTrait<T>::trace(visitor, const_cast<T*>(it));
    563     }
    564 };
    565 
    566 template<typename T, size_t N>
    567 struct OffHeapCollectionTraceTrait<WTF::Deque<T, N> > {
    568     typedef WTF::Deque<T, N> Deque;
    569 
    570     static void trace(Visitor* visitor, const Deque& deque)
    571     {
    572         if (deque.isEmpty())
    573             return;
    574         for (typename Deque::const_iterator it = deque.begin(), end = deque.end(); it != end; ++it)
    575             TraceTrait<T>::trace(visitor, const_cast<T*>(&(*it)));
    576     }
    577 };
    578 
    579 template<typename T, typename U, typename V>
    580 struct OffHeapCollectionTraceTrait<WTF::HashCountedSet<T, U, V> > {
    581     typedef WTF::HashCountedSet<T, U, V> Set;
    582 
    583     static void trace(Visitor* visitor, const Set& set)
    584     {
    585         if (set.isEmpty())
    586             return;
    587         for (typename Set::const_iterator it = set.begin(), end = set.end(); it != end; ++it)
    588             TraceTrait<T>::trace(visitor, const_cast<T*>(&(it->key)));
    589     }
    590 };
    591 
    592 template<typename T, typename Traits = WTF::VectorTraits<T> >
    593 class HeapVectorBacking;
    594 
    595 template<typename Table>
    596 class HeapHashTableBacking {
    597 public:
    598     static void finalize(void* pointer);
    599 };
    600 
    601 template<typename T>
    602 class DefaultTraceTrait<T, false> {
    603 public:
    604     static void mark(Visitor* visitor, const T* t)
    605     {
    606         // Default mark method of the trait just calls the two-argument mark
    607         // method on the visitor. The second argument is the static trace method
    608         // of the trait, which by default calls the instance method
    609         // trace(Visitor*) on the object.
    610         visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace);
    611     }
    612 
    613 #ifndef NDEBUG
    614     static void checkGCInfo(Visitor* visitor, const T* t)
    615     {
    616         visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get());
    617     }
    618 #endif
    619 };
    620 
    621 template<typename T>
    622 class DefaultTraceTrait<T, true> {
    623 public:
    624     static void mark(Visitor* visitor, const T* self)
    625     {
    626         if (self)
    627             self->adjustAndMark(visitor);
    628     }
    629 
    630 #ifndef NDEBUG
    631     static void checkGCInfo(Visitor*, const T*) { }
    632 #endif
    633 };
    634 
    635 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAliveTrait;
    636 
    637 template<typename T>
    638 class DefaultObjectAliveTrait<T, false> {
    639 public:
    640     static bool isAlive(Visitor* visitor, T* obj)
    641     {
    642         return visitor->isMarked(obj);
    643     }
    644 };
    645 
    646 template<typename T>
    647 class DefaultObjectAliveTrait<T, true> {
    648 public:
    649     static bool isAlive(Visitor* visitor, T* obj)
    650     {
    651         return obj->isAlive(visitor);
    652     }
    653 };
    654 
    655 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T* obj)
    656 {
    657     return DefaultObjectAliveTrait<T>::isAlive(visitor, obj);
    658 }
    659 
    660 // The GarbageCollectedMixin interface and helper macro
    661 // USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define
    662 // TraceTrait/ObjectAliveTrait on non-leftmost deriving classes
    663 // which need to be garbage collected.
    664 //
    665 // Consider the following case:
    666 // class B {};
    667 // class A : public GarbageCollected, public B {};
    668 //
    669 // We can't correctly handle "Member<B> p = &a" as we can't compute addr of
    670 // object header statically. This can be solved by using GarbageCollectedMixin:
    671 // class B : public GarbageCollectedMixin {};
    672 // class A : public GarbageCollected, public B {
    673 //   USING_GARBAGE_COLLECTED_MIXIN(A)
    674 // };
    675 //
    676 // With the helper, as long as we are using Member<B>, TypeTrait<B> will
    677 // dispatch adjustAndMark dynamically to find collect addr of the object header.
    678 // Note that this is only enabled for Member<B>. For Member<A> which we can
    679 // compute the object header addr statically, this dynamic dispatch is not used.
    680 
    681 class GarbageCollectedMixin {
    682 public:
    683     virtual void adjustAndMark(Visitor*) const = 0;
    684     virtual bool isAlive(Visitor*) const = 0;
    685 };
    686 
    687 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
    688 public: \
    689     virtual void adjustAndMark(WebCore::Visitor* visitor) const OVERRIDE    \
    690     { \
    691         typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, WebCore::GarbageCollected> IsSubclassOfGarbageCollected; \
    692         COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollectedObjectsCanHaveGarbageCollectedMixins); \
    693         visitor->mark(static_cast<const TYPE*>(this), &WebCore::TraceTrait<TYPE>::trace); \
    694     } \
    695     virtual bool isAlive(WebCore::Visitor* visitor) const OVERRIDE  \
    696     { \
    697         return visitor->isAlive(this); \
    698     } \
    699 private:
    700 
    701 #if ENABLE(OILPAN)
    702 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXIN(TYPE)
    703 #else
    704 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE)
    705 #endif
    706 
    707 #if ENABLE(GC_TRACING)
    708 template<typename T>
    709 struct TypenameStringTrait {
    710     static const String& get()
    711     {
    712         DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFunctionName(WTF::extractNameFunction<T>())));
    713         return typenameString;
    714     }
    715 };
    716 #endif
    717 
    718 template<typename T>
    719 struct GCInfoAtBase {
    720     static const GCInfo* get()
    721     {
    722         static const GCInfo gcInfo = {
    723             TraceTrait<T>::trace,
    724             FinalizerTrait<T>::finalize,
    725             FinalizerTrait<T>::nonTrivialFinalizer,
    726             WTF::IsPolymorphic<T>::value,
    727 #if ENABLE(GC_TRACING)
    728             TypenameStringTrait<T>::get()
    729 #endif
    730         };
    731         return &gcInfo;
    732     }
    733 };
    734 
    735 template<typename T> class GarbageCollected;
    736 template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, GarbageCollected>::value> struct GetGarbageCollectedBase;
    737 
    738 template<typename T>
    739 struct GetGarbageCollectedBase<T, true> {
    740     typedef typename T::GarbageCollectedBase type;
    741 };
    742 
    743 template<typename T>
    744 struct GetGarbageCollectedBase<T, false> {
    745     typedef T type;
    746 };
    747 
    748 template<typename T>
    749 struct GCInfoTrait {
    750     static const GCInfo* get()
    751     {
    752         return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get();
    753     }
    754 };
    755 
    756 }
    757 
    758 #endif
    759