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 29 matching lines...) Expand all Loading... |
40 #include "wtf/HashTraits.h" | 40 #include "wtf/HashTraits.h" |
41 #include "wtf/InstanceCounter.h" | 41 #include "wtf/InstanceCounter.h" |
42 #include "wtf/OwnPtr.h" | 42 #include "wtf/OwnPtr.h" |
43 #include "wtf/RefPtr.h" | 43 #include "wtf/RefPtr.h" |
44 #include "wtf/TypeTraits.h" | 44 #include "wtf/TypeTraits.h" |
45 #include "wtf/WeakPtr.h" | 45 #include "wtf/WeakPtr.h" |
46 #if ENABLE(GC_TRACING) | 46 #if ENABLE(GC_TRACING) |
47 #include "wtf/text/WTFString.h" | 47 #include "wtf/text/WTFString.h" |
48 #endif | 48 #endif |
49 | 49 |
50 #ifndef NDEBUG | 50 #if ENABLE(ASSERT) |
51 #define DEBUG_ONLY(x) x | 51 #define DEBUG_ONLY(x) x |
52 #else | 52 #else |
53 #define DEBUG_ONLY(x) | 53 #define DEBUG_ONLY(x) |
54 #endif | 54 #endif |
55 | 55 |
56 namespace WebCore { | 56 namespace WebCore { |
57 | 57 |
58 class FinalizedHeapObjectHeader; | 58 class FinalizedHeapObjectHeader; |
59 template<typename T> class GarbageCollectedFinalized; | 59 template<typename T> class GarbageCollectedFinalized; |
60 class HeapObjectHeader; | 60 class HeapObjectHeader; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 static void trace(Visitor* visitor, void* self) | 166 static void trace(Visitor* visitor, void* self) |
167 { | 167 { |
168 static_cast<T*>(self)->trace(visitor); | 168 static_cast<T*>(self)->trace(visitor); |
169 } | 169 } |
170 | 170 |
171 static void mark(Visitor* visitor, const T* t) | 171 static void mark(Visitor* visitor, const T* t) |
172 { | 172 { |
173 DefaultTraceTrait<T>::mark(visitor, t); | 173 DefaultTraceTrait<T>::mark(visitor, t); |
174 } | 174 } |
175 | 175 |
176 #ifndef NDEBUG | 176 #if ENABLE(ASSERT) |
177 static void checkGCInfo(Visitor* visitor, const T* t) | 177 static void checkGCInfo(Visitor* visitor, const T* t) |
178 { | 178 { |
179 DefaultTraceTrait<T>::checkGCInfo(visitor, t); | 179 DefaultTraceTrait<T>::checkGCInfo(visitor, t); |
180 } | 180 } |
181 #endif | 181 #endif |
182 }; | 182 }; |
183 | 183 |
184 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 184 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
185 | 185 |
186 template<typename Collection> | 186 template<typename Collection> |
(...skipping 30 matching lines...) Expand all Loading... |
217 | 217 |
218 // One-argument templated mark method. This uses the static type of | 218 // One-argument templated mark method. This uses the static type of |
219 // the argument to get the TraceTrait. By default, the mark method | 219 // the argument to get the TraceTrait. By default, the mark method |
220 // of the TraceTrait just calls the virtual two-argument mark method on this | 220 // of the TraceTrait just calls the virtual two-argument mark method on this |
221 // visitor, where the second argument is the static trace method of the trai
t. | 221 // visitor, where the second argument is the static trace method of the trai
t. |
222 template<typename T> | 222 template<typename T> |
223 void mark(T* t) | 223 void mark(T* t) |
224 { | 224 { |
225 if (!t) | 225 if (!t) |
226 return; | 226 return; |
227 #ifndef NDEBUG | 227 #if ENABLE(ASSERT) |
228 TraceTrait<T>::checkGCInfo(this, t); | 228 TraceTrait<T>::checkGCInfo(this, t); |
229 #endif | 229 #endif |
230 TraceTrait<T>::mark(this, t); | 230 TraceTrait<T>::mark(this, t); |
231 | 231 |
232 reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected(); | 232 reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected(); |
233 } | 233 } |
234 | 234 |
235 // Member version of the one-argument templated trace method. | 235 // Member version of the one-argument templated trace method. |
236 template<typename T> | 236 template<typename T> |
237 void trace(const Member<T>& t) | 237 void trace(const Member<T>& t) |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 // In contrast to registerWeakMembers, the weak cell callbacks are | 370 // In contrast to registerWeakMembers, the weak cell callbacks are |
371 // run on the thread performing garbage collection. Therefore, all | 371 // run on the thread performing garbage collection. Therefore, all |
372 // threads are stopped during weak cell callbacks. | 372 // threads are stopped during weak cell callbacks. |
373 template<typename T> | 373 template<typename T> |
374 void registerWeakCell(T** cell) | 374 void registerWeakCell(T** cell) |
375 { | 375 { |
376 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>); | 376 registerWeakCell(reinterpret_cast<void**>(cell), &handleWeakCell<T>); |
377 } | 377 } |
378 | 378 |
379 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) = 0; | 379 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) = 0; |
380 #ifndef NDEBUG | 380 #if ENABLE(ASSERT) |
381 virtual bool weakTableRegistered(const void*) = 0; | 381 virtual bool weakTableRegistered(const void*) = 0; |
382 #endif | 382 #endif |
383 | 383 |
384 virtual bool isMarked(const void*) = 0; | 384 virtual bool isMarked(const void*) = 0; |
385 | 385 |
386 template<typename T> inline bool isAlive(T* obj) | 386 template<typename T> inline bool isAlive(T* obj) |
387 { | 387 { |
388 // Check that we actually know the definition of T when tracing. | 388 // Check that we actually know the definition of T when tracing. |
389 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); | 389 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); |
390 return !!obj && ObjectAliveTrait<T>::isAlive(this, obj); | 390 return !!obj && ObjectAliveTrait<T>::isAlive(this, obj); |
391 } | 391 } |
392 template<typename T> inline bool isAlive(const Member<T>& member) | 392 template<typename T> inline bool isAlive(const Member<T>& member) |
393 { | 393 { |
394 return isAlive(member.get()); | 394 return isAlive(member.get()); |
395 } | 395 } |
396 template<typename T> inline bool isAlive(RawPtr<T> ptr) | 396 template<typename T> inline bool isAlive(RawPtr<T> ptr) |
397 { | 397 { |
398 return isAlive(ptr.get()); | 398 return isAlive(ptr.get()); |
399 } | 399 } |
400 | 400 |
401 #ifndef NDEBUG | 401 #if ENABLE(ASSERT) |
402 void checkGCInfo(const void*, const GCInfo*); | 402 void checkGCInfo(const void*, const GCInfo*); |
403 #endif | 403 #endif |
404 | 404 |
405 // Macro to declare methods needed for each typed heap. | 405 // Macro to declare methods needed for each typed heap. |
406 #define DECLARE_VISITOR_METHODS(Type) \ | 406 #define DECLARE_VISITOR_METHODS(Type) \ |
407 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ | 407 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ |
408 virtual void mark(const Type*, TraceCallback) = 0; \ | 408 virtual void mark(const Type*, TraceCallback) = 0; \ |
409 virtual bool isMarked(const Type*) = 0; | 409 virtual bool isMarked(const Type*) = 0; |
410 | 410 |
411 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 411 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 public: | 499 public: |
500 static void mark(Visitor* visitor, const T* t) | 500 static void mark(Visitor* visitor, const T* t) |
501 { | 501 { |
502 // Default mark method of the trait just calls the two-argument mark | 502 // Default mark method of the trait just calls the two-argument mark |
503 // method on the visitor. The second argument is the static trace method | 503 // method on the visitor. The second argument is the static trace method |
504 // of the trait, which by default calls the instance method | 504 // of the trait, which by default calls the instance method |
505 // trace(Visitor*) on the object. | 505 // trace(Visitor*) on the object. |
506 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 506 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
507 } | 507 } |
508 | 508 |
509 #ifndef NDEBUG | 509 #if ENABLE(ASSERT) |
510 static void checkGCInfo(Visitor* visitor, const T* t) | 510 static void checkGCInfo(Visitor* visitor, const T* t) |
511 { | 511 { |
512 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); | 512 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); |
513 } | 513 } |
514 #endif | 514 #endif |
515 }; | 515 }; |
516 | 516 |
517 template<typename T> | 517 template<typename T> |
518 class DefaultTraceTrait<T, true> { | 518 class DefaultTraceTrait<T, true> { |
519 public: | 519 public: |
520 static void mark(Visitor* visitor, const T* self) | 520 static void mark(Visitor* visitor, const T* self) |
521 { | 521 { |
522 if (!self) | 522 if (!self) |
523 return; | 523 return; |
524 | 524 |
525 // Before doing adjustAndMark we need to check if the page is orphaned | 525 // Before doing adjustAndMark we need to check if the page is orphaned |
526 // since we cannot call adjustAndMark if so, as there will be no vtable. | 526 // since we cannot call adjustAndMark if so, as there will be no vtable. |
527 // If orphaned just mark the page as traced. | 527 // If orphaned just mark the page as traced. |
528 BaseHeapPage* heapPage = pageHeaderFromObject(self); | 528 BaseHeapPage* heapPage = pageHeaderFromObject(self); |
529 if (heapPage->orphaned()) { | 529 if (heapPage->orphaned()) { |
530 heapPage->setTracedAfterOrphaned(); | 530 heapPage->setTracedAfterOrphaned(); |
531 return; | 531 return; |
532 } | 532 } |
533 self->adjustAndMark(visitor); | 533 self->adjustAndMark(visitor); |
534 } | 534 } |
535 | 535 |
536 #ifndef NDEBUG | 536 #if ENABLE(ASSERT) |
537 static void checkGCInfo(Visitor*, const T*) { } | 537 static void checkGCInfo(Visitor*, const T*) { } |
538 #endif | 538 #endif |
539 }; | 539 }; |
540 | 540 |
541 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; | 541 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; |
542 | 542 |
543 template<typename T> | 543 template<typename T> |
544 class DefaultObjectAliveTrait<T, false> { | 544 class DefaultObjectAliveTrait<T, false> { |
545 public: | 545 public: |
546 static bool isAlive(Visitor* visitor, T* obj) | 546 static bool isAlive(Visitor* visitor, T* obj) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 struct GCInfoTrait { | 655 struct GCInfoTrait { |
656 static const GCInfo* get() | 656 static const GCInfo* get() |
657 { | 657 { |
658 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 658 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
659 } | 659 } |
660 }; | 660 }; |
661 | 661 |
662 } | 662 } |
663 | 663 |
664 #endif | 664 #endif |
OLD | NEW |