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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 #if ENABLE(ASSERT) | 184 #if ENABLE(ASSERT) |
185 static void checkGCInfo(Visitor* visitor, const T* t) | 185 static void checkGCInfo(Visitor* visitor, const T* t) |
186 { | 186 { |
187 DefaultTraceTrait<T>::checkGCInfo(visitor, t); | 187 DefaultTraceTrait<T>::checkGCInfo(visitor, t); |
188 } | 188 } |
189 #endif | 189 #endif |
190 }; | 190 }; |
191 | 191 |
192 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 192 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
193 | 193 |
194 // If ENABLE_EAGER_TRACING_BY_DEFAULT is set to 1, GCed objects will | 194 // If MARKER_EAGER_TRACING is set to 1, a marker thread is allowed |
195 // be eagerly traced by default. A class type can opt out by declaring | 195 // to directly invoke the trace() method of not-as-yet marked objects upon |
196 // a TraceEagerlyTrait<> specialization, mapping the value to 'false' | 196 // marking. If it is set to 0, the |trace()| callback for an object will |
197 // (see the WILL_NOT_BE_EAGERLY_TRACED() macro below.) | 197 // be pushed onto an explicit mark stack, which the marker proceeds to |
198 #define ENABLE_EAGER_TRACING_BY_DEFAULT 0 | 198 // iteratively pop and invoke. The eager scheme enables inlining of a trace() |
| 199 // method inside another, the latter keeps system call stack usage bounded |
| 200 // and under explicit control. |
| 201 // |
| 202 // If eager tracing leads to excessively deep |trace()| call chains (and |
| 203 // the system stack usage that this brings), the marker implementation will |
| 204 // switch to using an explicit mark stack. Recursive and deep object graphs |
| 205 // are uncommon for Blink objects. |
| 206 // |
| 207 // A class type can opt out of eager tracing by declaring a TraceEagerlyTrait<> |
| 208 // specialization, mapping the trait's |value| to |false| (see the |
| 209 // WILL_NOT_BE_EAGERLY_TRACED() macros below.) For Blink, this is done for |
| 210 // the small set of GCed classes that are directly recursive. |
| 211 #define MARKER_EAGER_TRACING 1 |
199 | 212 |
200 // DISABLE_ALL_EAGER_TRACING provides the "kill switch" for eager | 213 // The TraceEagerlyTrait<T> trait controls whether or not a class |
201 // tracing; setting it to 1 will disable the use of eager tracing | 214 // (and its subclasses) should be eagerly traced or not. |
202 // entirely. That is, eager tracing is disabled even if traits have | |
203 // been declared. | |
204 #define DISABLE_ALL_EAGER_TRACING 0 | |
205 | |
206 // If TraceEagerlyTrait<T>::value is true, then the marker thread should | |
207 // invoke trace() on not-yet-marked objects deriving from class T right | |
208 // away, and not queue their trace callbacks on its marker stack. | |
209 // | 215 // |
210 // Specific template specializations of TraceEagerlyTrait<T> can be used | 216 // If |TraceEagerlyTrait<T>::value| is |true|, then the marker thread |
211 // to declare that eager tracing should always be used when tracing over | 217 // should invoke |trace()| on not-yet-marked objects deriving from class T |
212 // GCed objects with class type T. If the trait's boolean 'value' is | 218 // right away, and not queue their trace callbacks on its marker stack, |
213 // mapped to 'true' that is; declare it as 'false' to disable eager tracing. | 219 // which it will do if |value| is |false|. |
214 // | 220 // |
215 // The trait can be declared to enable/disable eager tracing for a class T | 221 // The trait can be declared to enable/disable eager tracing for a class T |
216 // and any of its subclasses, or just to the class T (but none of its subclasses
.) | 222 // and any of its subclasses, or just to the class T, but none of its |
| 223 // subclasses. |
217 // | 224 // |
218 template<typename T, typename Enabled = void> | 225 template<typename T, typename Enabled = void> |
219 class TraceEagerlyTrait { | 226 class TraceEagerlyTrait { |
220 public: | 227 public: |
221 static const bool value = ENABLE_EAGER_TRACING_BY_DEFAULT; | 228 static const bool value = MARKER_EAGER_TRACING; |
222 }; | 229 }; |
223 | 230 |
224 #define WILL_BE_EAGERLY_TRACED(TYPE)
\ | |
225 template<typename U>
\ | |
226 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu
e>::Type> { \ | |
227 public:
\ | |
228 static const bool value = true;
\ | |
229 } | |
230 | |
231 #define WILL_NOT_BE_EAGERLY_TRACED(TYPE)
\ | 231 #define WILL_NOT_BE_EAGERLY_TRACED(TYPE)
\ |
232 template<typename U>
\ | 232 template<typename T>
\ |
233 class TraceEagerlyTrait<U, typename WTF::EnableIf<WTF::IsSubclass<U, TYPE>::valu
e>::Type> { \ | 233 class TraceEagerlyTrait<T, typename WTF::EnableIf<WTF::IsSubclass<T, TYPE>::valu
e>::Type> { \ |
234 public:
\ | 234 public:
\ |
235 static const bool value = false;
\ | 235 static const bool value = false;
\ |
236 } | 236 } |
237 | 237 |
238 // Limit eager tracing to only apply to TYPE (but not any of its subclasses.) | 238 // Disable eager tracing for TYPE, but not any of its subclasses. |
239 #define WILL_BE_EAGERLY_TRACED_CLASS(TYPE) \ | |
240 template<> \ | |
241 class TraceEagerlyTrait<TYPE> { \ | |
242 public: \ | |
243 static const bool value = true; \ | |
244 } | |
245 | |
246 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \ | 239 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \ |
247 template<> \ | 240 template<> \ |
248 class TraceEagerlyTrait<TYPE> { \ | 241 class TraceEagerlyTrait<TYPE> { \ |
249 public: \ | 242 public: \ |
250 static const bool value = false; \ | 243 static const bool value = false; \ |
251 } | 244 } |
252 | 245 |
253 // Set to 1 if you want collections to be eagerly traced regardless | |
254 // of whether the elements are eagerly traceable or not. | |
255 #define ENABLE_EAGER_HEAP_COLLECTION_TRACING ENABLE_EAGER_TRACING_BY_DEFAULT | |
256 | |
257 #if ENABLE_EAGER_HEAP_COLLECTION_TRACING | |
258 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) true | |
259 #else | |
260 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) TraceEagerlyTrait<Type>::value | |
261 #endif | |
262 | |
263 template<typename Collection> | 246 template<typename Collection> |
264 struct OffHeapCollectionTraceTrait; | 247 struct OffHeapCollectionTraceTrait; |
265 | 248 |
266 template<typename T> | 249 template<typename T> |
267 struct ObjectAliveTrait { | 250 struct ObjectAliveTrait { |
268 static bool isHeapObjectAlive(Visitor*, T*); | 251 static bool isHeapObjectAlive(Visitor*, T*); |
269 }; | 252 }; |
270 | 253 |
271 // Visitor is used to traverse the Blink object graph. Used for the | 254 // Visitor is used to traverse the Blink object graph. Used for the |
272 // marking phase of the mark-sweep garbage collector. | 255 // marking phase of the mark-sweep garbage collector. |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 public: | 562 public: |
580 static void mark(Visitor* visitor, const T* t) | 563 static void mark(Visitor* visitor, const T* t) |
581 { | 564 { |
582 // Default mark method of the trait just calls the two-argument mark | 565 // Default mark method of the trait just calls the two-argument mark |
583 // method on the visitor. The second argument is the static trace method | 566 // method on the visitor. The second argument is the static trace method |
584 // of the trait, which by default calls the instance method | 567 // of the trait, which by default calls the instance method |
585 // trace(Visitor*) on the object. | 568 // trace(Visitor*) on the object. |
586 // | 569 // |
587 // If the trait allows it, invoke the trace callback right here on the | 570 // If the trait allows it, invoke the trace callback right here on the |
588 // not-yet-marked object. | 571 // not-yet-marked object. |
589 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { | 572 if (TraceEagerlyTrait<T>::value) { |
590 // Protect against too deep trace call chains, and the | 573 // Protect against too deep trace call chains, and the |
591 // unbounded system stack usage they can bring about. | 574 // unbounded system stack usage they can bring about. |
592 // | 575 // |
593 // Assert against deep stacks so as to flush them out, | 576 // Assert against deep stacks so as to flush them out, |
594 // but test and appropriately handle them should they occur | 577 // but test and appropriately handle them should they occur |
595 // in release builds. | 578 // in release builds. |
596 ASSERT(visitor->canTraceEagerly()); | 579 ASSERT(visitor->canTraceEagerly()); |
597 if (LIKELY(visitor->canTraceEagerly())) { | 580 if (LIKELY(visitor->canTraceEagerly())) { |
598 if (visitor->ensureMarked(t)) { | 581 if (visitor->ensureMarked(t)) { |
599 visitor->incrementTraceDepth(); | 582 visitor->incrementTraceDepth(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 virtual bool isHeapObjectAlive(Visitor*) const = 0; | 673 virtual bool isHeapObjectAlive(Visitor*) const = 0; |
691 virtual void trace(Visitor*) { } | 674 virtual void trace(Visitor*) { } |
692 }; | 675 }; |
693 | 676 |
694 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 677 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
695 public: \ | 678 public: \ |
696 virtual void adjustAndMark(blink::Visitor* visitor) const override \ | 679 virtual void adjustAndMark(blink::Visitor* visitor) const override \ |
697 { \ | 680 { \ |
698 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ | 681 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type,
blink::GarbageCollected> IsSubclassOfGarbageCollected; \ |
699 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected
ObjectsCanHaveGarbageCollectedMixins); \ | 682 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected
ObjectsCanHaveGarbageCollectedMixins); \ |
700 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<TYPE>::value) {
\ | 683 if (TraceEagerlyTrait<TYPE>::value) {
\ |
701 if (visitor->ensureMarked(static_cast<const TYPE*>(this)))
\ | 684 if (visitor->ensureMarked(static_cast<const TYPE*>(this)))
\ |
702 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this));
\ | 685 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this));
\ |
703 return;
\ | 686 return;
\ |
704 }
\ | 687 }
\ |
705 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ | 688 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>::
trace); \ |
706 } \ | 689 } \ |
707 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override
\ | 690 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override
\ |
708 { \ | 691 { \ |
709 return visitor->isAlive(this); \ | 692 return visitor->isAlive(this); \ |
710 } \ | 693 } \ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 struct GCInfoTrait { | 743 struct GCInfoTrait { |
761 static const GCInfo* get() | 744 static const GCInfo* get() |
762 { | 745 { |
763 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 746 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
764 } | 747 } |
765 }; | 748 }; |
766 | 749 |
767 } | 750 } |
768 | 751 |
769 #endif | 752 #endif |
OLD | NEW |