| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #include "wtf/Forward.h" | 38 #include "wtf/Forward.h" |
| 39 #include "wtf/HashTraits.h" | 39 #include "wtf/HashTraits.h" |
| 40 #include "wtf/TypeTraits.h" | 40 #include "wtf/TypeTraits.h" |
| 41 #include <memory> | 41 #include <memory> |
| 42 | 42 |
| 43 namespace blink { | 43 namespace blink { |
| 44 | 44 |
| 45 template <typename T> | 45 template <typename T> |
| 46 class GarbageCollected; | 46 class GarbageCollected; |
| 47 class HeapObjectHeader; | 47 class HeapObjectHeader; |
| 48 class InlinedGlobalMarkingVisitor; | |
| 49 template <typename T> | 48 template <typename T> |
| 50 class TraceTrait; | 49 class TraceTrait; |
| 51 class ThreadState; | 50 class ThreadState; |
| 52 class Visitor; | 51 class Visitor; |
| 53 template <typename T> | 52 template <typename T> |
| 54 class SameThreadCheckedMember; | 53 class SameThreadCheckedMember; |
| 55 template <typename T> | 54 template <typename T> |
| 56 class TraceWrapperMember; | 55 class TraceWrapperMember; |
| 57 | 56 |
| 58 // The TraceMethodDelegate is used to convert a trace method for type T to a | 57 // The TraceMethodDelegate is used to convert a trace method for type T to a |
| 59 // TraceCallback. This allows us to pass a type's trace method as a parameter | 58 // TraceCallback. This allows us to pass a type's trace method as a parameter |
| 60 // to the PersistentNode constructor. The PersistentNode constructor needs the | 59 // to the PersistentNode constructor. The PersistentNode constructor needs the |
| 61 // specific trace method due an issue with the Windows compiler which | 60 // specific trace method due an issue with the Windows compiler which |
| 62 // instantiates even unused variables. This causes problems | 61 // instantiates even unused variables. This causes problems |
| 63 // in header files where we have only forward declarations of classes. | 62 // in header files where we have only forward declarations of classes. |
| 64 template <typename T, void (T::*method)(Visitor*)> | 63 template <typename T, void (T::*method)(Visitor*)> |
| 65 struct TraceMethodDelegate { | 64 struct TraceMethodDelegate { |
| 66 STATIC_ONLY(TraceMethodDelegate); | 65 STATIC_ONLY(TraceMethodDelegate); |
| 67 static void trampoline(Visitor* visitor, void* self) { | 66 static void trampoline(Visitor* visitor, void* self) { |
| 68 (reinterpret_cast<T*>(self)->*method)(visitor); | 67 (reinterpret_cast<T*>(self)->*method)(visitor); |
| 69 } | 68 } |
| 70 }; | 69 }; |
| 71 | 70 |
| 72 #define DECLARE_TRACE_IMPL(maybevirtual) \ | 71 #define DECLARE_TRACE_IMPL(maybevirtual) \ |
| 73 public: \ | 72 public: \ |
| 74 maybevirtual void trace(blink::Visitor*); \ | 73 maybevirtual void trace(blink::Visitor*); |
| 75 maybevirtual void trace(blink::InlinedGlobalMarkingVisitor); \ | |
| 76 \ | |
| 77 private: \ | |
| 78 template <typename VisitorDispatcher> \ | |
| 79 void traceImpl(VisitorDispatcher); \ | |
| 80 \ | |
| 81 public: | |
| 82 #define DEFINE_TRACE(T) \ | |
| 83 void T::trace(blink::Visitor* visitor) { traceImpl(visitor); } \ | |
| 84 void T::trace(blink::InlinedGlobalMarkingVisitor visitor) { \ | |
| 85 traceImpl(visitor); \ | |
| 86 } \ | |
| 87 template <typename VisitorDispatcher> \ | |
| 88 ALWAYS_INLINE void T::traceImpl(VisitorDispatcher visitor) | |
| 89 | 74 |
| 90 #define DEFINE_INLINE_TRACE_IMPL(maybevirtual) \ | 75 #define DECLARE_TRACE_AFTER_DISPATCH() \ |
| 91 maybevirtual void trace(blink::Visitor* visitor) { traceImpl(visitor); } \ | 76 public: \ |
| 92 maybevirtual void trace(blink::InlinedGlobalMarkingVisitor visitor) { \ | 77 void traceAfterDispatch(blink::Visitor*); |
| 93 traceImpl(visitor); \ | |
| 94 } \ | |
| 95 template <typename VisitorDispatcher> \ | |
| 96 inline void traceImpl(VisitorDispatcher visitor) | |
| 97 | 78 |
| 98 #define DECLARE_TRACE_AFTER_DISPATCH() \ | 79 #define DEFINE_TRACE(T) void T::trace(blink::Visitor* visitor) |
| 99 public: \ | |
| 100 void traceAfterDispatch(blink::Visitor*); \ | |
| 101 void traceAfterDispatch(blink::InlinedGlobalMarkingVisitor); \ | |
| 102 \ | |
| 103 private: \ | |
| 104 template <typename VisitorDispatcher> \ | |
| 105 void traceAfterDispatchImpl(VisitorDispatcher); \ | |
| 106 \ | |
| 107 public: | |
| 108 | 80 |
| 109 #define DEFINE_TRACE_AFTER_DISPATCH(T) \ | 81 #define DEFINE_INLINE_TRACE_IMPL(maybevirtual) \ |
| 110 void T::traceAfterDispatch(blink::Visitor* visitor) { \ | 82 maybevirtual void trace(blink::Visitor* visitor) |
| 111 traceAfterDispatchImpl(visitor); \ | |
| 112 } \ | |
| 113 void T::traceAfterDispatch(blink::InlinedGlobalMarkingVisitor visitor) { \ | |
| 114 traceAfterDispatchImpl(visitor); \ | |
| 115 } \ | |
| 116 template <typename VisitorDispatcher> \ | |
| 117 ALWAYS_INLINE void T::traceAfterDispatchImpl(VisitorDispatcher visitor) | |
| 118 | 83 |
| 119 #define DEFINE_INLINE_TRACE_AFTER_DISPATCH() \ | 84 #define DEFINE_TRACE_AFTER_DISPATCH(T) \ |
| 120 void traceAfterDispatch(blink::Visitor* visitor) { \ | 85 void T::traceAfterDispatch(blink::Visitor* visitor) |
| 121 traceAfterDispatchImpl(visitor); \ | 86 |
| 122 } \ | 87 #define DEFINE_INLINE_TRACE_AFTER_DISPATCH() \ |
| 123 void traceAfterDispatch(blink::InlinedGlobalMarkingVisitor visitor) { \ | 88 void traceAfterDispatch(blink::Visitor* visitor) |
| 124 traceAfterDispatchImpl(visitor); \ | |
| 125 } \ | |
| 126 template <typename VisitorDispatcher> \ | |
| 127 inline void traceAfterDispatchImpl(VisitorDispatcher visitor) | |
| 128 | 89 |
| 129 #define EMPTY_MACRO_ARGUMENT | 90 #define EMPTY_MACRO_ARGUMENT |
| 130 | 91 |
| 131 #define DECLARE_TRACE() DECLARE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) | 92 #define DECLARE_TRACE() DECLARE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) |
| 132 #define DECLARE_VIRTUAL_TRACE() DECLARE_TRACE_IMPL(virtual) | 93 #define DECLARE_VIRTUAL_TRACE() DECLARE_TRACE_IMPL(virtual) |
| 133 #define DEFINE_INLINE_TRACE() DEFINE_INLINE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) | 94 #define DEFINE_INLINE_TRACE() DEFINE_INLINE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) |
| 134 #define DEFINE_INLINE_VIRTUAL_TRACE() DEFINE_INLINE_TRACE_IMPL(virtual) | 95 #define DEFINE_INLINE_VIRTUAL_TRACE() DEFINE_INLINE_TRACE_IMPL(virtual) |
| 135 | 96 |
| 136 enum class VisitorMarkingMode { | 97 enum class VisitorMarkingMode { |
| 137 // This is a default visitor. This is used for GCType=GCWithSweep | 98 // This is a default visitor. This is used for GCType=GCWithSweep |
| (...skipping 10 matching lines...) Expand all Loading... |
| 148 WeakProcessing, | 109 WeakProcessing, |
| 149 // Perform global marking along with preparing for additional sweep | 110 // Perform global marking along with preparing for additional sweep |
| 150 // compaction of heap arenas afterwards. Compared to the GlobalMarking | 111 // compaction of heap arenas afterwards. Compared to the GlobalMarking |
| 151 // visitor, this visitor will also register references to objects | 112 // visitor, this visitor will also register references to objects |
| 152 // that might be moved during arena compaction -- the compaction | 113 // that might be moved during arena compaction -- the compaction |
| 153 // pass will then fix up those references when the object move goes | 114 // pass will then fix up those references when the object move goes |
| 154 // ahead. | 115 // ahead. |
| 155 GlobalMarkingWithCompaction, | 116 GlobalMarkingWithCompaction, |
| 156 }; | 117 }; |
| 157 | 118 |
| 158 // VisitorHelper contains common implementation of Visitor helper methods. | 119 // Visitor is used to traverse the Blink object graph. Used for the |
| 120 // marking phase of the mark-sweep garbage collector. |
| 159 // | 121 // |
| 160 // VisitorHelper avoids virtual methods by using CRTP. | 122 // Pointers are marked and pushed on the marking stack by calling the |
| 161 // c.f. http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern | 123 // |mark| method with the pointer as an argument. |
| 162 template <typename Derived> | 124 // |
| 163 class VisitorHelper { | 125 // Pointers within objects are traced by calling the |trace| methods |
| 126 // with the object as an argument. Tracing objects will mark all of the |
| 127 // contained pointers and push them on the marking stack. |
| 128 class PLATFORM_EXPORT Visitor { |
| 164 public: | 129 public: |
| 165 VisitorHelper(ThreadState* state, VisitorMarkingMode markingMode) | 130 static std::unique_ptr<Visitor> create(ThreadState*, VisitorMarkingMode); |
| 166 : m_state(state), m_markingMode(markingMode) {} | 131 |
| 132 Visitor(ThreadState*, VisitorMarkingMode); |
| 133 virtual ~Visitor(); |
| 167 | 134 |
| 168 // One-argument templated mark method. This uses the static type of | 135 // One-argument templated mark method. This uses the static type of |
| 169 // the argument to get the TraceTrait. By default, the mark method | 136 // the argument to get the TraceTrait. By default, the mark method |
| 170 // of the TraceTrait just calls the virtual two-argument mark method on this | 137 // of the TraceTrait just calls the virtual two-argument mark method on this |
| 171 // visitor, where the second argument is the static trace method of the trait. | 138 // visitor, where the second argument is the static trace method of the trait. |
| 172 template <typename T> | 139 template <typename T> |
| 173 void mark(T* t) { | 140 void mark(T* t) { |
| 174 static_assert(sizeof(T), "T must be fully defined"); | 141 static_assert(sizeof(T), "T must be fully defined"); |
| 175 static_assert(IsGarbageCollectedType<T>::value, | 142 static_assert(IsGarbageCollectedType<T>::value, |
| 176 "T needs to be a garbage collected object"); | 143 "T needs to be a garbage collected object"); |
| 177 if (!t) | 144 if (!t) |
| 178 return; | 145 return; |
| 179 TraceTrait<T>::mark(Derived::fromHelper(this), t); | 146 TraceTrait<T>::mark(this, t); |
| 180 } | 147 } |
| 181 | 148 |
| 182 // Member version of the one-argument templated trace method. | 149 // Member version of the one-argument templated trace method. |
| 183 template <typename T> | 150 template <typename T> |
| 184 void trace(const Member<T>& t) { | 151 void trace(const Member<T>& t) { |
| 185 mark(t.get()); | 152 mark(t.get()); |
| 186 } | 153 } |
| 187 | 154 |
| 188 template <typename T> | 155 template <typename T> |
| 189 void trace(const TraceWrapperMember<T>& t) { | 156 void trace(const TraceWrapperMember<T>& t) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 216 void trace(const WeakMember<T>& t) { | 183 void trace(const WeakMember<T>& t) { |
| 217 static_assert(sizeof(T), "T must be fully defined"); | 184 static_assert(sizeof(T), "T must be fully defined"); |
| 218 static_assert(IsGarbageCollectedType<T>::value, | 185 static_assert(IsGarbageCollectedType<T>::value, |
| 219 "T needs to be a garbage collected object"); | 186 "T needs to be a garbage collected object"); |
| 220 registerWeakCell(const_cast<WeakMember<T>&>(t).cell()); | 187 registerWeakCell(const_cast<WeakMember<T>&>(t).cell()); |
| 221 } | 188 } |
| 222 | 189 |
| 223 template <typename T> | 190 template <typename T> |
| 224 void traceInCollection(T& t, | 191 void traceInCollection(T& t, |
| 225 WTF::ShouldWeakPointersBeMarkedStrongly strongify) { | 192 WTF::ShouldWeakPointersBeMarkedStrongly strongify) { |
| 226 HashTraits<T>::traceInCollection(Derived::fromHelper(this), t, strongify); | 193 HashTraits<T>::traceInCollection(this, t, strongify); |
| 227 } | 194 } |
| 228 | 195 |
| 229 // Fallback trace method for part objects to allow individual trace methods | 196 // Fallback trace method for part objects to allow individual trace methods |
| 230 // to trace through a part object with visitor->trace(m_partObject). This | 197 // to trace through a part object with visitor->trace(m_partObject). This |
| 231 // takes a const argument, because otherwise it will match too eagerly: a | 198 // takes a const argument, because otherwise it will match too eagerly: a |
| 232 // non-const argument would match a non-const Vector<T>& argument better | 199 // non-const argument would match a non-const Vector<T>& argument better |
| 233 // than the specialization that takes const Vector<T>&. For a similar reason, | 200 // than the specialization that takes const Vector<T>&. For a similar reason, |
| 234 // the other specializations take a const argument even though they are | 201 // the other specializations take a const argument even though they are |
| 235 // usually used with non-const arguments, otherwise this function would match | 202 // usually used with non-const arguments, otherwise this function would match |
| 236 // too well. | 203 // too well. |
| 237 template <typename T> | 204 template <typename T> |
| 238 void trace(const T& t) { | 205 void trace(const T& t) { |
| 239 static_assert(sizeof(T), "T must be fully defined"); | 206 static_assert(sizeof(T), "T must be fully defined"); |
| 240 if (std::is_polymorphic<T>::value) { | 207 if (std::is_polymorphic<T>::value) { |
| 241 intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t); | 208 intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t); |
| 242 if (!vtable) | 209 if (!vtable) |
| 243 return; | 210 return; |
| 244 } | 211 } |
| 245 TraceTrait<T>::trace(Derived::fromHelper(this), &const_cast<T&>(t)); | 212 TraceTrait<T>::trace(this, &const_cast<T&>(t)); |
| 246 } | |
| 247 | |
| 248 void markNoTracing(const void* pointer) { | |
| 249 Derived::fromHelper(this)->mark(pointer, | |
| 250 reinterpret_cast<TraceCallback>(0)); | |
| 251 } | |
| 252 void markHeaderNoTracing(HeapObjectHeader* header) { | |
| 253 Derived::fromHelper(this)->markHeader(header, | |
| 254 reinterpret_cast<TraceCallback>(0)); | |
| 255 } | 213 } |
| 256 | 214 |
| 257 // For simple cases where you just want to zero out a cell when the thing | 215 // For simple cases where you just want to zero out a cell when the thing |
| 258 // it is pointing at is garbage, you can use this. This will register a | 216 // it is pointing at is garbage, you can use this. This will register a |
| 259 // callback for each cell that needs to be zeroed, so if you have a lot of | 217 // callback for each cell that needs to be zeroed, so if you have a lot of |
| 260 // weak cells in your object you should still consider using | 218 // weak cells in your object you should still consider using |
| 261 // registerWeakMembers above. | 219 // registerWeakMembers above. |
| 262 // | 220 // |
| 263 // In contrast to registerWeakMembers, the weak cell callbacks are | 221 // In contrast to registerWeakMembers, the weak cell callbacks are |
| 264 // run on the thread performing garbage collection. Therefore, all | 222 // run on the thread performing garbage collection. Therefore, all |
| 265 // threads are stopped during weak cell callbacks. | 223 // threads are stopped during weak cell callbacks. |
| 266 template <typename T> | 224 template <typename T> |
| 267 void registerWeakCell(T** cell) { | 225 void registerWeakCell(T** cell) { |
| 268 Derived::fromHelper(this)->registerWeakCellWithCallback( | 226 registerWeakCellWithCallback( |
| 269 reinterpret_cast<void**>( | 227 reinterpret_cast<void**>( |
| 270 const_cast<typename std::remove_const<T>::type**>(cell)), | 228 const_cast<typename std::remove_const<T>::type**>(cell)), |
| 271 &handleWeakCell<T>); | 229 &handleWeakCell<T>); |
| 272 } | 230 } |
| 273 | 231 |
| 274 template <typename T, void (T::*method)(Visitor*)> | 232 template <typename T, void (T::*method)(Visitor*)> |
| 275 void registerWeakMembers(const T* obj) { | 233 void registerWeakMembers(const T* obj) { |
| 276 registerWeakMembers(obj, &TraceMethodDelegate<T, method>::trampoline); | 234 registerWeakMembers(obj, &TraceMethodDelegate<T, method>::trampoline); |
| 277 } | 235 } |
| 278 | 236 |
| 279 void registerWeakMembers(const void* object, WeakCallback callback) { | 237 void registerWeakMembers(const void* object, WeakCallback callback) { |
| 280 Derived::fromHelper(this)->registerWeakMembers(object, object, callback); | 238 registerWeakMembers(object, object, callback); |
| 281 } | 239 } |
| 282 | 240 |
| 283 void registerBackingStoreReference(void* slot) { | 241 inline void registerBackingStoreReference(void* slot); |
| 284 if (getMarkingMode() != VisitorMarkingMode::GlobalMarkingWithCompaction) | |
| 285 return; | |
| 286 heap().registerMovingObjectReference( | |
| 287 reinterpret_cast<MovableReference*>(slot)); | |
| 288 } | |
| 289 | 242 |
| 290 void registerBackingStoreCallback(void* backingStore, | 243 inline void registerBackingStoreCallback(void* backingStore, |
| 291 MovingObjectCallback callback, | 244 MovingObjectCallback, |
| 292 void* callbackData) { | 245 void* callbackData); |
| 293 if (getMarkingMode() != VisitorMarkingMode::GlobalMarkingWithCompaction) | |
| 294 return; | |
| 295 heap().registerMovingObjectCallback( | |
| 296 reinterpret_cast<MovableReference>(backingStore), callback, | |
| 297 callbackData); | |
| 298 } | |
| 299 | |
| 300 inline ThreadState* state() const { return m_state; } | |
| 301 inline ThreadHeap& heap() const { return state()->heap(); } | |
| 302 | |
| 303 inline VisitorMarkingMode getMarkingMode() const { return m_markingMode; } | |
| 304 | |
| 305 inline bool isGlobalMarking() const { | |
| 306 return m_markingMode == VisitorMarkingMode::GlobalMarking || | |
| 307 m_markingMode == VisitorMarkingMode::GlobalMarkingWithCompaction; | |
| 308 } | |
| 309 | |
| 310 private: | |
| 311 template <typename T> | |
| 312 static void handleWeakCell(Visitor* self, void* object); | |
| 313 | |
| 314 ThreadState* const m_state; | |
| 315 const VisitorMarkingMode m_markingMode; | |
| 316 }; | |
| 317 | |
| 318 // Visitor is used to traverse the Blink object graph. Used for the | |
| 319 // marking phase of the mark-sweep garbage collector. | |
| 320 // | |
| 321 // Pointers are marked and pushed on the marking stack by calling the | |
| 322 // |mark| method with the pointer as an argument. | |
| 323 // | |
| 324 // Pointers within objects are traced by calling the |trace| methods | |
| 325 // with the object as an argument. Tracing objects will mark all of the | |
| 326 // contained pointers and push them on the marking stack. | |
| 327 class PLATFORM_EXPORT Visitor : public VisitorHelper<Visitor> { | |
| 328 public: | |
| 329 friend class VisitorHelper<Visitor>; | |
| 330 friend class InlinedGlobalMarkingVisitor; | |
| 331 | |
| 332 static std::unique_ptr<Visitor> create(ThreadState*, VisitorMarkingMode); | |
| 333 | |
| 334 virtual ~Visitor(); | |
| 335 | |
| 336 using VisitorHelper<Visitor>::mark; | |
| 337 | 246 |
| 338 // This method marks an object and adds it to the set of objects | 247 // This method marks an object and adds it to the set of objects |
| 339 // that should have their trace method called. Since not all | 248 // that should have their trace method called. Since not all |
| 340 // objects have vtables we have to have the callback as an | 249 // objects have vtables we have to have the callback as an |
| 341 // explicit argument, but we can use the templated one-argument | 250 // explicit argument, but we can use the templated one-argument |
| 342 // mark method above to automatically provide the callback | 251 // mark method above to automatically provide the callback |
| 343 // function. | 252 // function. |
| 344 virtual void mark(const void*, TraceCallback) = 0; | 253 inline void mark(const void* objectPointer, TraceCallback); |
| 345 | |
| 346 // Used to mark objects during conservative scanning. | |
| 347 virtual void markHeader(HeapObjectHeader*, TraceCallback) = 0; | |
| 348 | 254 |
| 349 // Used to delay the marking of objects until the usual marking | 255 // Used to delay the marking of objects until the usual marking |
| 350 // including emphemeron iteration is done. This is used to delay | 256 // including emphemeron iteration is done. This is used to delay |
| 351 // the marking of collection backing stores until we know if they | 257 // the marking of collection backing stores until we know if they |
| 352 // are reachable from locations other than the collection front | 258 // are reachable from locations other than the collection front |
| 353 // object. If collection backings are reachable from other | 259 // object. If collection backings are reachable from other |
| 354 // locations we strongify them to avoid issues with iterators and | 260 // locations we strongify them to avoid issues with iterators and |
| 355 // weak processing. | 261 // weak processing. |
| 356 virtual void registerDelayedMarkNoTracing(const void*) = 0; | 262 inline void registerDelayedMarkNoTracing(const void* pointer); |
| 357 | 263 |
| 358 // If the object calls this during the regular trace callback, then the | 264 // If the object calls this during the regular trace callback, then the |
| 359 // WeakCallback argument may be called later, when the strong roots | 265 // WeakCallback argument may be called later, when the strong roots |
| 360 // have all been found. The WeakCallback will normally use isAlive | 266 // have all been found. The WeakCallback will normally use isAlive |
| 361 // to find out whether some pointers are pointing to dying objects. When | 267 // to find out whether some pointers are pointing to dying objects. When |
| 362 // the WeakCallback is done the object must have purged all pointers | 268 // the WeakCallback is done the object must have purged all pointers |
| 363 // to objects where isAlive returned false. In the weak callback it is not | 269 // to objects where isAlive returned false. In the weak callback it is not |
| 364 // allowed to do anything that adds or extends the object graph (e.g., | 270 // allowed to do anything that adds or extends the object graph (e.g., |
| 365 // allocate a new object, add a new reference revive a dead object etc.) | 271 // allocate a new object, add a new reference revive a dead object etc.) |
| 366 // Clearing out pointers to other heap objects is allowed, however. Note | 272 // Clearing out pointers to other heap objects is allowed, however. Note |
| 367 // that even removing things from HeapHashSet or HeapHashMap can cause | 273 // that even removing things from HeapHashSet or HeapHashMap can cause |
| 368 // an allocation if the backing store resizes, but these collections know | 274 // an allocation if the backing store resizes, but these collections know |
| 369 // how to remove WeakMember elements safely. | 275 // how to remove WeakMember elements safely. |
| 370 // | 276 // |
| 371 // The weak pointer callbacks are run on the thread that owns the | 277 // The weak pointer callbacks are run on the thread that owns the |
| 372 // object and other threads are not stopped during the | 278 // object and other threads are not stopped during the |
| 373 // callbacks. Since isAlive is used in the callback to determine | 279 // callbacks. Since isAlive is used in the callback to determine |
| 374 // if objects pointed to are alive it is crucial that the object | 280 // if objects pointed to are alive it is crucial that the object |
| 375 // pointed to belong to the same thread as the object receiving | 281 // pointed to belong to the same thread as the object receiving |
| 376 // the weak callback. Since other threads have been resumed the | 282 // the weak callback. Since other threads have been resumed the |
| 377 // mark bits are not valid for objects from other threads. | 283 // mark bits are not valid for objects from other threads. |
| 378 virtual void registerWeakMembers(const void*, const void*, WeakCallback) = 0; | 284 inline void registerWeakMembers(const void* closure, |
| 379 using VisitorHelper<Visitor>::registerWeakMembers; | 285 const void* pointer, |
| 286 WeakCallback); |
| 380 | 287 |
| 381 virtual void registerWeakTable(const void*, | 288 inline void registerWeakTable(const void* closure, |
| 382 EphemeronCallback, | 289 EphemeronCallback iterationCallback, |
| 383 EphemeronCallback) = 0; | 290 EphemeronCallback iterationDoneCallback); |
| 291 |
| 384 #if DCHECK_IS_ON() | 292 #if DCHECK_IS_ON() |
| 385 virtual bool weakTableRegistered(const void*) = 0; | 293 inline bool weakTableRegistered(const void* closure); |
| 386 #endif | 294 #endif |
| 387 | 295 |
| 388 virtual bool ensureMarked(const void*) = 0; | 296 inline bool ensureMarked(const void* pointer); |
| 389 | 297 |
| 390 virtual void registerWeakCellWithCallback(void**, WeakCallback) = 0; | 298 inline void registerWeakCellWithCallback(void** cell, WeakCallback); |
| 391 | 299 |
| 392 protected: | 300 inline void markNoTracing(const void* pointer) { |
| 393 Visitor(ThreadState*, VisitorMarkingMode); | 301 mark(pointer, reinterpret_cast<TraceCallback>(0)); |
| 302 } |
| 303 |
| 304 inline void markHeaderNoTracing(HeapObjectHeader*); |
| 305 |
| 306 // Used to mark objects during conservative scanning. |
| 307 inline void markHeader(HeapObjectHeader*, |
| 308 const void* objectPointer, |
| 309 TraceCallback); |
| 310 |
| 311 inline void markHeader(HeapObjectHeader*, TraceCallback); |
| 312 |
| 313 inline ThreadState* state() const { return m_state; } |
| 314 inline ThreadHeap& heap() const { return state()->heap(); } |
| 315 |
| 316 inline VisitorMarkingMode getMarkingMode() const { return m_markingMode; } |
| 394 | 317 |
| 395 private: | 318 private: |
| 396 static Visitor* fromHelper(VisitorHelper<Visitor>* helper) { | 319 template <typename T> |
| 397 return static_cast<Visitor*>(helper); | 320 static void handleWeakCell(Visitor* self, void*); |
| 398 } | 321 |
| 322 static void markNoTracingCallback(Visitor*, void*); |
| 323 |
| 324 ThreadState* const m_state; |
| 325 const VisitorMarkingMode m_markingMode; |
| 399 }; | 326 }; |
| 400 | 327 |
| 401 } // namespace blink | 328 } // namespace blink |
| 402 | 329 |
| 403 #endif // Visitor_h | 330 #endif // Visitor_h |
| OLD | NEW |