| 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 |