Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: Source/platform/heap/Visitor.h

Issue 783823002: Oilpan: enable eager tracing. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: prevent trace depth asserts in HeapTest Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« Source/platform/heap/Handle.h ('K') | « Source/platform/heap/HeapTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698