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 |