| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 template<typename T> class GarbageCollected; | 58 template<typename T> class GarbageCollected; |
| 59 template<typename T> class GarbageCollectedFinalized; | 59 template<typename T> class GarbageCollectedFinalized; |
| 60 class GarbageCollectedMixin; | 60 class GarbageCollectedMixin; |
| 61 class GeneralHeapObjectHeader; | 61 class GeneralHeapObjectHeader; |
| 62 class HeapObjectHeader; | 62 class HeapObjectHeader; |
| 63 template<typename T> class Member; | 63 template<typename T> class Member; |
| 64 template<typename T> class WeakMember; | 64 template<typename T> class WeakMember; |
| 65 class Visitor; | 65 class Visitor; |
| 66 | 66 |
| 67 template <typename T> struct IsGarbageCollectedType; | 67 template <typename T> struct IsGarbageCollectedType; |
| 68 #define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \ | 68 #define STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \ |
| 69 COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage) | 69 static_assert(IsGarbageCollectedType<T>::value, ErrorMessage) |
| 70 #define COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, ErrorMessage) \ | 70 #define STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, ErrorMessage) \ |
| 71 COMPILE_ASSERT(!IsGarbageCollectedType<T>::value, ErrorMessage) | 71 static_assert(!IsGarbageCollectedType<T>::value, ErrorMessage) |
| 72 | 72 |
| 73 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct Colle
ctionBackingTraceTrait; | 73 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct Colle
ctionBackingTraceTrait; |
| 74 | 74 |
| 75 // The TraceMethodDelegate is used to convert a trace method for type T to a Tra
ceCallback. | 75 // The TraceMethodDelegate is used to convert a trace method for type T to a Tra
ceCallback. |
| 76 // This allows us to pass a type's trace method as a parameter to the Persistent
Node | 76 // This allows us to pass a type's trace method as a parameter to the Persistent
Node |
| 77 // constructor. The PersistentNode constructor needs the specific trace method d
ue an issue | 77 // constructor. The PersistentNode constructor needs the specific trace method d
ue an issue |
| 78 // with the Windows compiler which instantiates even unused variables. This caus
es problems | 78 // with the Windows compiler which instantiates even unused variables. This caus
es problems |
| 79 // in header files where we have only forward declarations of classes. | 79 // in header files where we have only forward declarations of classes. |
| 80 template<typename T, void (T::*method)(Visitor*)> | 80 template<typename T, void (T::*method)(Visitor*)> |
| 81 struct TraceMethodDelegate { | 81 struct TraceMethodDelegate { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 template<typename T> | 277 template<typename T> |
| 278 void mark(T* t) | 278 void mark(T* t) |
| 279 { | 279 { |
| 280 if (!t) | 280 if (!t) |
| 281 return; | 281 return; |
| 282 #if ENABLE(ASSERT) | 282 #if ENABLE(ASSERT) |
| 283 TraceTrait<T>::checkGCInfo(t); | 283 TraceTrait<T>::checkGCInfo(t); |
| 284 #endif | 284 #endif |
| 285 TraceTrait<T>::mark(toDerived(), t); | 285 TraceTrait<T>::mark(toDerived(), t); |
| 286 | 286 |
| 287 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, AttemptedToMarkNonGarbageCollecte
dObject); | 287 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "attempted to mark non garbage col
lected object"); |
| 288 } | 288 } |
| 289 | 289 |
| 290 // Member version of the one-argument templated trace method. | 290 // Member version of the one-argument templated trace method. |
| 291 template<typename T> | 291 template<typename T> |
| 292 void trace(const Member<T>& t) | 292 void trace(const Member<T>& t) |
| 293 { | 293 { |
| 294 toDerived()->mark(t.get()); | 294 toDerived()->mark(t.get()); |
| 295 } | 295 } |
| 296 | 296 |
| 297 // Fallback method used only when we need to trace raw pointers of T. | 297 // Fallback method used only when we need to trace raw pointers of T. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 311 // WeakMember version of the templated trace method. It doesn't keep | 311 // WeakMember version of the templated trace method. It doesn't keep |
| 312 // the traced thing alive, but will write null to the WeakMember later | 312 // the traced thing alive, but will write null to the WeakMember later |
| 313 // if the pointed-to object is dead. It's lying for this to be const, | 313 // if the pointed-to object is dead. It's lying for this to be const, |
| 314 // but the overloading resolver prioritizes constness too high when | 314 // but the overloading resolver prioritizes constness too high when |
| 315 // picking the correct overload, so all these trace methods have to have | 315 // picking the correct overload, so all these trace methods have to have |
| 316 // the same constness on their argument to allow the type to decide. | 316 // the same constness on their argument to allow the type to decide. |
| 317 template<typename T> | 317 template<typename T> |
| 318 void trace(const WeakMember<T>& t) | 318 void trace(const WeakMember<T>& t) |
| 319 { | 319 { |
| 320 // Check that we actually know the definition of T when tracing. | 320 // Check that we actually know the definition of T when tracing. |
| 321 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); | 321 static_assert(sizeof(T), "we need to know the definition of the type we
are tracing"); |
| 322 registerWeakCell(const_cast<WeakMember<T>&>(t).cell()); | 322 registerWeakCell(const_cast<WeakMember<T>&>(t).cell()); |
| 323 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, AttemptedToWeakTraceNonGarbageCol
lectedObject); | 323 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "cannot weak trace non garbage col
lected object"); |
| 324 } | 324 } |
| 325 | 325 |
| 326 template<typename T> | 326 template<typename T> |
| 327 void traceInCollection(T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongi
fy) | 327 void traceInCollection(T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongi
fy) |
| 328 { | 328 { |
| 329 HashTraits<T>::traceInCollection(toDerived(), t, strongify); | 329 HashTraits<T>::traceInCollection(toDerived(), t, strongify); |
| 330 } | 330 } |
| 331 | 331 |
| 332 // Fallback trace method for part objects to allow individual trace methods | 332 // Fallback trace method for part objects to allow individual trace methods |
| 333 // to trace through a part object with visitor->trace(m_partObject). This | 333 // to trace through a part object with visitor->trace(m_partObject). This |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 template<typename T> void trace(const RawPtr<T>&) { } | 387 template<typename T> void trace(const RawPtr<T>&) { } |
| 388 template<typename T> void trace(const WeakPtr<T>&) { } | 388 template<typename T> void trace(const WeakPtr<T>&) { } |
| 389 | 389 |
| 390 // On non-oilpan builds, it is convenient to allow calling trace on | 390 // On non-oilpan builds, it is convenient to allow calling trace on |
| 391 // WillBeHeap{Vector,Deque}<FooPtrWillBeMember<T>>. | 391 // WillBeHeap{Vector,Deque}<FooPtrWillBeMember<T>>. |
| 392 // Forbid tracing on-heap objects in off-heap collections. | 392 // Forbid tracing on-heap objects in off-heap collections. |
| 393 // This is forbidden because convservative marking cannot identify | 393 // This is forbidden because convservative marking cannot identify |
| 394 // those off-heap collection backing stores. | 394 // those off-heap collection backing stores. |
| 395 template<typename T, size_t inlineCapacity> void trace(const Vector<OwnPtr<T
>, inlineCapacity>& vector) | 395 template<typename T, size_t inlineCapacity> void trace(const Vector<OwnPtr<T
>, inlineCapacity>& vector) |
| 396 { | 396 { |
| 397 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideVector); | 397 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Vector"); |
| 398 } | 398 } |
| 399 template<typename T, size_t inlineCapacity> void trace(const Vector<RefPtr<T
>, inlineCapacity>& vector) | 399 template<typename T, size_t inlineCapacity> void trace(const Vector<RefPtr<T
>, inlineCapacity>& vector) |
| 400 { | 400 { |
| 401 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideVector); | 401 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Vector"); |
| 402 } | 402 } |
| 403 template<typename T, size_t inlineCapacity> void trace(const Vector<RawPtr<T
>, inlineCapacity>& vector) | 403 template<typename T, size_t inlineCapacity> void trace(const Vector<RawPtr<T
>, inlineCapacity>& vector) |
| 404 { | 404 { |
| 405 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideVector); | 405 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Vector"); |
| 406 } | 406 } |
| 407 template<typename T, size_t inlineCapacity> void trace(const Vector<WeakPtr<
T>, inlineCapacity>& vector) | 407 template<typename T, size_t inlineCapacity> void trace(const Vector<WeakPtr<
T>, inlineCapacity>& vector) |
| 408 { | 408 { |
| 409 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideVector); | 409 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Vector"); |
| 410 } | 410 } |
| 411 template<typename T, size_t N> void trace(const Deque<OwnPtr<T>, N>& deque) | 411 template<typename T, size_t N> void trace(const Deque<OwnPtr<T>, N>& deque) |
| 412 { | 412 { |
| 413 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideDeque); | 413 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Deque"); |
| 414 } | 414 } |
| 415 template<typename T, size_t N> void trace(const Deque<RefPtr<T>, N>& deque) | 415 template<typename T, size_t N> void trace(const Deque<RefPtr<T>, N>& deque) |
| 416 { | 416 { |
| 417 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideDeque); | 417 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Deque"); |
| 418 } | 418 } |
| 419 template<typename T, size_t N> void trace(const Deque<RawPtr<T>, N>& deque) | 419 template<typename T, size_t N> void trace(const Deque<RawPtr<T>, N>& deque) |
| 420 { | 420 { |
| 421 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideDeque); | 421 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Deque"); |
| 422 } | 422 } |
| 423 template<typename T, size_t N> void trace(const Deque<WeakPtr<T>, N>& deque) | 423 template<typename T, size_t N> void trace(const Deque<WeakPtr<T>, N>& deque) |
| 424 { | 424 { |
| 425 COMPILE_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, AttemptedToTraceGarbageCollec
tedObjectInsideDeque); | 425 STATIC_ASSERT_IS_NOT_GARBAGE_COLLECTED(T, "cannot trace garbage collecte
d object inside Deque"); |
| 426 } | 426 } |
| 427 #endif | 427 #endif |
| 428 | 428 |
| 429 void markNoTracing(const void* pointer) { toDerived()->mark(pointer, reinter
pret_cast<TraceCallback>(0)); } | 429 void markNoTracing(const void* pointer) { toDerived()->mark(pointer, reinter
pret_cast<TraceCallback>(0)); } |
| 430 void markHeaderNoTracing(HeapObjectHeader* header) { toDerived()->markHeader
(header, reinterpret_cast<TraceCallback>(0)); } | 430 void markHeaderNoTracing(HeapObjectHeader* header) { toDerived()->markHeader
(header, reinterpret_cast<TraceCallback>(0)); } |
| 431 void markHeaderNoTracing(GeneralHeapObjectHeader* header) { toDerived()->mar
kHeader(header, reinterpret_cast<TraceCallback>(0)); } | 431 void markHeaderNoTracing(GeneralHeapObjectHeader* header) { toDerived()->mar
kHeader(header, reinterpret_cast<TraceCallback>(0)); } |
| 432 template<typename T> void markNoTracing(const T* pointer) { toDerived()->mar
k(pointer, reinterpret_cast<TraceCallback>(0)); } | 432 template<typename T> void markNoTracing(const T* pointer) { toDerived()->mar
k(pointer, reinterpret_cast<TraceCallback>(0)); } |
| 433 | 433 |
| 434 template<typename T> inline bool isAlive(T* obj) | 434 template<typename T> inline bool isAlive(T* obj) |
| 435 { | 435 { |
| 436 // Check that we actually know the definition of T when tracing. | 436 // Check that we actually know the definition of T when tracing. |
| 437 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); | 437 static_assert(sizeof(T), "T must be fully defined"); |
| 438 // The strongification of collections relies on the fact that once a | 438 // The strongification of collections relies on the fact that once a |
| 439 // collection has been strongified, there is no way that it can contain | 439 // collection has been strongified, there is no way that it can contain |
| 440 // non-live entries, so no entries will be removed. Since you can't set | 440 // non-live entries, so no entries will be removed. Since you can't set |
| 441 // the mark bit on a null pointer, that means that null pointers are | 441 // the mark bit on a null pointer, that means that null pointers are |
| 442 // always 'alive'. | 442 // always 'alive'. |
| 443 if (!obj) | 443 if (!obj) |
| 444 return true; | 444 return true; |
| 445 return ObjectAliveTrait<T>::isHeapObjectAlive(toDerived(), obj); | 445 return ObjectAliveTrait<T>::isHeapObjectAlive(toDerived(), obj); |
| 446 } | 446 } |
| 447 template<typename T> inline bool isAlive(const Member<T>& member) | 447 template<typename T> inline bool isAlive(const Member<T>& member) |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 virtual void adjustAndMark(Visitor*) const = 0; | 751 virtual void adjustAndMark(Visitor*) const = 0; |
| 752 virtual bool isHeapObjectAlive(Visitor*) const = 0; | 752 virtual bool isHeapObjectAlive(Visitor*) const = 0; |
| 753 virtual void trace(Visitor*) { } | 753 virtual void trace(Visitor*) { } |
| 754 }; | 754 }; |
| 755 | 755 |
| 756 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 756 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
| 757 public: \ | 757 public: \ |
| 758 virtual void adjustAndMark(blink::Visitor* visitor) const override \ | 758 virtual void adjustAndMark(blink::Visitor* visitor) const override \ |
| 759 { \ | 759 { \ |
| 760 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ | 760 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ |
| 761 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected
ObjectsCanHaveGarbageCollectedMixins); \ | 761 static_assert(IsSubclassOfGarbageCollected::value, "only garbage collect
ed objects can have garbage collected mixins"); \ |
| 762 if (TraceEagerlyTrait<TYPE>::value) {
\ | 762 if (TraceEagerlyTrait<TYPE>::value) {
\ |
| 763 if (visitor->ensureMarked(static_cast<const TYPE*>(this)))
\ | 763 if (visitor->ensureMarked(static_cast<const TYPE*>(this)))
\ |
| 764 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this));
\ | 764 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this));
\ |
| 765 return;
\ | 765 return;
\ |
| 766 }
\ | 766 }
\ |
| 767 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ | 767 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ |
| 768 } \ | 768 } \ |
| 769 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override
\ | 769 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override
\ |
| 770 { \ | 770 { \ |
| 771 return visitor->isAlive(this); \ | 771 return visitor->isAlive(this); \ |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 struct GCInfoTrait { | 822 struct GCInfoTrait { |
| 823 static const GCInfo* get() | 823 static const GCInfo* get() |
| 824 { | 824 { |
| 825 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 825 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
| 826 } | 826 } |
| 827 }; | 827 }; |
| 828 | 828 |
| 829 } | 829 } |
| 830 | 830 |
| 831 #endif | 831 #endif |
| OLD | NEW |