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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #define TRACE_GC_USING_CLASSOF 1 | 46 #define TRACE_GC_USING_CLASSOF 1 |
47 #else | 47 #else |
48 #define TRACE_GC_USING_CLASSOF 0 | 48 #define TRACE_GC_USING_CLASSOF 0 |
49 #endif | 49 #endif |
50 | 50 |
51 namespace WebCore { | 51 namespace WebCore { |
52 | 52 |
53 template<typename T> class Member; | 53 template<typename T> class Member; |
54 template<typename T> class WeakMember; | 54 template<typename T> class WeakMember; |
55 class HeapAllocator; | 55 class HeapAllocator; |
56 template<bool needsVisiting, bool isWeak, bool visitWeakPointersStrongly, typena
me T, typename Traits> struct VisitCollectionBackingTrait; | 56 template<bool needsTracing, bool isWeak, bool markWeakPointersStrongly, typename
T, typename Traits> struct CollectionBackingTraceTrait; |
57 | 57 |
58 typedef void (*FinalizationCallback)(void*); | 58 typedef void (*FinalizationCallback)(void*); |
59 | 59 |
60 class Visitor; | 60 class Visitor; |
61 typedef void (*VisitorCallback)(Visitor*, void* self); | 61 typedef void (*VisitorCallback)(Visitor*, void* self); |
62 typedef VisitorCallback TraceCallback; | 62 typedef VisitorCallback TraceCallback; |
63 typedef VisitorCallback WeakPointerCallback; | 63 typedef VisitorCallback WeakPointerCallback; |
64 | 64 |
65 template<typename T, void (T::*method)(Visitor*)> | 65 template<typename T, void (T::*method)(Visitor*)> |
66 struct TraceMethodDelegate { | 66 struct TraceMethodDelegate { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 template<typename T> | 187 template<typename T> |
188 class TraceTrait { | 188 class TraceTrait { |
189 public: | 189 public: |
190 // Default implementation of TraceTrait<T>::trace just statically | 190 // Default implementation of TraceTrait<T>::trace just statically |
191 // dispatches to the trace method of the class T. | 191 // dispatches to the trace method of the class T. |
192 static void trace(Visitor* visitor, void* self) | 192 static void trace(Visitor* visitor, void* self) |
193 { | 193 { |
194 static_cast<T*>(self)->trace(visitor); | 194 static_cast<T*>(self)->trace(visitor); |
195 } | 195 } |
196 | 196 |
197 static void visit(Visitor*, const T*); | 197 static void mark(Visitor*, const T*); |
198 | 198 |
199 #ifndef NDEBUG | 199 #ifndef NDEBUG |
200 static void checkTypeMarker(Visitor*, const T*); | 200 static void checkTypeMarker(Visitor*, const T*); |
201 #endif | 201 #endif |
202 }; | 202 }; |
203 | 203 |
204 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 204 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
205 | 205 |
206 template<typename K, typename V, typename HashTraits, typename KeyTraits, typena
me ValueTraits> | 206 template<typename K, typename V, typename HashTraits, typename KeyTraits, typena
me ValueTraits> |
207 void processWeakOffHeapHashMap(Visitor*, void* map); | 207 void processWeakOffHeapHashMap(Visitor*, void* map); |
208 template<typename T, typename HashFunctions, typename Traits> | 208 template<typename T, typename HashFunctions, typename Traits> |
209 void processWeakOffHeapHashSet(Visitor*, void* set); | 209 void processWeakOffHeapHashSet(Visitor*, void* set); |
210 | 210 |
211 template<typename Collection> | 211 template<typename Collection> |
212 struct CollectionVisitingTrait { | 212 struct OffHeapCollectionTraceTrait { |
213 static void visit(Visitor*, const Collection&); | 213 static void mark(Visitor*, const Collection&); |
214 }; | 214 }; |
215 | 215 |
216 template<typename T> | 216 template<typename T> |
217 struct ObjectAliveTrait { | 217 struct ObjectAliveTrait { |
218 static bool isAlive(Visitor*, T); | 218 static bool isAlive(Visitor*, T); |
219 }; | 219 }; |
220 | 220 |
221 template<typename T> | 221 template<typename T> |
222 struct ObjectAliveTrait<Member<T> > { | 222 struct ObjectAliveTrait<Member<T> > { |
223 static bool isAlive(Visitor*, const Member<T>&); | 223 static bool isAlive(Visitor*, const Member<T>&); |
224 }; | 224 }; |
225 | 225 |
226 class HeapObjectHeader; | 226 class HeapObjectHeader; |
227 class FinalizedHeapObjectHeader; | 227 class FinalizedHeapObjectHeader; |
228 | 228 |
229 #ifndef NDEBUG | 229 #ifndef NDEBUG |
230 #define DEBUG_ONLY(x) x | 230 #define DEBUG_ONLY(x) x |
231 #else | 231 #else |
232 #define DEBUG_ONLY(x) | 232 #define DEBUG_ONLY(x) |
233 #endif | 233 #endif |
234 | 234 |
235 class Visitor { | 235 class Visitor { |
236 public: | 236 public: |
237 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING | 237 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING |
238 Visitor() : m_hostObject(0), m_hostName(0) { } | 238 Visitor() : m_hostObject(0), m_hostName(0) { } |
239 #endif | 239 #endif |
240 | 240 |
241 // One-argument templated visit method. This uses the static type of | 241 // One-argument templated mark method. This uses the static type of |
242 // the argument to get the TraceTrait. By default, the visit method | 242 // the argument to get the TraceTrait. By default, the mark method |
243 // of the TraceTrait just calls the virtual two-argument visit method on thi
s | 243 // of the TraceTrait just calls the virtual two-argument mark method on this |
244 // visitor, where the second argument is the static trace method. | 244 // visitor, where the second argument is the static trace method. |
245 template<typename T> | 245 template<typename T> |
246 void visit(T* t) | 246 void mark(T* t) |
247 { | 247 { |
248 if (!t) | 248 if (!t) |
249 return; | 249 return; |
250 #ifndef NDEBUG | 250 #ifndef NDEBUG |
251 TraceTrait<T>::checkTypeMarker(this, t); | 251 TraceTrait<T>::checkTypeMarker(this, t); |
252 #endif | 252 #endif |
253 TraceTrait<T>::visit(this, t); | 253 TraceTrait<T>::mark(this, t); |
254 } | 254 } |
255 | 255 |
256 // Member version of the one-argument templated visit method. | 256 // Member version of the one-argument templated mark method. |
257 template<typename T> | 257 template<typename T> |
258 void trace(const Member<T>& t) | 258 void trace(const Member<T>& t) |
259 { | 259 { |
260 if (!t) | 260 if (!t) |
261 return; | 261 return; |
262 #ifndef NDEBUG | 262 #ifndef NDEBUG |
263 TraceTrait<T>::checkTypeMarker(this, t.raw()); | 263 TraceTrait<T>::checkTypeMarker(this, t.raw()); |
264 #endif | 264 #endif |
265 TraceTrait<T>::visit(this, t.raw()); | 265 TraceTrait<T>::mark(this, t.raw()); |
266 } | 266 } |
267 | 267 |
268 // Doesn't keep the visited thing alive, but will write null to the | 268 // Doesn't keep the traced thing alive, but will write null to the |
269 // WeakMember later if the pointed-to object is dead. | 269 // WeakMember later if the pointed-to object is dead. |
270 template<typename T> | 270 template<typename T> |
271 void trace(const WeakMember<T>& t) | 271 void trace(const WeakMember<T>& t) |
272 { | 272 { |
273 registerWeakCell(t.cell()); | 273 registerWeakCell(t.cell()); |
274 } | 274 } |
275 | 275 |
276 // The following visit methods are for off-heap collections. | 276 // The following mark methods are for off-heap collections. |
277 template<typename T, size_t inlineCapacity> | 277 template<typename T, size_t inlineCapacity> |
278 void trace(const Vector<T, inlineCapacity, WTF::FastAllocator>& vector) | 278 void trace(const Vector<T, inlineCapacity, WTF::FastAllocator>& vector) |
279 { | 279 { |
280 CollectionVisitingTrait<Vector<T, inlineCapacity, WTF::FastAllocator> >:
:visit(this, vector); | 280 OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::FastAllocator
> >::mark(this, vector); |
281 } | 281 } |
282 | 282 |
283 template<typename T, typename U, typename V> | 283 template<typename T, typename U, typename V> |
284 void trace(const HashSet<T, WTF::FastAllocator, U, V>& hashSet) | 284 void trace(const HashSet<T, WTF::FastAllocator, U, V>& hashSet) |
285 { | 285 { |
286 CollectionVisitingTrait<HashSet<T, WTF::FastAllocator, U, V> >::visit(th
is, hashSet); | 286 OffHeapCollectionTraceTrait<HashSet<T, WTF::FastAllocator, U, V> >::mark
(this, hashSet); |
287 } | 287 } |
288 | 288 |
289 template<typename T, size_t inlineCapacity, typename U> | 289 template<typename T, size_t inlineCapacity, typename U> |
290 void trace(const ListHashSet<T, inlineCapacity, U>& hashSet) | 290 void trace(const ListHashSet<T, inlineCapacity, U>& hashSet) |
291 { | 291 { |
292 CollectionVisitingTrait<ListHashSet<T, inlineCapacity, U> >::visit(this,
hashSet); | 292 OffHeapCollectionTraceTrait<ListHashSet<T, inlineCapacity, U> >::mark(th
is, hashSet); |
293 } | 293 } |
294 | 294 |
295 template<typename T, size_t N> | 295 template<typename T, size_t N> |
296 void trace(const Deque<T, N>& deque) | 296 void trace(const Deque<T, N>& deque) |
297 { | 297 { |
298 CollectionVisitingTrait<Deque<T, N> >::visit(this, deque); | 298 OffHeapCollectionTraceTrait<Deque<T, N> >::mark(this, deque); |
299 } | 299 } |
300 | 300 |
301 template<typename T, typename U, typename V, typename W, typename X> | 301 template<typename T, typename U, typename V, typename W, typename X> |
302 void trace(const HashMap<T, U, WTF::FastAllocator, V, W, X>& map) | 302 void trace(const HashMap<T, U, WTF::FastAllocator, V, W, X>& map) |
303 { | 303 { |
304 CollectionVisitingTrait<HashMap<T, U, WTF::FastAllocator, V, W, X> >::vi
sit(this, map); | 304 OffHeapCollectionTraceTrait<HashMap<T, U, WTF::FastAllocator, V, W, X> >
::mark(this, map); |
305 } | 305 } |
306 | 306 |
307 // Fallback trace method for part objects to allow individual | 307 // Fallback trace method for part objects to allow individual |
308 // trace methods to trace through a part object with | 308 // trace methods to trace through a part object with |
309 // visitor->trace(m_partObject). | 309 // visitor->trace(m_partObject). |
310 template<typename T> | 310 template<typename T> |
311 void trace(const T& t) | 311 void trace(const T& t) |
312 { | 312 { |
313 const_cast<T&>(t).trace(this); | 313 const_cast<T&>(t).trace(this); |
314 } | 314 } |
315 | 315 |
316 // OwnPtrs that are traced are treated as part objects and the | 316 // OwnPtrs that are traced are treated as part objects and the |
317 // trace method of the owned object is called. | 317 // trace method of the owned object is called. |
318 template<typename T> | 318 template<typename T> |
319 void trace(const OwnPtr<T>& t) | 319 void trace(const OwnPtr<T>& t) |
320 { | 320 { |
321 t->trace(this); | 321 t->trace(this); |
322 } | 322 } |
323 | 323 |
324 // This method adds the object to the set of objects that should have their | 324 // This method adds the object to the set of objects that should have their |
325 // trace method called. Since not all objects have vtables we have to have | 325 // trace method called. Since not all objects have vtables we have to have |
326 // the callback as an explicit argument, but we can use the templated | 326 // the callback as an explicit argument, but we can use the templated |
327 // one-argument visit method above to automatically provide the callback | 327 // one-argument mark method above to automatically provide the callback |
328 // function. | 328 // function. |
329 virtual void visit(const void*, TraceCallback) = 0; | 329 virtual void mark(const void*, TraceCallback) = 0; |
330 | 330 |
331 // Used during conservative scanning. | 331 // Used during conservative scanning. |
332 virtual void visit(HeapObjectHeader*, TraceCallback) = 0; | 332 virtual void mark(HeapObjectHeader*, TraceCallback) = 0; |
333 virtual void visit(FinalizedHeapObjectHeader*, TraceCallback) = 0; | 333 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0; |
334 | 334 |
335 // If the object calls this during the regular trace callback, then the | 335 // If the object calls this during the regular trace callback, then the |
336 // WeakPointerCallback argument may be called later, when the strong roots | 336 // WeakPointerCallback argument may be called later, when the strong roots |
337 // have all been found. The WeakPointerCallback will normally use isAlive | 337 // have all been found. The WeakPointerCallback will normally use isAlive |
338 // to find out whether some pointers are pointing to dying objects. When | 338 // to find out whether some pointers are pointing to dying objects. When |
339 // the WeakPointerCallback is done the object must have purged all pointers | 339 // the WeakPointerCallback is done the object must have purged all pointers |
340 // to objects where isAlive returned false. | 340 // to objects where isAlive returned false. |
341 virtual void registerWeakPointers(const void*, WeakPointerCallback) = 0; | 341 virtual void registerWeakPointers(const void*, WeakPointerCallback) = 0; |
342 | 342 |
343 template<typename T, void (T::*method)(Visitor*)> | 343 template<typename T, void (T::*method)(Visitor*)> |
(...skipping 26 matching lines...) Expand all Loading... |
370 } | 370 } |
371 #endif | 371 #endif |
372 | 372 |
373 #ifndef NDEBUG | 373 #ifndef NDEBUG |
374 void checkTypeMarker(const void*, const char* marker); | 374 void checkTypeMarker(const void*, const char* marker); |
375 #endif | 375 #endif |
376 | 376 |
377 // Macro to declare methods needed for each typed heap. | 377 // Macro to declare methods needed for each typed heap. |
378 #define DECLARE_VISITOR_METHODS(Type) \ | 378 #define DECLARE_VISITOR_METHODS(Type) \ |
379 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \ | 379 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \ |
380 virtual void visit(const Type*, TraceCallback) = 0; \ | 380 virtual void mark(const Type*, TraceCallback) = 0; \ |
381 virtual bool isMarked(const Type*) = 0; | 381 virtual bool isMarked(const Type*) = 0; |
382 | 382 |
383 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 383 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
384 #undef DECLARE_VISITOR_METHODS | 384 #undef DECLARE_VISITOR_METHODS |
385 | 385 |
386 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING | 386 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING |
387 protected: | 387 protected: |
388 void* m_hostObject; | 388 void* m_hostObject; |
389 const char* m_hostName; | 389 const char* m_hostName; |
390 #endif | 390 #endif |
391 private: | 391 private: |
392 template<typename T> | 392 template<typename T> |
393 static void handleWeakCell(Visitor* self, void* obj) | 393 static void handleWeakCell(Visitor* self, void* obj) |
394 { | 394 { |
395 T** cell = reinterpret_cast<T**>(obj); | 395 T** cell = reinterpret_cast<T**>(obj); |
396 if (*cell && !self->isAlive(*cell)) | 396 if (*cell && !self->isAlive(*cell)) |
397 *cell = 0; | 397 *cell = 0; |
398 } | 398 } |
399 }; | 399 }; |
400 | 400 |
401 template<typename T, typename HashFunctions, typename Traits> | 401 template<typename T, typename HashFunctions, typename Traits> |
402 struct CollectionVisitingTrait<WTF::HashSet<T, WTF::FastAllocator, HashFunctions
, Traits> > { | 402 struct OffHeapCollectionTraceTrait<WTF::HashSet<T, WTF::FastAllocator, HashFunct
ions, Traits> > { |
403 typedef WTF::HashSet<T, WTF::FastAllocator, HashFunctions, Traits> HashSet; | 403 typedef WTF::HashSet<T, WTF::FastAllocator, HashFunctions, Traits> HashSet; |
404 | 404 |
405 static void visit(Visitor* v, const HashSet& set) | 405 static void mark(Visitor* v, const HashSet& set) |
406 { | 406 { |
407 if (set.isEmpty()) | 407 if (set.isEmpty()) |
408 return; | 408 return; |
409 if (WTF::NeedsVisiting<T>::value) { | 409 if (WTF::NeedsTracing<T>::value) { |
410 for (typename HashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) | 410 for (typename HashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
411 VisitCollectionBackingTrait<Traits::needsVisiting, Traits::isWea
k, false, T, Traits>::visit(v, *it); | 411 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak
, false, T, Traits>::mark(v, *it); |
412 } | 412 } |
413 if (Traits::isWeak) { | 413 if (Traits::isWeak) { |
414 if (!set.isEmpty()) | 414 if (!set.isEmpty()) |
415 v->registerWeakPointers(&set, processWeakOffHeapHashSet<T, HashF
unctions, Traits>); | 415 v->registerWeakPointers(&set, processWeakOffHeapHashSet<T, HashF
unctions, Traits>); |
416 } | 416 } |
417 } | 417 } |
418 }; | 418 }; |
419 | 419 |
420 template<typename T, size_t inlineCapacity, typename HashFunctions> | 420 template<typename T, size_t inlineCapacity, typename HashFunctions> |
421 struct CollectionVisitingTrait<WTF::ListHashSet<T, inlineCapacity, HashFunctions
> > { | 421 struct OffHeapCollectionTraceTrait<WTF::ListHashSet<T, inlineCapacity, HashFunct
ions> > { |
422 typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; | 422 typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; |
423 | 423 |
424 static void visit(Visitor* visitor, const ListHashSet& set) | 424 static void mark(Visitor* visitor, const ListHashSet& set) |
425 { | 425 { |
426 if (set.isEmpty()) | 426 if (set.isEmpty()) |
427 return; | 427 return; |
428 for (typename ListHashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) | 428 for (typename ListHashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
429 visitor->trace(*it); | 429 visitor->trace(*it); |
430 } | 430 } |
431 }; | 431 }; |
432 | 432 |
433 template<typename Key, typename Value, typename HashFunctions, typename KeyTrait
s, typename ValueTraits> | 433 template<typename Key, typename Value, typename HashFunctions, typename KeyTrait
s, typename ValueTraits> |
434 struct CollectionVisitingTrait<WTF::HashMap<Key, Value, WTF::FastAllocator, Hash
Functions, KeyTraits, ValueTraits> > { | 434 struct OffHeapCollectionTraceTrait<WTF::HashMap<Key, Value, WTF::FastAllocator,
HashFunctions, KeyTraits, ValueTraits> > { |
435 typedef WTF::HashMap<Key, Value, WTF::FastAllocator, HashFunctions, KeyTrait
s, ValueTraits> HashMap; | 435 typedef WTF::HashMap<Key, Value, WTF::FastAllocator, HashFunctions, KeyTrait
s, ValueTraits> HashMap; |
436 | 436 |
437 static void visit(Visitor* v, const HashMap& map) | 437 static void mark(Visitor* v, const HashMap& map) |
438 { | 438 { |
439 if (map.isEmpty()) | 439 if (map.isEmpty()) |
440 return; | 440 return; |
441 if (WTF::NeedsVisiting<Key>::value || WTF::NeedsVisiting<Value>::value)
{ | 441 if (WTF::NeedsTracing<Key>::value || WTF::NeedsTracing<Value>::value) { |
442 for (typename HashMap::const_iterator it = map.begin(), end = map.en
d(); it != end; ++it) { | 442 for (typename HashMap::const_iterator it = map.begin(), end = map.en
d(); it != end; ++it) { |
443 VisitCollectionBackingTrait<KeyTraits::needsVisiting, KeyTraits:
:isWeak, false, Key, KeyTraits>::visit(v, it->key); | 443 CollectionBackingTraceTrait<KeyTraits::needsTracing, KeyTraits::
isWeak, false, Key, KeyTraits>::mark(v, it->key); |
444 VisitCollectionBackingTrait<ValueTraits::needsVisiting, ValueTra
its::isWeak, false, Value, ValueTraits>::visit(v, it->value); | 444 CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTrai
ts::isWeak, false, Value, ValueTraits>::mark(v, it->value); |
445 } | 445 } |
446 } | 446 } |
447 if (KeyTraits::isWeak || ValueTraits::isWeak) { | 447 if (KeyTraits::isWeak || ValueTraits::isWeak) { |
448 if (!map.isEmpty()) | 448 if (!map.isEmpty()) |
449 v->registerWeakPointers(&map, processWeakOffHeapHashMap<Key, Val
ue, HashFunctions, KeyTraits, ValueTraits>); | 449 v->registerWeakPointers(&map, processWeakOffHeapHashMap<Key, Val
ue, HashFunctions, KeyTraits, ValueTraits>); |
450 } | 450 } |
451 } | 451 } |
452 }; | 452 }; |
453 | 453 |
454 #ifndef NDEBUG | 454 #ifndef NDEBUG |
455 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) | 455 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) |
456 { | 456 { |
457 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); | 457 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); |
458 } | 458 } |
459 #endif | 459 #endif |
460 | 460 |
461 template<typename T> void TraceTrait<T>::visit(Visitor* visitor, const T* t) | 461 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) |
462 { | 462 { |
463 // Default visit method of the trait just calls the two-argument visit | 463 // Default mark method of the trait just calls the two-argument mark |
464 // method on the visitor. The second argument is the static trace method | 464 // method on the visitor. The second argument is the static trace method |
465 // of the trait, which by default calls the instance method | 465 // of the trait, which by default calls the instance method |
466 // trace(Visitor*) on the object. | 466 // trace(Visitor*) on the object. |
467 visitor->visit(const_cast<T*>(t), &trace); | 467 visitor->mark(const_cast<T*>(t), &trace); |
468 } | 468 } |
469 | 469 |
470 inline void doNothingTrace(Visitor*, void*) | 470 inline void doNothingTrace(Visitor*, void*) |
471 { | 471 { |
472 } | 472 } |
473 | 473 |
474 template<typename T, typename Traits = WTF::VectorTraits<T> > | 474 template<typename T, typename Traits = WTF::VectorTraits<T> > |
475 class HeapVectorBacking; | 475 class HeapVectorBacking; |
476 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> | 476 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> |
477 class HeapHashTableBacking; | 477 class HeapHashTableBacking; |
478 | 478 |
479 // Non-class types like char don't have an trace method, so we provide a more | 479 // Non-class types like char don't have an trace method, so we provide a more |
480 // specialized template instantiation here that will be selected in preference | 480 // specialized template instantiation here that will be selected in preference |
481 // to the default. Most of them do nothing, since the type in question cannot | 481 // to the default. Most of them do nothing, since the type in question cannot |
482 // point to other heap allocated objects. | 482 // point to other heap allocated objects. |
483 #define ITERATE_DO_NOTHING_TYPES(f) \ | 483 #define ITERATE_DO_NOTHING_TYPES(f) \ |
484 f(uint8_t) \ | 484 f(uint8_t) \ |
485 f(void) | 485 f(void) |
486 | 486 |
487 #define DECLARE_DO_NOTHING_TRAIT(type) \ | 487 #define DECLARE_DO_NOTHING_TRAIT(type) \ |
488 template<> \ | 488 template<> \ |
489 class TraceTrait<type> { \ | 489 class TraceTrait<type> { \ |
490 public: \ | 490 public: \ |
491 static void checkTypeMarker(Visitor*, const void*) { } \ | 491 static void checkTypeMarker(Visitor*, const void*) { } \ |
492 static void visit(Visitor* v, const type* p) { \ | 492 static void mark(Visitor* v, const type* p) { \ |
493 v->visit(p, nullptr); \ | 493 v->mark(p, nullptr); \ |
494 } \ | 494 } \ |
495 }; \ | 495 }; \ |
496 template<> \ | 496 template<> \ |
497 struct FinalizerTrait<type> { \ | 497 struct FinalizerTrait<type> { \ |
498 static void finalize(void*) { } \ | 498 static void finalize(void*) { } \ |
499 static const bool nonTrivialFinalizer = false; \ | 499 static const bool nonTrivialFinalizer = false; \ |
500 }; \ | 500 }; \ |
501 template<> \ | 501 template<> \ |
502 struct GCInfoTrait<type> { \ | 502 struct GCInfoTrait<type> { \ |
503 static const GCInfo* get() \ | 503 static const GCInfo* get() \ |
504 { \ | 504 { \ |
505 return &info; \ | 505 return &info; \ |
506 } \ | 506 } \ |
507 static const GCInfo info; \ | 507 static const GCInfo info; \ |
508 }; | 508 }; |
509 | 509 |
510 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) | 510 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) |
511 | 511 |
512 #undef DECLARE_DO_NOTHING_TRAIT | 512 #undef DECLARE_DO_NOTHING_TRAIT |
513 | 513 |
514 // Vectors are simple collections, and it's possible to visit vectors in a more | 514 // Vectors are simple collections, and it's possible to mark vectors in a more |
515 // general way so that collections of objects (not pointers to objects) can be | 515 // general way so that collections of objects (not pointers to objects) can be |
516 // visited. | 516 // marked. |
517 template<typename T, size_t N> | 517 template<typename T, size_t N> |
518 struct CollectionVisitingTrait<WTF::Vector<T, N, WTF::FastAllocator> > { | 518 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::FastAllocator> > { |
519 typedef WTF::Vector<T, N, WTF::FastAllocator> Vector; | 519 typedef WTF::Vector<T, N, WTF::FastAllocator> Vector; |
520 | 520 |
521 static void visit(Visitor* v, const Vector& vector) | 521 static void mark(Visitor* v, const Vector& vector) |
522 { | 522 { |
523 if (vector.isEmpty()) | 523 if (vector.isEmpty()) |
524 return; | 524 return; |
525 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) | 525 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) |
526 TraceTrait<T>::trace(v, const_cast<T*>(it)); | 526 TraceTrait<T>::trace(v, const_cast<T*>(it)); |
527 } | 527 } |
528 }; | 528 }; |
529 | 529 |
530 // Fallback definition. | 530 // Fallback definition. |
531 template<typename Collection> void CollectionVisitingTrait<Collection>::visit(Vi
sitor* visitor, const Collection& collection) | 531 template<typename Collection> void OffHeapCollectionTraceTrait<Collection>::mark
(Visitor* visitor, const Collection& collection) |
532 { | 532 { |
533 if (collection.isEmpty()) | 533 if (collection.isEmpty()) |
534 return; | 534 return; |
535 for (typename Collection::const_iterator it = collection.begin(), end = coll
ection.end(); it != end; ++it) | 535 for (typename Collection::const_iterator it = collection.begin(), end = coll
ection.end(); it != end; ++it) |
536 visitor->trace(*it); | 536 visitor->trace(*it); |
537 } | 537 } |
538 | 538 |
539 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) | 539 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) |
540 { | 540 { |
541 return visitor->isMarked(obj); | 541 return visitor->isMarked(obj); |
542 } | 542 } |
543 | 543 |
544 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) | 544 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) |
545 { | 545 { |
546 return visitor->isMarked(obj.raw()); | 546 return visitor->isMarked(obj.raw()); |
547 } | 547 } |
548 | 548 |
549 class HeapVisitable { | 549 class HeapVisitable { |
550 public: | 550 public: |
551 virtual void trace(Visitor*) = 0; | 551 virtual void trace(Visitor*) = 0; |
552 virtual ~HeapVisitable() | 552 virtual ~HeapVisitable() |
553 { | 553 { |
554 } | 554 } |
555 }; | 555 }; |
556 | 556 |
557 } | 557 } |
558 #endif | 558 #endif |
OLD | NEW |