Chromium Code Reviews| 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 | 190 // If MARKER_EAGER_TRACING is set to 1, a marker thread is allowed |
| 191 // be eagerly traced by default. A class type can opt out by declaring | 191 // to directly invoke the trace() method of not-as-yet marked objects upon |
| 192 // a TraceEagerlyTrait<> specialization, mapping the value to 'false' | 192 // marking. If it is set to 0, the |trace()| callback for an object will |
| 193 // (see the WILL_NOT_BE_EAGERLY_TRACED() macro below.) | 193 // be pushed onto an explicit mark stack, which the marker proceeds to |
| 194 #define ENABLE_EAGER_TRACING_BY_DEFAULT 0 | 194 // iteratively pop and invoke. The eager scheme enables inlining of a trace() |
| 195 // method inside another, the latter keeps system call stack usage bounded | |
| 196 // and under explicit control. | |
| 197 // | |
| 198 // If eager tracing leads to excessively deep |trace()| call chains (and | |
| 199 // the system stack usage that this brings), the marker implementation will | |
| 200 // switch to using an explicit mark stack. Recursive and deep object graphs | |
| 201 // are uncommon for Blink objects. | |
| 202 // | |
| 203 // A class type can opt out of eager tracing by declaring a TraceEagerlyTrait<> | |
| 204 // specialization, mapping the trait's |value| to |false| (see the | |
| 205 // WILL_NOT_BE_EAGERLY_TRACED() macros below.) For Blink, this is done for | |
| 206 // the small set of GCed classes that are directly recursive. | |
| 207 #define MARKER_EAGER_TRACING 1 | |
| 195 | 208 |
| 196 // DISABLE_ALL_EAGER_TRACING provides the "kill switch" for eager | 209 // The TraceEagerlyTrait<T> trait controls whether or not a class |
| 197 // tracing; setting it to 1 will disable the use of eager tracing | 210 // (and its subclasses) should be eagerly traced or not. |
| 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 // | 211 // |
| 206 // Specific template specializations of TraceEagerlyTrait<T> can be used | 212 // If |TraceEagerlyTrait<T>::value| is |true|, then the marker thread |
| 207 // to declare that eager tracing should always be used when tracing over | 213 // should invoke |trace()| on not-yet-marked objects deriving from class T |
| 208 // GCed objects with class type T. If the trait's boolean 'value' is | 214 // right away, and not queue their trace callbacks on its marker stack, |
| 209 // mapped to 'true' that is; declare it as 'false' to disable eager tracing. | 215 // which it will do if |value| is |false|. |
| 210 // | 216 // |
| 211 // The trait can be declared to enable/disable eager tracing for a class T | 217 // 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 .) | 218 // and any of its subclasses, or just to the class T, but none of its |
| 219 // subclasses. | |
| 213 // | 220 // |
| 214 template<typename T, typename Enabled = void> | 221 template<typename T, typename Enabled = void> |
| 215 class TraceEagerlyTrait { | 222 class TraceEagerlyTrait { |
| 216 public: | 223 public: |
| 217 static const bool value = ENABLE_EAGER_TRACING_BY_DEFAULT; | 224 static const bool value = MARKER_EAGER_TRACING; |
| 218 }; | 225 }; |
| 219 | 226 |
| 220 #define WILL_BE_EAGERLY_TRACED(TYPE) \ | 227 #define WILL_BE_EAGERLY_TRACED(TYPE) \ |
|
haraken
2014/12/09 15:47:24
This macro is no longer needed probably?
sof
2014/12/09 21:55:37
No particular harm in having it around, but now un
| |
| 221 template<typename U> \ | 228 template<typename T> \ |
| 222 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu e>::Type> { \ | 229 class TraceEagerlyTrait<T, typename WTF::EnableIf<WTF::IsSubclass<T, TYPE>::valu e>::Type> { \ |
| 223 public: \ | 230 public: \ |
| 224 static const bool value = true; \ | 231 static const bool value = true; \ |
| 225 } | 232 } |
| 226 | 233 |
| 227 #define WILL_NOT_BE_EAGERLY_TRACED(TYPE) \ | 234 #define WILL_NOT_BE_EAGERLY_TRACED(TYPE) \ |
|
haraken
2014/12/09 15:47:24
Ditto.
sof
2014/12/09 21:55:37
Kept, as it serves a purpose.
| |
| 228 template<typename U> \ | 235 template<typename T> \ |
| 229 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu e>::Type> { \ | 236 class TraceEagerlyTrait<T, typename WTF::EnableIf<WTF::IsSubclass<T, TYPE>::valu e>::Type> { \ |
| 230 public: \ | 237 public: \ |
| 231 static const bool value = false; \ | 238 static const bool value = false; \ |
| 232 } | 239 } |
| 233 | 240 |
| 234 // Limit eager tracing to only apply to TYPE (but not any of its subclasses.) | 241 // Enable eager tracing for TYPE, but not any of its subclasses. |
| 235 #define WILL_BE_EAGERLY_TRACED_CLASS(TYPE) \ | 242 #define WILL_BE_EAGERLY_TRACED_CLASS(TYPE) \ |
|
haraken
2014/12/09 15:47:24
Ditto. If it's unused, we might want to drop this.
sof
2014/12/09 21:55:37
Retired also.
| |
| 236 template<> \ | 243 template<> \ |
| 237 class TraceEagerlyTrait<TYPE> { \ | 244 class TraceEagerlyTrait<TYPE> { \ |
| 238 public: \ | 245 public: \ |
| 239 static const bool value = true; \ | 246 static const bool value = true; \ |
| 240 } | 247 } |
| 241 | 248 |
| 249 // Disable eager tracing for TYPE, but not any of its subclasses. | |
| 242 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \ | 250 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \ |
| 243 template<> \ | 251 template<> \ |
| 244 class TraceEagerlyTrait<TYPE> { \ | 252 class TraceEagerlyTrait<TYPE> { \ |
| 245 public: \ | 253 public: \ |
| 246 static const bool value = false; \ | 254 static const bool value = false; \ |
| 247 } | 255 } |
| 248 | 256 |
| 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 | |
| 259 template<typename Collection> | 257 template<typename Collection> |
| 260 struct OffHeapCollectionTraceTrait; | 258 struct OffHeapCollectionTraceTrait; |
| 261 | 259 |
| 262 template<typename T> | 260 template<typename T> |
| 263 struct ObjectAliveTrait { | 261 struct ObjectAliveTrait { |
| 264 static bool isHeapObjectAlive(Visitor*, T*); | 262 static bool isHeapObjectAlive(Visitor*, T*); |
| 265 }; | 263 }; |
| 266 | 264 |
| 267 // Visitor is used to traverse the Blink object graph. Used for the | 265 // Visitor is used to traverse the Blink object graph. Used for the |
| 268 // marking phase of the mark-sweep garbage collector. | 266 // marking phase of the mark-sweep garbage collector. |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 | 503 |
| 506 #if ENABLE(GC_PROFILE_MARKING) | 504 #if ENABLE(GC_PROFILE_MARKING) |
| 507 void setHostInfo(void* object, const String& name) | 505 void setHostInfo(void* object, const String& name) |
| 508 { | 506 { |
| 509 m_hostObject = object; | 507 m_hostObject = object; |
| 510 m_hostName = name; | 508 m_hostName = name; |
| 511 } | 509 } |
| 512 #endif | 510 #endif |
| 513 | 511 |
| 514 inline bool canTraceEagerly() const { return m_traceDepth < kMaxEagerTraceDe pth; } | 512 inline bool canTraceEagerly() const { return m_traceDepth < kMaxEagerTraceDe pth; } |
| 515 inline void incrementTraceDepth() { m_traceDepth++; } | 513 inline void incrementTraceDepth() { m_traceDepth++; } |
|
Erik Corry
2014/12/09 15:49:02
Perhaps not in this CL, but it would be great to t
sof
2014/12/09 15:56:40
Numbers from
https://docs.google.com/spreadshe
| |
| 516 inline void decrementTraceDepth() { ASSERT(m_traceDepth > 0); m_traceDepth-- ; } | 514 inline void decrementTraceDepth() { ASSERT(m_traceDepth > 0); m_traceDepth-- ; } |
| 517 | 515 |
| 518 protected: | 516 protected: |
| 519 Visitor() | 517 Visitor() |
| 520 : m_traceDepth(0) | 518 : m_traceDepth(0) |
| 521 { | 519 { |
| 522 } | 520 } |
| 523 | 521 |
| 524 virtual void registerWeakCell(void**, WeakPointerCallback) = 0; | 522 virtual void registerWeakCell(void**, WeakPointerCallback) = 0; |
| 525 #if ENABLE(GC_PROFILE_MARKING) | 523 #if ENABLE(GC_PROFILE_MARKING) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 586 public: | 584 public: |
| 587 static void mark(Visitor* visitor, const T* t) | 585 static void mark(Visitor* visitor, const T* t) |
| 588 { | 586 { |
| 589 // Default mark method of the trait just calls the two-argument mark | 587 // Default mark method of the trait just calls the two-argument mark |
| 590 // method on the visitor. The second argument is the static trace method | 588 // method on the visitor. The second argument is the static trace method |
| 591 // of the trait, which by default calls the instance method | 589 // of the trait, which by default calls the instance method |
| 592 // trace(Visitor*) on the object. | 590 // trace(Visitor*) on the object. |
| 593 // | 591 // |
| 594 // If the trait allows it, invoke the trace callback right here on the | 592 // If the trait allows it, invoke the trace callback right here on the |
| 595 // not-yet-marked object. | 593 // not-yet-marked object. |
| 596 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { | 594 if (TraceEagerlyTrait<T>::value) { |
| 597 // Protect against too deep trace call chains, and the | 595 // Protect against too deep trace call chains, and the |
| 598 // unbounded system stack usage they can bring about. | 596 // unbounded system stack usage they can bring about. |
| 599 // | 597 // |
| 600 // Assert against deep stacks so as to flush them out, | 598 // Assert against deep stacks so as to flush them out, |
| 601 // but test and appropriately handle them should they occur | 599 // but test and appropriately handle them should they occur |
| 602 // in release builds. | 600 // in release builds. |
| 603 ASSERT(visitor->canTraceEagerly()); | 601 ASSERT(visitor->canTraceEagerly()); |
| 604 if (LIKELY(visitor->canTraceEagerly())) { | 602 if (LIKELY(visitor->canTraceEagerly())) { |
| 605 if (visitor->ensureMarked(t)) { | 603 if (visitor->ensureMarked(t)) { |
| 606 visitor->incrementTraceDepth(); | 604 visitor->incrementTraceDepth(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 virtual bool isHeapObjectAlive(Visitor*) const = 0; | 695 virtual bool isHeapObjectAlive(Visitor*) const = 0; |
| 698 virtual void trace(Visitor*) { } | 696 virtual void trace(Visitor*) { } |
| 699 }; | 697 }; |
| 700 | 698 |
| 701 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 699 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
| 702 public: \ | 700 public: \ |
| 703 virtual void adjustAndMark(blink::Visitor* visitor) const override \ | 701 virtual void adjustAndMark(blink::Visitor* visitor) const override \ |
| 704 { \ | 702 { \ |
| 705 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, blink::GarbageCollected> IsSubclassOfGarbageCollected; \ | 703 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, blink::GarbageCollected> IsSubclassOfGarbageCollected; \ |
| 706 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected ObjectsCanHaveGarbageCollectedMixins); \ | 704 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected ObjectsCanHaveGarbageCollectedMixins); \ |
| 707 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<TYPE>::value) { \ | 705 if (TraceEagerlyTrait<TYPE>::value) { \ |
| 708 if (visitor->ensureMarked(static_cast<const TYPE*>(this))) \ | 706 if (visitor->ensureMarked(static_cast<const TYPE*>(this))) \ |
| 709 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \ | 707 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \ |
| 710 return; \ | 708 return; \ |
| 711 } \ | 709 } \ |
| 712 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \ | 710 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \ |
| 713 } \ | 711 } \ |
| 714 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override \ | 712 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override \ |
| 715 { \ | 713 { \ |
| 716 return visitor->isAlive(this); \ | 714 return visitor->isAlive(this); \ |
| 717 } \ | 715 } \ |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 struct GCInfoTrait { | 766 struct GCInfoTrait { |
| 769 static const GCInfo* get() | 767 static const GCInfo* get() |
| 770 { | 768 { |
| 771 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 769 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
| 772 } | 770 } |
| 773 }; | 771 }; |
| 774 | 772 |
| 775 } | 773 } |
| 776 | 774 |
| 777 #endif | 775 #endif |
| OLD | NEW |