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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 #if ENABLE(ASSERT) | 180 #if ENABLE(ASSERT) |
181 static void checkGCInfo(Visitor* visitor, const T* t) | 181 static void checkGCInfo(Visitor* visitor, const T* t) |
182 { | 182 { |
183 DefaultTraceTrait<T>::checkGCInfo(visitor, t); | 183 DefaultTraceTrait<T>::checkGCInfo(visitor, t); |
184 } | 184 } |
185 #endif | 185 #endif |
186 }; | 186 }; |
187 | 187 |
188 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 188 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
189 | 189 |
| 190 // If ENABLE_EAGER_TRACING_BY_DEFAULT is set to 1, GCed objects will |
| 191 // be eagerly traced by default. A class type can opt out by declaring |
| 192 // a TraceEagerlyTrait<> specialization, mapping the value to 'false' |
| 193 // (see the WILL_NOT_BE_EAGERLY_TRACED() macro below.) |
| 194 #define ENABLE_EAGER_TRACING_BY_DEFAULT 0 |
| 195 |
| 196 // DISABLE_ALL_EAGER_TRACING provides the "kill switch" for eager |
| 197 // tracing; setting it to 1 will disable the use of eager tracing |
| 198 // entirely. That is, eager tracing is disabled even if traits have |
| 199 // been declared. |
| 200 #define DISABLE_ALL_EAGER_TRACING 0 |
| 201 |
| 202 // If TraceEagerlyTrait<T>::value is true, then the marker thread should |
| 203 // invoke trace() on not-yet-marked objects deriving from class T right |
| 204 // away, and not queue their trace callbacks on its marker stack. |
| 205 // |
| 206 // Specific template specializations of TraceEagerlyTrait<T> can be used |
| 207 // to declare that eager tracing should always be used when tracing over |
| 208 // GCed objects with class type T. If the trait's boolean 'value' is |
| 209 // mapped to 'true' that is; declare it as 'false' to disable eager tracing. |
| 210 // |
| 211 // The trait can be declared to enable/disable eager tracing for a class T |
| 212 // and any of its subclasses, or just to the class T (but none of its subclasses
.) |
| 213 // |
| 214 template<typename T, typename Enabled = void> |
| 215 class TraceEagerlyTrait { |
| 216 public: |
| 217 static const bool value = ENABLE_EAGER_TRACING_BY_DEFAULT; |
| 218 }; |
| 219 |
| 220 #define WILL_BE_EAGERLY_TRACED(TYPE)
\ |
| 221 template<typename U>
\ |
| 222 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu
e>::Type> { \ |
| 223 public:
\ |
| 224 static const bool value = true;
\ |
| 225 } |
| 226 |
| 227 #define WILL_NOT_BE_EAGERLY_TRACED(TYPE)
\ |
| 228 template<typename U>
\ |
| 229 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu
e>::Type> { \ |
| 230 public:
\ |
| 231 static const bool value = false;
\ |
| 232 } |
| 233 |
| 234 // Limit eager tracing to only apply to TYPE (but not any of its subclasses.) |
| 235 #define WILL_BE_EAGERLY_TRACED_CLASS(TYPE) \ |
| 236 template<> \ |
| 237 class TraceEagerlyTrait<TYPE> { \ |
| 238 public: \ |
| 239 static const bool value = true; \ |
| 240 } |
| 241 |
| 242 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \ |
| 243 template<> \ |
| 244 class TraceEagerlyTrait<TYPE> { \ |
| 245 public: \ |
| 246 static const bool value = false; \ |
| 247 } |
| 248 |
| 249 // Set to 1 if you want collections to be eagerly traced regardless |
| 250 // of whether the elements are eagerly traceable or not. |
| 251 #define ENABLE_EAGER_HEAP_COLLECTION_TRACING ENABLE_EAGER_TRACING_BY_DEFAULT |
| 252 |
| 253 #if ENABLE_EAGER_HEAP_COLLECTION_TRACING |
| 254 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) true |
| 255 #else |
| 256 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) TraceEagerlyTrait<Type>::value |
| 257 #endif |
| 258 |
190 template<typename Collection> | 259 template<typename Collection> |
191 struct OffHeapCollectionTraceTrait; | 260 struct OffHeapCollectionTraceTrait; |
192 | 261 |
193 template<typename T> | 262 template<typename T> |
194 struct ObjectAliveTrait { | 263 struct ObjectAliveTrait { |
195 static bool isHeapObjectAlive(Visitor*, T*); | 264 static bool isHeapObjectAlive(Visitor*, T*); |
196 }; | 265 }; |
197 | 266 |
198 // Visitor is used to traverse the Blink object graph. Used for the | 267 // Visitor is used to traverse the Blink object graph. Used for the |
199 // marking phase of the mark-sweep garbage collector. | 268 // marking phase of the mark-sweep garbage collector. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 template<typename T> void trace(const WeakPtr<T>&) { } | 391 template<typename T> void trace(const WeakPtr<T>&) { } |
323 #endif | 392 #endif |
324 | 393 |
325 // This method marks an object and adds it to the set of objects | 394 // This method marks an object and adds it to the set of objects |
326 // that should have their trace method called. Since not all | 395 // that should have their trace method called. Since not all |
327 // objects have vtables we have to have the callback as an | 396 // objects have vtables we have to have the callback as an |
328 // explicit argument, but we can use the templated one-argument | 397 // explicit argument, but we can use the templated one-argument |
329 // mark method above to automatically provide the callback | 398 // mark method above to automatically provide the callback |
330 // function. | 399 // function. |
331 virtual void mark(const void*, TraceCallback) = 0; | 400 virtual void mark(const void*, TraceCallback) = 0; |
| 401 |
| 402 template<typename T> void markNoTracing(const T* pointer) { mark(pointer, re
interpret_cast<TraceCallback>(0)); } |
332 void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<Tra
ceCallback>(0)); } | 403 void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<Tra
ceCallback>(0)); } |
333 void markNoTracing(HeapObjectHeader* header) { mark(header, reinterpret_cast
<TraceCallback>(0)); } | 404 void markNoTracing(HeapObjectHeader* header) { mark(header, reinterpret_cast
<TraceCallback>(0)); } |
334 void markNoTracing(FinalizedHeapObjectHeader* header) { mark(header, reinter
pret_cast<TraceCallback>(0)); } | 405 void markNoTracing(FinalizedHeapObjectHeader* header) { mark(header, reinter
pret_cast<TraceCallback>(0)); } |
335 | 406 |
336 // Used to mark objects during conservative scanning. | 407 // Used to mark objects during conservative scanning. |
337 virtual void mark(HeapObjectHeader*, TraceCallback) = 0; | 408 virtual void mark(HeapObjectHeader*, TraceCallback) = 0; |
338 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0; | 409 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0; |
339 | 410 |
340 // Used to delay the marking of objects until the usual marking | 411 // Used to delay the marking of objects until the usual marking |
341 // including emphemeron iteration is done. This is used to delay | 412 // including emphemeron iteration is done. This is used to delay |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 { | 458 { |
388 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>); | 459 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>); |
389 } | 460 } |
390 | 461 |
391 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) = 0; | 462 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) = 0; |
392 #if ENABLE(ASSERT) | 463 #if ENABLE(ASSERT) |
393 virtual bool weakTableRegistered(const void*) = 0; | 464 virtual bool weakTableRegistered(const void*) = 0; |
394 #endif | 465 #endif |
395 | 466 |
396 virtual bool isMarked(const void*) = 0; | 467 virtual bool isMarked(const void*) = 0; |
| 468 virtual bool ensureMarked(const void*) = 0; |
397 | 469 |
398 template<typename T> inline bool isAlive(T* obj) | 470 template<typename T> inline bool isAlive(T* obj) |
399 { | 471 { |
400 // Check that we actually know the definition of T when tracing. | 472 // Check that we actually know the definition of T when tracing. |
401 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); | 473 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); |
402 // The strongification of collections relies on the fact that once a | 474 // The strongification of collections relies on the fact that once a |
403 // collection has been strongified, there is no way that it can contain | 475 // collection has been strongified, there is no way that it can contain |
404 // non-live entries, so no entries will be removed. Since you can't set | 476 // non-live entries, so no entries will be removed. Since you can't set |
405 // the mark bit on a null pointer, that means that null pointers are | 477 // the mark bit on a null pointer, that means that null pointers are |
406 // always 'alive'. | 478 // always 'alive'. |
407 if (!obj) | 479 if (!obj) |
408 return true; | 480 return true; |
409 return ObjectAliveTrait<T>::isHeapObjectAlive(this, obj); | 481 return ObjectAliveTrait<T>::isHeapObjectAlive(this, obj); |
410 } | 482 } |
411 template<typename T> inline bool isAlive(const Member<T>& member) | 483 template<typename T> inline bool isAlive(const Member<T>& member) |
412 { | 484 { |
413 return isAlive(member.get()); | 485 return isAlive(member.get()); |
414 } | 486 } |
415 template<typename T> inline bool isAlive(RawPtr<T> ptr) | 487 template<typename T> inline bool isAlive(RawPtr<T> ptr) |
416 { | 488 { |
417 return isAlive(ptr.get()); | 489 return isAlive(ptr.get()); |
418 } | 490 } |
419 | 491 |
420 #if ENABLE(ASSERT) | 492 #if ENABLE(ASSERT) |
421 void checkGCInfo(const void*, const GCInfo*); | 493 void checkGCInfo(const void*, const GCInfo*); |
422 #endif | 494 #endif |
423 | 495 |
424 // Macro to declare methods needed for each typed heap. | 496 // Macro to declare methods needed for each typed heap. |
425 #define DECLARE_VISITOR_METHODS(Type) \ | 497 #define DECLARE_VISITOR_METHODS(Type) \ |
426 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ | 498 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ |
427 virtual void mark(const Type*, TraceCallback) = 0; \ | 499 virtual void mark(const Type*, TraceCallback) = 0; \ |
428 virtual bool isMarked(const Type*) = 0; | 500 virtual bool isMarked(const Type*) = 0; \ |
| 501 virtual bool ensureMarked(const Type*) = 0; |
429 | 502 |
430 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 503 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
431 #undef DECLARE_VISITOR_METHODS | 504 #undef DECLARE_VISITOR_METHODS |
432 | 505 |
433 #if ENABLE(GC_PROFILE_MARKING) | 506 #if ENABLE(GC_PROFILE_MARKING) |
434 void setHostInfo(void* object, const String& name) | 507 void setHostInfo(void* object, const String& name) |
435 { | 508 { |
436 m_hostObject = object; | 509 m_hostObject = object; |
437 m_hostName = name; | 510 m_hostName = name; |
438 } | 511 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 568 |
496 template<typename T> | 569 template<typename T> |
497 class DefaultTraceTrait<T, false> { | 570 class DefaultTraceTrait<T, false> { |
498 public: | 571 public: |
499 static void mark(Visitor* visitor, const T* t) | 572 static void mark(Visitor* visitor, const T* t) |
500 { | 573 { |
501 // Default mark method of the trait just calls the two-argument mark | 574 // Default mark method of the trait just calls the two-argument mark |
502 // method on the visitor. The second argument is the static trace method | 575 // method on the visitor. The second argument is the static trace method |
503 // of the trait, which by default calls the instance method | 576 // of the trait, which by default calls the instance method |
504 // trace(Visitor*) on the object. | 577 // trace(Visitor*) on the object. |
| 578 // |
| 579 // If the trait allows it, invoke the trace callback right here on the |
| 580 // not-yet-marked object. |
| 581 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { |
| 582 if (visitor->ensureMarked(t)) |
| 583 TraceTrait<T>::trace(visitor, const_cast<T*>(t)); |
| 584 return; |
| 585 } |
505 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 586 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
506 } | 587 } |
507 | 588 |
508 #if ENABLE(ASSERT) | 589 #if ENABLE(ASSERT) |
509 static void checkGCInfo(Visitor* visitor, const T* t) | 590 static void checkGCInfo(Visitor* visitor, const T* t) |
510 { | 591 { |
511 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); | 592 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); |
512 } | 593 } |
513 #endif | 594 #endif |
514 }; | 595 }; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 | 666 |
586 class PLATFORM_EXPORT GarbageCollectedMixin { | 667 class PLATFORM_EXPORT GarbageCollectedMixin { |
587 public: | 668 public: |
588 virtual void adjustAndMark(Visitor*) const = 0; | 669 virtual void adjustAndMark(Visitor*) const = 0; |
589 virtual bool isHeapObjectAlive(Visitor*) const = 0; | 670 virtual bool isHeapObjectAlive(Visitor*) const = 0; |
590 virtual void trace(Visitor*) { } | 671 virtual void trace(Visitor*) { } |
591 }; | 672 }; |
592 | 673 |
593 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 674 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
594 public: \ | 675 public: \ |
595 virtual void adjustAndMark(blink::Visitor* visitor) const override \ | 676 virtual void adjustAndMark(blink::Visitor* visitor) const override \ |
596 { \ | 677 { \ |
597 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ | 678 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ |
598 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected
ObjectsCanHaveGarbageCollectedMixins); \ | 679 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected
ObjectsCanHaveGarbageCollectedMixins); \ |
| 680 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<TYPE>::value) {
\ |
| 681 if (visitor->ensureMarked(static_cast<const TYPE*>(this)))
\ |
| 682 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this));
\ |
| 683 return;
\ |
| 684 }
\ |
599 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ | 685 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ |
600 } \ | 686 } \ |
601 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override \ | 687 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override
\ |
602 { \ | 688 { \ |
603 return visitor->isAlive(this); \ | 689 return visitor->isAlive(this); \ |
604 } \ | 690 } \ |
605 private: | 691 private: |
606 | 692 |
607 #if ENABLE(OILPAN) | 693 #if ENABLE(OILPAN) |
608 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) | 694 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) |
609 #else | 695 #else |
610 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) | 696 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) |
611 #endif | 697 #endif |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 struct GCInfoTrait { | 741 struct GCInfoTrait { |
656 static const GCInfo* get() | 742 static const GCInfo* get() |
657 { | 743 { |
658 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 744 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
659 } | 745 } |
660 }; | 746 }; |
661 | 747 |
662 } | 748 } |
663 | 749 |
664 #endif | 750 #endif |
OLD | NEW |