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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // GCInfo contains meta-data associated with objects allocated in the | 79 // GCInfo contains meta-data associated with objects allocated in the |
80 // Blink heap. This meta-data consists of a function pointer used to | 80 // Blink heap. This meta-data consists of a function pointer used to |
81 // trace the pointers in the object during garbage collection, an | 81 // trace the pointers in the object during garbage collection, an |
82 // indication of whether or not the object needs a finalization | 82 // indication of whether or not the object needs a finalization |
83 // callback, and a function pointer used to finalize the object when | 83 // callback, and a function pointer used to finalize the object when |
84 // the garbage collector determines that the object is no longer | 84 // the garbage collector determines that the object is no longer |
85 // reachable. There is a GCInfo struct for each class that directly | 85 // reachable. There is a GCInfo struct for each class that directly |
86 // inherits from GarbageCollected or GarbageCollectedFinalized. | 86 // inherits from GarbageCollected or GarbageCollectedFinalized. |
87 struct GCInfo { | 87 struct GCInfo { |
88 bool hasFinalizer() const { return m_nonTrivialFinalizer; } | 88 bool hasFinalizer() const { return m_nonTrivialFinalizer; } |
89 const char* m_typeMarker; | |
90 TraceCallback m_trace; | 89 TraceCallback m_trace; |
91 FinalizationCallback m_finalize; | 90 FinalizationCallback m_finalize; |
92 bool m_nonTrivialFinalizer; | 91 bool m_nonTrivialFinalizer; |
93 }; | 92 }; |
94 | 93 |
95 // The FinalizerTraitImpl specifies how to finalize objects. Object | 94 // The FinalizerTraitImpl specifies how to finalize objects. Object |
96 // that inherit from GarbageCollectedFinalized are finalized by | 95 // that inherit from GarbageCollectedFinalized are finalized by |
97 // calling their 'finalize' method which by default will call the | 96 // calling their 'finalize' method which by default will call the |
98 // destructor on the object. | 97 // destructor on the object. |
99 template<typename T, bool isGarbageCollectedFinalized> | 98 template<typename T, bool isGarbageCollectedFinalized> |
(...skipping 19 matching lines...) Expand all Loading... |
119 template<typename T> | 118 template<typename T> |
120 struct FinalizerTrait { | 119 struct FinalizerTrait { |
121 static const bool nonTrivialFinalizer = WTF::IsSubclassOfTemplate<T, Garbage
CollectedFinalized>::value; | 120 static const bool nonTrivialFinalizer = WTF::IsSubclassOfTemplate<T, Garbage
CollectedFinalized>::value; |
122 static void finalize(void* obj) { FinalizerTraitImpl<T, nonTrivialFinalizer>
::finalize(obj); } | 121 static void finalize(void* obj) { FinalizerTraitImpl<T, nonTrivialFinalizer>
::finalize(obj); } |
123 }; | 122 }; |
124 | 123 |
125 // Trait to get the GCInfo structure for types that have their | 124 // Trait to get the GCInfo structure for types that have their |
126 // instances allocated in the Blink garbage-collected heap. | 125 // instances allocated in the Blink garbage-collected heap. |
127 template<typename T> struct GCInfoTrait; | 126 template<typename T> struct GCInfoTrait; |
128 | 127 |
129 template<typename T> | |
130 const char* getTypeMarker() | |
131 { | |
132 return GCInfoTrait<T>::get()->m_typeMarker; | |
133 } | |
134 | |
135 template<typename T> class GarbageCollected; | 128 template<typename T> class GarbageCollected; |
136 class GarbageCollectedMixin; | 129 class GarbageCollectedMixin; |
137 template<typename T, bool = WTF::IsSubclassOfTemplate<T, GarbageCollected>::valu
e> class NeedsAdjustAndMark; | 130 template<typename T, bool = WTF::IsSubclassOfTemplate<T, GarbageCollected>::valu
e> class NeedsAdjustAndMark; |
138 | 131 |
139 template<typename T> | 132 template<typename T> |
140 class NeedsAdjustAndMark<T, true> { | 133 class NeedsAdjustAndMark<T, true> { |
141 public: | 134 public: |
142 static const bool value = false; | 135 static const bool value = false; |
143 }; | 136 }; |
144 | 137 |
(...skipping 25 matching lines...) Expand all Loading... |
170 { | 163 { |
171 static_cast<T*>(self)->trace(visitor); | 164 static_cast<T*>(self)->trace(visitor); |
172 } | 165 } |
173 | 166 |
174 static void mark(Visitor* visitor, const T* t) | 167 static void mark(Visitor* visitor, const T* t) |
175 { | 168 { |
176 DefaultTraceTrait<T>::mark(visitor, t); | 169 DefaultTraceTrait<T>::mark(visitor, t); |
177 } | 170 } |
178 | 171 |
179 #ifndef NDEBUG | 172 #ifndef NDEBUG |
180 static void checkTypeMarker(Visitor* visitor, const T* t) | 173 static void checkGCInfo(Visitor* visitor, const T* t) |
181 { | 174 { |
182 DefaultTraceTrait<T>::checkTypeMarker(visitor, t); | 175 DefaultTraceTrait<T>::checkGCInfo(visitor, t); |
183 } | 176 } |
184 #endif | 177 #endif |
185 }; | 178 }; |
186 | 179 |
187 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 180 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
188 | 181 |
189 template<typename Collection> | 182 template<typename Collection> |
190 struct OffHeapCollectionTraceTrait; | 183 struct OffHeapCollectionTraceTrait; |
191 | 184 |
192 template<typename T> | 185 template<typename T> |
(...skipping 20 matching lines...) Expand all Loading... |
213 // One-argument templated mark method. This uses the static type of | 206 // One-argument templated mark method. This uses the static type of |
214 // the argument to get the TraceTrait. By default, the mark method | 207 // the argument to get the TraceTrait. By default, the mark method |
215 // of the TraceTrait just calls the virtual two-argument mark method on this | 208 // of the TraceTrait just calls the virtual two-argument mark method on this |
216 // visitor, where the second argument is the static trace method of the trai
t. | 209 // visitor, where the second argument is the static trace method of the trai
t. |
217 template<typename T> | 210 template<typename T> |
218 void mark(T* t) | 211 void mark(T* t) |
219 { | 212 { |
220 if (!t) | 213 if (!t) |
221 return; | 214 return; |
222 #ifndef NDEBUG | 215 #ifndef NDEBUG |
223 TraceTrait<T>::checkTypeMarker(this, t); | 216 TraceTrait<T>::checkGCInfo(this, t); |
224 #endif | 217 #endif |
225 TraceTrait<T>::mark(this, t); | 218 TraceTrait<T>::mark(this, t); |
226 } | 219 } |
227 | 220 |
228 // Member version of the one-argument templated trace method. | 221 // Member version of the one-argument templated trace method. |
229 template<typename T> | 222 template<typename T> |
230 void trace(const Member<T>& t) | 223 void trace(const Member<T>& t) |
231 { | 224 { |
232 mark(t.get()); | 225 mark(t.get()); |
233 } | 226 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 355 |
363 virtual bool isMarked(const void*) = 0; | 356 virtual bool isMarked(const void*) = 0; |
364 | 357 |
365 template<typename T> inline bool isAlive(T obj) { return ObjectAliveTrait<T>
::isAlive(this, obj); } | 358 template<typename T> inline bool isAlive(T obj) { return ObjectAliveTrait<T>
::isAlive(this, obj); } |
366 template<typename T> inline bool isAlive(const Member<T>& member) | 359 template<typename T> inline bool isAlive(const Member<T>& member) |
367 { | 360 { |
368 return isAlive(member.get()); | 361 return isAlive(member.get()); |
369 } | 362 } |
370 | 363 |
371 #ifndef NDEBUG | 364 #ifndef NDEBUG |
372 void checkTypeMarker(const void*, const char* marker); | 365 void checkGCInfo(const void*, const GCInfo*); |
373 #endif | 366 #endif |
374 | 367 |
375 // Macro to declare methods needed for each typed heap. | 368 // Macro to declare methods needed for each typed heap. |
376 #define DECLARE_VISITOR_METHODS(Type) \ | 369 #define DECLARE_VISITOR_METHODS(Type) \ |
377 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \ | 370 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ |
378 virtual void mark(const Type*, TraceCallback) = 0; \ | 371 virtual void mark(const Type*, TraceCallback) = 0; \ |
379 virtual bool isMarked(const Type*) = 0; | 372 virtual bool isMarked(const Type*) = 0; |
380 | 373 |
381 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 374 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
382 #undef DECLARE_VISITOR_METHODS | 375 #undef DECLARE_VISITOR_METHODS |
383 | 376 |
384 private: | 377 private: |
385 template<typename T> | 378 template<typename T> |
386 static void handleWeakCell(Visitor* self, void* obj) | 379 static void handleWeakCell(Visitor* self, void* obj) |
387 { | 380 { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 // to the default. Most of them do nothing, since the type in question cannot | 476 // to the default. Most of them do nothing, since the type in question cannot |
484 // point to other heap allocated objects. | 477 // point to other heap allocated objects. |
485 #define ITERATE_DO_NOTHING_TYPES(f) \ | 478 #define ITERATE_DO_NOTHING_TYPES(f) \ |
486 f(uint8_t) \ | 479 f(uint8_t) \ |
487 f(void) | 480 f(void) |
488 | 481 |
489 #define DECLARE_DO_NOTHING_TRAIT(type) \ | 482 #define DECLARE_DO_NOTHING_TRAIT(type) \ |
490 template<> \ | 483 template<> \ |
491 class TraceTrait<type> { \ | 484 class TraceTrait<type> { \ |
492 public: \ | 485 public: \ |
493 static void checkTypeMarker(Visitor*, const void*) { } \ | 486 static void checkGCInfo(Visitor*, const void*) { } \ |
494 static void mark(Visitor* visitor, const type* p) { \ | 487 static void mark(Visitor* visitor, const type* p) { \ |
495 visitor->mark(p, reinterpret_cast<TraceCallback>(0)); \ | 488 visitor->mark(p, reinterpret_cast<TraceCallback>(0)); \ |
496 } \ | 489 } \ |
497 }; \ | 490 }; \ |
498 template<> \ | 491 template<> \ |
499 struct FinalizerTrait<type> { \ | 492 struct FinalizerTrait<type> { \ |
500 static void finalize(void*) { } \ | 493 static void finalize(void*) { } \ |
501 static const bool nonTrivialFinalizer = false; \ | 494 static const bool nonTrivialFinalizer = false; \ |
502 }; \ | 495 }; \ |
503 template<> \ | 496 template<> \ |
504 struct HEAP_EXPORT GCInfoTrait<type> { \ | 497 struct HEAP_EXPORT GCInfoTrait<type> { \ |
505 static const GCInfo* get() \ | 498 static const GCInfo* get() \ |
506 { \ | 499 { \ |
507 return &info; \ | 500 return &info; \ |
508 } \ | 501 } \ |
509 static const GCInfo info; \ | 502 static const GCInfo info; \ |
510 }; | 503 }; |
511 | 504 |
512 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) | 505 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) |
513 | 506 |
514 #undef DECLARE_DO_NOTHING_TRAIT | 507 #undef DECLARE_DO_NOTHING_TRAIT |
515 | 508 |
516 template<typename T> | 509 template<typename T> |
517 class DefaultTraceTrait<T, false> { | 510 class DefaultTraceTrait<T, false> { |
518 public: | 511 public: |
519 // Default implementation of TraceTrait<T>::trace just statically | |
520 // dispatches to the trace method of the class T. | |
521 static void trace(Visitor* visitor, void* self) | |
522 { | |
523 static_cast<T*>(self)->trace(visitor); | |
524 } | |
525 | |
526 static void mark(Visitor* visitor, const T* t) | 512 static void mark(Visitor* visitor, const T* t) |
527 { | 513 { |
528 // Default mark method of the trait just calls the two-argument mark | 514 // Default mark method of the trait just calls the two-argument mark |
529 // method on the visitor. The second argument is the static trace method | 515 // method on the visitor. The second argument is the static trace method |
530 // of the trait, which by default calls the instance method | 516 // of the trait, which by default calls the instance method |
531 // trace(Visitor*) on the object. | 517 // trace(Visitor*) on the object. |
532 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 518 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
533 } | 519 } |
534 | 520 |
535 #ifndef NDEBUG | 521 #ifndef NDEBUG |
536 static void checkTypeMarker(Visitor* visitor, const T* t) | 522 static void checkGCInfo(Visitor* visitor, const T* t) |
537 { | 523 { |
538 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); | 524 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); |
539 } | 525 } |
540 #endif | 526 #endif |
541 }; | 527 }; |
542 | 528 |
543 template<typename T> | 529 template<typename T> |
544 class DefaultTraceTrait<T, true> { | 530 class DefaultTraceTrait<T, true> { |
545 public: | 531 public: |
546 static void mark(Visitor* visitor, const T* self) | 532 static void mark(Visitor* visitor, const T* self) |
547 { | 533 { |
548 self->adjustAndMark(visitor); | 534 self->adjustAndMark(visitor); |
549 } | 535 } |
550 | 536 |
551 #ifndef NDEBUG | 537 #ifndef NDEBUG |
552 static void checkTypeMarker(Visitor*, const T*) { } | 538 static void checkGCInfo(Visitor*, const T*) { } |
553 #endif | 539 #endif |
554 }; | 540 }; |
555 | 541 |
556 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; | 542 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; |
557 | 543 |
558 template<typename T> | 544 template<typename T> |
559 class DefaultObjectAliveTrait<T, false> { | 545 class DefaultObjectAliveTrait<T, false> { |
560 public: | 546 public: |
561 static bool isAlive(Visitor* visitor, T obj) | 547 static bool isAlive(Visitor* visitor, T obj) |
562 { | 548 { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 #if ENABLE(OILPAN) | 611 #if ENABLE(OILPAN) |
626 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) | 612 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) |
627 #else | 613 #else |
628 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) | 614 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) |
629 #endif | 615 #endif |
630 | 616 |
631 template<typename T> | 617 template<typename T> |
632 struct GCInfoAtBase { | 618 struct GCInfoAtBase { |
633 static const GCInfo* get() | 619 static const GCInfo* get() |
634 { | 620 { |
635 static char pseudoTypeMarker = 'a'; | |
636 static const GCInfo gcInfo = { | 621 static const GCInfo gcInfo = { |
637 &pseudoTypeMarker, | |
638 TraceTrait<T>::trace, | 622 TraceTrait<T>::trace, |
639 FinalizerTrait<T>::finalize, | 623 FinalizerTrait<T>::finalize, |
640 FinalizerTrait<T>::nonTrivialFinalizer, | 624 FinalizerTrait<T>::nonTrivialFinalizer, |
641 }; | 625 }; |
642 return &gcInfo; | 626 return &gcInfo; |
643 } | 627 } |
644 }; | 628 }; |
645 | 629 |
646 template<typename T> class GarbageCollected; | 630 template<typename T> class GarbageCollected; |
647 template<typename T, bool = WTF::IsSubclassOfTemplate<T, GarbageCollected>::valu
e> struct GetGarbageCollectedBase; | 631 template<typename T, bool = WTF::IsSubclassOfTemplate<T, GarbageCollected>::valu
e> struct GetGarbageCollectedBase; |
(...skipping 12 matching lines...) Expand all Loading... |
660 struct GCInfoTrait { | 644 struct GCInfoTrait { |
661 static const GCInfo* get() | 645 static const GCInfo* get() |
662 { | 646 { |
663 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 647 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
664 } | 648 } |
665 }; | 649 }; |
666 | 650 |
667 } | 651 } |
668 | 652 |
669 #endif | 653 #endif |
OLD | NEW |