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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |