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

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

Issue 765673004: Oilpan: support eager tracing of objects when marking. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Re-introduce TraceEagerly 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
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 TraceEagerlyTrait<T>::value is true, then the marker thread should
191 // invoke trace() on unmarked objects deriving from class T right away,
192 // and not queue its trace callback on the marker stack.
193 template<typename T> class TraceEagerlyTrait;
194
195 // Specific template specializations of TraceEagerlyTrait<T> can be used
196 // to declare that eager tracing should always be used when tracing over
197 // GCed objects with class type T. If the trait's boolean 'value' is
198 // mapped to 'true' that is; declare it as 'false' to disable eager tracing.
199 //
200 // Should you want to declare that a class T and all its derived objects,
201 // should all be eagerly traced - regardless of the particular class type
202 // they end up being traced over - make T derive/inherit from the empty
203 // class TraceEagerly.
204 //
205 // To express the opposite, that a class T and its derived classes should
206 // never be eagerly traced, use TraceNonEagerly. This only makes sense
207 // if enable eager tracing by default (see ENABLE_EAGER_TRACING_BY_DEFAULT
208 // below.)
209 class TraceEagerly { };
210 class TraceNonEagerly { };
211
212 // If ENABLE_EAGER_TRACING_BY_DEFAULT is set to 1, GCed objects will
213 // be eagerly traced by default. A class type can opt out by declaring
214 // a TraceEagerlyTrait<> specialization, mapping the value to 'false'
215 // (see the WILL_NOT_BE_EAGERLY_TRACED() macro below), or derive
216 // from the TraceNonEagerly class.
217 #define ENABLE_EAGER_TRACING_BY_DEFAULT 0
218
219 // DISABLE_ALL_EAGER_TRACING provides the "kill switch" for eager
220 // tracing; setting it to 1 will disable the use of eager tracing
221 // entirely. That is, eager tracing is disabled even if traits have
222 // been declared or types derive from TraceEagerly.
223 #define DISABLE_ALL_EAGER_TRACING 0
224
225 // If TraceEagerlyTrait<T>::value is true, then the marker thread should
226 // invoke trace() on unmarked objects deriving from class T right away,
227 // and not queue its trace callback on the marker stack.
228 template<typename T>
229 class TraceEagerlyTrait {
230 typedef typename WTF::RemoveConst<T>::Type NonConstType;
231 typedef WTF::IsSubclass<NonConstType, TraceEagerly> TraceEagerlySubclass;
232 typedef WTF::IsSubclass<NonConstType, TraceNonEagerly> TraceNonEagerlySubcla ss;
233 public:
234 static const bool value = (DISABLE_ALL_EAGER_TRACING || TraceNonEagerlySubcl ass::value) ? false : (ENABLE_EAGER_TRACING_BY_DEFAULT || TraceEagerlySubclass:: value);
235 };
236
237 template<typename T>
238 class TraceEagerlyTrait<Member<T>> {
239 public:
240 static const bool value = TraceEagerlyTrait<T>::value;
241 };
242
243 template<typename T>
244 class TraceEagerlyTrait<WeakMember<T>> {
245 public:
246 static const bool value = TraceEagerlyTrait<T>::value;
247 };
248
249 #if ENABLE(OILPAN)
250 #define WILL_BE_EAGERLY_TRACED(Type) \
251 template<> \
252 class TraceEagerlyTrait<Type> { \
253 public: \
254 static const bool value = true; \
255 }
256 #define WILL_NOT_BE_EAGERLY_TRACED(Type) \
257 template<> \
258 class TraceEagerlyTrait<Type> { \
259 public: \
260 static const bool value = false; \
261 }
262 #else
263 #define WILL_BE_EAGERLY_TRACED(Type)
264 #define WILL_NOT_BE_EAGERLY_TRACED(Type)
265 #endif
266
267 // Set to 1 if you want collections to be eagerly traced regardless
268 // of whether the elements are eagerly traceable or not.
269 #define ENABLE_EAGER_HEAP_COLLECTION_TRACING ENABLE_EAGER_TRACING_BY_DEFAULT
270
271 #if ENABLE_EAGER_HEAP_COLLECTION_TRACING
272 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) true
273 #else
274 #define IS_EAGERLY_TRACED_HEAP_COLLECTION(Type) TraceEagerlyTrait<Type>::value
275 #endif
276
190 template<typename Collection> 277 template<typename Collection>
191 struct OffHeapCollectionTraceTrait; 278 struct OffHeapCollectionTraceTrait;
192 279
193 template<typename T> 280 template<typename T>
194 struct ObjectAliveTrait { 281 struct ObjectAliveTrait {
195 static bool isHeapObjectAlive(Visitor*, T*); 282 static bool isHeapObjectAlive(Visitor*, T*);
196 }; 283 };
197 284
198 // Visitor is used to traverse the Blink object graph. Used for the 285 // Visitor is used to traverse the Blink object graph. Used for the
199 // marking phase of the mark-sweep garbage collector. 286 // marking phase of the mark-sweep garbage collector.
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 template<typename T> void trace(const WeakPtr<T>&) { } 409 template<typename T> void trace(const WeakPtr<T>&) { }
323 #endif 410 #endif
324 411
325 // This method marks an object and adds it to the set of objects 412 // This method marks an object and adds it to the set of objects
326 // that should have their trace method called. Since not all 413 // that should have their trace method called. Since not all
327 // objects have vtables we have to have the callback as an 414 // objects have vtables we have to have the callback as an
328 // explicit argument, but we can use the templated one-argument 415 // explicit argument, but we can use the templated one-argument
329 // mark method above to automatically provide the callback 416 // mark method above to automatically provide the callback
330 // function. 417 // function.
331 virtual void mark(const void*, TraceCallback) = 0; 418 virtual void mark(const void*, TraceCallback) = 0;
419
420 template<typename T>void markNoTracing(const T* pointer) { mark(pointer, rei nterpret_cast<TraceCallback>(0)); }
kouhei (in TOK) 2014/11/28 01:00:57 insert space.
sof 2014/12/01 10:59:54 Done.
332 void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<Tra ceCallback>(0)); } 421 void markNoTracing(const void* pointer) { mark(pointer, reinterpret_cast<Tra ceCallback>(0)); }
333 void markNoTracing(HeapObjectHeader* header) { mark(header, reinterpret_cast <TraceCallback>(0)); } 422 void markNoTracing(HeapObjectHeader* header) { mark(header, reinterpret_cast <TraceCallback>(0)); }
334 void markNoTracing(FinalizedHeapObjectHeader* header) { mark(header, reinter pret_cast<TraceCallback>(0)); } 423 void markNoTracing(FinalizedHeapObjectHeader* header) { mark(header, reinter pret_cast<TraceCallback>(0)); }
335 424
336 // Used to mark objects during conservative scanning. 425 // Used to mark objects during conservative scanning.
337 virtual void mark(HeapObjectHeader*, TraceCallback) = 0; 426 virtual void mark(HeapObjectHeader*, TraceCallback) = 0;
338 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0; 427 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0;
339 428
340 // Used to delay the marking of objects until the usual marking 429 // Used to delay the marking of objects until the usual marking
341 // including emphemeron iteration is done. This is used to delay 430 // including emphemeron iteration is done. This is used to delay
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 { 476 {
388 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>); 477 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>);
389 } 478 }
390 479
391 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall back) = 0; 480 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall back) = 0;
392 #if ENABLE(ASSERT) 481 #if ENABLE(ASSERT)
393 virtual bool weakTableRegistered(const void*) = 0; 482 virtual bool weakTableRegistered(const void*) = 0;
394 #endif 483 #endif
395 484
396 virtual bool isMarked(const void*) = 0; 485 virtual bool isMarked(const void*) = 0;
486 virtual bool ensureMarked(const void*) = 0;
397 487
398 template<typename T> inline bool isAlive(T* obj) 488 template<typename T> inline bool isAlive(T* obj)
399 { 489 {
400 // Check that we actually know the definition of T when tracing. 490 // Check that we actually know the definition of T when tracing.
401 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing ); 491 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing );
402 // The strongification of collections relies on the fact that once a 492 // The strongification of collections relies on the fact that once a
403 // collection has been strongified, there is no way that it can contain 493 // collection has been strongified, there is no way that it can contain
404 // non-live entries, so no entries will be removed. Since you can't set 494 // non-live entries, so no entries will be removed. Since you can't set
405 // the mark bit on a null pointer, that means that null pointers are 495 // the mark bit on a null pointer, that means that null pointers are
406 // always 'alive'. 496 // always 'alive'.
407 if (!obj) 497 if (!obj)
408 return true; 498 return true;
409 return ObjectAliveTrait<T>::isHeapObjectAlive(this, obj); 499 return ObjectAliveTrait<T>::isHeapObjectAlive(this, obj);
410 } 500 }
411 template<typename T> inline bool isAlive(const Member<T>& member) 501 template<typename T> inline bool isAlive(const Member<T>& member)
412 { 502 {
413 return isAlive(member.get()); 503 return isAlive(member.get());
414 } 504 }
415 template<typename T> inline bool isAlive(RawPtr<T> ptr) 505 template<typename T> inline bool isAlive(RawPtr<T> ptr)
416 { 506 {
417 return isAlive(ptr.get()); 507 return isAlive(ptr.get());
418 } 508 }
419 509
420 #if ENABLE(ASSERT) 510 #if ENABLE(ASSERT)
421 void checkGCInfo(const void*, const GCInfo*); 511 void checkGCInfo(const void*, const GCInfo*);
422 #endif 512 #endif
423 513
424 // Macro to declare methods needed for each typed heap. 514 // Macro to declare methods needed for each typed heap.
425 #define DECLARE_VISITOR_METHODS(Type) \ 515 #define DECLARE_VISITOR_METHODS(Type) \
426 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ 516 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \
427 virtual void mark(const Type*, TraceCallback) = 0; \ 517 virtual void mark(const Type*, TraceCallback) = 0; \
428 virtual bool isMarked(const Type*) = 0; 518 virtual bool isMarked(const Type*) = 0; \
519 virtual bool ensureMarked(const Type*) = 0;
429 520
430 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) 521 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS)
431 #undef DECLARE_VISITOR_METHODS 522 #undef DECLARE_VISITOR_METHODS
432 523
433 #if ENABLE(GC_PROFILE_MARKING) 524 #if ENABLE(GC_PROFILE_MARKING)
434 void setHostInfo(void* object, const String& name) 525 void setHostInfo(void* object, const String& name)
435 { 526 {
436 m_hostObject = object; 527 m_hostObject = object;
437 m_hostName = name; 528 m_hostName = name;
438 } 529 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 586
496 template<typename T> 587 template<typename T>
497 class DefaultTraceTrait<T, false> { 588 class DefaultTraceTrait<T, false> {
498 public: 589 public:
499 static void mark(Visitor* visitor, const T* t) 590 static void mark(Visitor* visitor, const T* t)
500 { 591 {
501 // Default mark method of the trait just calls the two-argument mark 592 // Default mark method of the trait just calls the two-argument mark
502 // method on the visitor. The second argument is the static trace method 593 // method on the visitor. The second argument is the static trace method
503 // of the trait, which by default calls the instance method 594 // of the trait, which by default calls the instance method
504 // trace(Visitor*) on the object. 595 // trace(Visitor*) on the object.
596 //
597 // If trait allows it, invoke trace callback right here on unmarked obje cts.
598 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) {
599 if (!visitor->ensureMarked(t))
600 TraceTrait<T>::trace(visitor, const_cast<T*>(t));
haraken 2014/11/28 05:20:05 Just recursively tracing an object is not enough f
haraken 2014/11/28 12:39:27 Are you going to address this one? Or is it not a
sof 2014/11/28 12:44:27 I need to make progress on other fronts right now.
sof 2014/12/01 10:59:54 Now addressed, but a gnarlier issue to get right.
601 return;
602 }
505 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); 603 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace);
506 } 604 }
507 605
508 #if ENABLE(ASSERT) 606 #if ENABLE(ASSERT)
509 static void checkGCInfo(Visitor* visitor, const T* t) 607 static void checkGCInfo(Visitor* visitor, const T* t)
510 { 608 {
511 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); 609 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get());
512 } 610 }
513 #endif 611 #endif
514 }; 612 };
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 683
586 class PLATFORM_EXPORT GarbageCollectedMixin { 684 class PLATFORM_EXPORT GarbageCollectedMixin {
587 public: 685 public:
588 virtual void adjustAndMark(Visitor*) const = 0; 686 virtual void adjustAndMark(Visitor*) const = 0;
589 virtual bool isHeapObjectAlive(Visitor*) const = 0; 687 virtual bool isHeapObjectAlive(Visitor*) const = 0;
590 virtual void trace(Visitor*) { } 688 virtual void trace(Visitor*) { }
591 }; 689 };
592 690
593 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ 691 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
594 public: \ 692 public: \
595 virtual void adjustAndMark(blink::Visitor* visitor) const override \ 693 virtual void adjustAndMark(blink::Visitor* visitor) const override \
596 { \ 694 { \
597 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, blink::GarbageCollected> IsSubclassOfGarbageCollected; \ 695 typedef WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<TYPE>::Type, blink::GarbageCollected> IsSubclassOfGarbageCollected; \
598 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected ObjectsCanHaveGarbageCollectedMixins); \ 696 COMPILE_ASSERT(IsSubclassOfGarbageCollected::value, OnlyGarbageCollected ObjectsCanHaveGarbageCollectedMixins); \
697 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<TYPE>::value) { \
698 if (!visitor->ensureMarked(static_cast<const TYPE*>(this))) \
699 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \
700 return; \
701 } \
599 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \ 702 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \
600 } \ 703 } \
601 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override \ 704 virtual bool isHeapObjectAlive(blink::Visitor* visitor) const override \
602 { \ 705 { \
603 return visitor->isAlive(this); \ 706 return visitor->isAlive(this); \
604 } \ 707 } \
605 private: 708 private:
606 709
607 #if ENABLE(OILPAN) 710 #if ENABLE(OILPAN)
608 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI N(TYPE) 711 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI N(TYPE)
609 #else 712 #else
610 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) 713 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE)
611 #endif 714 #endif
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 struct GCInfoTrait { 758 struct GCInfoTrait {
656 static const GCInfo* get() 759 static const GCInfo* get()
657 { 760 {
658 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); 761 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get();
659 } 762 }
660 }; 763 };
661 764
662 } 765 }
663 766
664 #endif 767 #endif
OLDNEW
« Source/platform/heap/HeapTest.cpp ('K') | « Source/platform/heap/HeapTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698