2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
34 #include "heap/HeapExport.h"
35 #include "heap/ThreadState.h"
36 #include "wtf/Assertions.h"
37 #include "wtf/Deque.h"
38 #include "wtf/Forward.h"
39 #include "wtf/HashMap.h"
40 #include "wtf/HashSet.h"
41 #include "wtf/HashTraits.h"
42 #include "wtf/ListHashSet.h"
43 #include "wtf/OwnPtr.h"
46 #define DEBUG_ONLY(x) x
53 class FinalizedHeapObjectHeader;
54 template<typename T> class GarbageCollectedFinalized;
55 class HeapObjectHeader;
56 template<typename T> class Member;
57 template<typename T> class WeakMember;
60 template<bool needsTracing, bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits> struct CollectionBackingTraceTrait;
62 typedef void (*FinalizationCallback)(void*);
63 typedef void (*VisitorCallback)(Visitor*, void* self);
64 typedef VisitorCallback TraceCallback;
65 typedef VisitorCallback WeakPointerCallback;
67 // The TraceMethodDelegate is used to convert a trace method for type T to a TraceCallback.
68 // This allows us to pass a type's trace method as a parameter to the PersistentNode
69 // constructor. The PersistentNode constructor needs the specific trace method due an issue
70 // with the Windows compiler which instantiates even unused variables. This causes problems
71 // in header files where we have only forward declarations of classes.
72 template<typename T, void (T::*method)(Visitor*)>
73 struct TraceMethodDelegate {
74 static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*>(self)->*method)(visitor); }
77 // GCInfo contains meta-data associated with objects allocated in the
78 // Blink heap. This meta-data consists of a function pointer used to
79 // trace the pointers in the object during garbage collection, an
80 // indication of whether or not the object needs a finalization
81 // callback, and a function pointer used to finalize the object when
82 // the garbage collector determines that the object is no longer
83 // reachable. There is a GCInfo struct for each class that directly
84 // inherits from GarbageCollected or GarbageCollectedFinalized.
86 bool hasFinalizer() const { return m_nonTrivialFinalizer; }
87 const char* m_typeMarker;
88 TraceCallback m_trace;
89 FinalizationCallback m_finalize;
90 bool m_nonTrivialFinalizer;
93 // Template struct to detect whether type T inherits from
94 // GarbageCollectedFinalized.
96 struct IsGarbageCollectedFinalized {
97 typedef char TrueType;
101 template<typename U> static TrueType has(GarbageCollectedFinalized<U>*);
102 static FalseType has(...);
103 static bool const value = sizeof(has(static_cast<T*>(0))) == sizeof(TrueType);
106 // The FinalizerTraitImpl specifies how to finalize objects. Object
107 // that inherit from GarbageCollectedFinalized are finalized by
108 // calling their 'finalize' method which by default will call the
109 // destructor on the object.
110 template<typename T, bool isGarbageCollectedFinalized>
111 struct FinalizerTraitImpl;
114 struct FinalizerTraitImpl<T, true> {
115 static void finalize(void* obj) { static_cast<T*>(obj)->finalize(); };
119 struct FinalizerTraitImpl<T, false> {
120 static void finalize(void* obj) { };
123 // The FinalizerTrait is used to determine if a type requires
124 // finalization and what finalization means.
126 // By default classes that inherit from GarbageCollectedFinalized need
127 // finalization and finalization means calling the 'finalize' method
128 // of the object. The FinalizerTrait can be specialized if the default
129 // behavior is not desired.
131 struct FinalizerTrait {
132 static const bool nonTrivialFinalizer = IsGarbageCollectedFinalized<T>::value;
133 static void finalize(void* obj) { FinalizerTraitImpl<T, nonTrivialFinalizer>::finalize(obj); }
136 // Macros to declare and define GCInfo structures for objects
137 // allocated in the Blink garbage-collected heap.
138 #define DECLARE_GC_INFO \
140 static const GCInfo s_gcInfo; \
141 template<typename Any> friend struct FinalizerTrait; \
144 #define DEFINE_GC_INFO(Type) \
145 const GCInfo Type::s_gcInfo = { \
147 TraceTrait<Type>::trace, \
148 FinalizerTrait<Type>::finalize, \
149 FinalizerTrait<Type>::nonTrivialFinalizer, \
152 // Trait to get the GCInfo structure for types that have their
153 // instances allocated in the Blink garbage-collected heap.
156 static const GCInfo* get()
163 const char* getTypeMarker()
165 return GCInfoTrait<T>::get()->m_typeMarker;
168 // The TraceTrait is used to specify how to mark an object pointer and
169 // how to trace all of the pointers in the object.
171 // By default, the 'trace' method implemented on an object itself is
172 // used to trace the pointers to other heap objects inside the object.
174 // However, the TraceTrait can be specialized to use a different
175 // implementation. A common case where a TraceTrait specialization is
176 // needed is when multiple inheritance leads to pointers that are not
177 // to the start of the object in the Blink garbage-collected heap. In
178 // that case the pointer has to be adjusted before marking.
182 // Default implementation of TraceTrait<T>::trace just statically
183 // dispatches to the trace method of the class T.
184 static void trace(Visitor* visitor, void* self)
186 static_cast<T*>(self)->trace(visitor);
189 static void mark(Visitor*, const T*);
192 static void checkTypeMarker(Visitor*, const T*);
196 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
199 struct ObjectAliveTrait {
200 static bool isAlive(Visitor*, T);
204 struct ObjectAliveTrait<Member<T> > {
205 static bool isAlive(Visitor*, const Member<T>&);
208 // Visitor is used to traverse the Blink object graph. Used for the
209 // marking phase of the mark-sweep garbage collector.
211 // Pointers are marked and pushed on the marking stack by calling the
212 // |mark| method with the pointer as an argument.
214 // Pointers within objects are traced by calling the |trace| methods
215 // with the object as an argument. Tracing objects will mark all of the
216 // contained pointers and push them on the marking stack.
217 class HEAP_EXPORT Visitor {
219 // One-argument templated mark method. This uses the static type of
220 // the argument to get the TraceTrait. By default, the mark method
221 // of the TraceTrait just calls the virtual two-argument mark method on this
222 // visitor, where the second argument is the static trace method of the trait.
229 TraceTrait<T>::checkTypeMarker(this, t);
231 TraceTrait<T>::mark(this, t);
234 // Member version of the one-argument templated trace method.
236 void trace(const Member<T>& t)
241 // WeakMember version of the templated trace method. It doesn't keep
242 // the traced thing alive, but will write null to the WeakMember later
243 // if the pointed-to object is dead.
245 void trace(const WeakMember<T>& t)
247 registerWeakCell(t.cell());
250 // Fallback trace method for part objects to allow individual
251 // trace methods to trace through a part object with
252 // visitor->trace(m_partObject).
254 void trace(const T& t)
256 const_cast<T&>(t).trace(this);
259 // OwnPtrs that are traced are treated as part objects and the
260 // trace method of the owned object is called.
262 void trace(const OwnPtr<T>& t)
267 // This method marks an object and adds it to the set of objects
268 // that should have their trace method called. Since not all
269 // objects have vtables we have to have the callback as an
270 // explicit argument, but we can use the templated one-argument
271 // mark method above to automatically provide the callback
273 virtual void mark(const void*, TraceCallback) = 0;
275 // Used to mark objects during conservative scanning.
276 virtual void mark(HeapObjectHeader*, TraceCallback) = 0;
277 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0;
279 // If the object calls this during the regular trace callback, then the
280 // WeakPointerCallback argument may be called later, when the strong roots
281 // have all been found. The WeakPointerCallback will normally use isAlive
282 // to find out whether some pointers are pointing to dying objects. When
283 // the WeakPointerCallback is done the object must have purged all pointers
284 // to objects where isAlive returned false. In the weak callback it is not
285 // allowed to touch other objects (except using isAlive) or to allocate on
286 // the GC heap. Note that even removing things from HeapHashSet or
287 // HeapHashMap can cause an allocation if the backing store resizes, but
288 // these collections know to remove WeakMember elements safely.
289 virtual void registerWeakMembers(const void*, WeakPointerCallback) = 0;
291 template<typename T, void (T::*method)(Visitor*)>
292 void registerWeakMembers(const T* obj)
294 registerWeakMembers(obj, &TraceMethodDelegate<T, method>::trampoline);
297 // For simple cases where you just want to zero out a cell when the thing
298 // it is pointing at is garbage, you can use this. This will register a
299 // callback for each cell that needs to be zeroed, so if you have a lot of
300 // weak cells in your object you should still consider using
301 // registerWeakMembers above.
303 void registerWeakCell(T** cell)
305 registerWeakMembers(reinterpret_cast<const void*>(cell), &handleWeakCell<T>);
308 virtual bool isMarked(const void*) = 0;
310 template<typename T> inline bool isAlive(T obj) { return ObjectAliveTrait<T>::isAlive(this, obj); }
311 template<typename T> inline bool isAlive(const Member<T>& member)
313 return isAlive(member.get());
317 void checkTypeMarker(const void*, const char* marker);
320 // Macro to declare methods needed for each typed heap.
321 #define DECLARE_VISITOR_METHODS(Type) \
322 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \
323 virtual void mark(const Type*, TraceCallback) = 0; \
324 virtual bool isMarked(const Type*) = 0;
326 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS)
327 #undef DECLARE_VISITOR_METHODS
331 static void handleWeakCell(Visitor* self, void* obj)
333 T** cell = reinterpret_cast<T**>(obj);
334 if (*cell && !self->isAlive(*cell))
339 template<typename T, typename Traits = WTF::VectorTraits<T> >
340 class HeapVectorBacking;
341 template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
342 class HeapHashTableBacking;
344 inline void doNothingTrace(Visitor*, void*) { }
346 // Non-class types like char don't have an trace method, so we provide a more
347 // specialized template instantiation here that will be selected in preference
348 // to the default. Most of them do nothing, since the type in question cannot
349 // point to other heap allocated objects.
350 #define ITERATE_DO_NOTHING_TYPES(f) \
354 #define DECLARE_DO_NOTHING_TRAIT(type) \
356 class TraceTrait<type> { \
358 static void checkTypeMarker(Visitor*, const void*) { } \
359 static void mark(Visitor* v, const type* p) { \
360 v->mark(p, reinterpret_cast<TraceCallback>(0)); \
364 struct FinalizerTrait<type> { \
365 static void finalize(void*) { } \
366 static const bool nonTrivialFinalizer = false; \
369 struct HEAP_EXPORT GCInfoTrait<type> { \
370 static const GCInfo* get() \
374 static const GCInfo info; \
377 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT)
379 #undef DECLARE_DO_NOTHING_TRAIT
382 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const T* t)
384 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>());
388 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t)
390 // Default mark method of the trait just calls the two-argument mark
391 // method on the visitor. The second argument is the static trace method
392 // of the trait, which by default calls the instance method
393 // trace(Visitor*) on the object.
394 visitor->mark(const_cast<T*>(t), &trace);
397 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj)
399 return visitor->isMarked(obj);
401 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor, const Member<T>& obj)
403 return visitor->isMarked(obj.get());