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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 | 218 |
219 inline Address payload(); | 219 inline Address payload(); |
220 inline size_t payloadSize(); | 220 inline size_t payloadSize(); |
221 inline Address payloadEnd(); | 221 inline Address payloadEnd(); |
222 | 222 |
223 inline void setDebugMark(); | 223 inline void setDebugMark(); |
224 inline void clearDebugMark(); | 224 inline void clearDebugMark(); |
225 inline bool hasDebugMark() const; | 225 inline bool hasDebugMark() const; |
226 | 226 |
227 // Zap magic number with a new magic number that means there was once an | 227 // Zap magic number with a new magic number that means there was once an |
228 // object allocated here, but it was freed because nobody visited it during | 228 // object allocated here, but it was freed because nobody marked it during |
229 // GC. | 229 // GC. |
230 void zapMagic(); | 230 void zapMagic(); |
231 | 231 |
232 static void finalize(const GCInfo*, Address, size_t); | 232 static void finalize(const GCInfo*, Address, size_t); |
233 static HeapObjectHeader* fromPayload(const void*); | 233 static HeapObjectHeader* fromPayload(const void*); |
234 | 234 |
235 static const intptr_t magic = 0xc0de247; | 235 static const intptr_t magic = 0xc0de247; |
236 static const intptr_t zappedMagic = 0xC0DEdead; | 236 static const intptr_t zappedMagic = 0xC0DEdead; |
237 static const intptr_t zappedVTable = 0xd0d; // should be < 4K to ensure it c annot be used for dispatch | 237 static const intptr_t zappedVTable = 0xd0d; // should be < 4K to ensure it c annot be used for dispatch |
238 | 238 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 public: | 341 public: |
342 BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo) | 342 BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo) |
343 : m_storage(storage) | 343 : m_storage(storage) |
344 , m_gcInfo(gcInfo) | 344 , m_gcInfo(gcInfo) |
345 { | 345 { |
346 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 346 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
347 } | 347 } |
348 | 348 |
349 Address address() { return reinterpret_cast<Address>(this); } | 349 Address address() { return reinterpret_cast<Address>(this); } |
350 const GCInfo* gcInfo() { return m_gcInfo; } | 350 const GCInfo* gcInfo() { return m_gcInfo; } |
351 virtual bool checkAndVisitPointer(Visitor*, Address) = 0; | 351 virtual bool checkAndMarkPointer(Visitor*, Address) = 0; |
352 | 352 |
353 PageMemory* storage() const { return m_storage; } | 353 PageMemory* storage() const { return m_storage; } |
354 | 354 |
355 private: | 355 private: |
356 union { | 356 union { |
357 PageMemory* m_storage; | 357 PageMemory* m_storage; |
358 uint64_t m_dummy; | 358 uint64_t m_dummy; |
359 }; | 359 }; |
360 const GCInfo* m_gcInfo; | 360 const GCInfo* m_gcInfo; |
361 }; | 361 }; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 | 401 |
402 Header* heapObjectHeader() | 402 Header* heapObjectHeader() |
403 { | 403 { |
404 Address headerAddress = address() + sizeof(LargeHeapObject<Header>); | 404 Address headerAddress = address() + sizeof(LargeHeapObject<Header>); |
405 return reinterpret_cast<Header*>(headerAddress); | 405 return reinterpret_cast<Header*>(headerAddress); |
406 } | 406 } |
407 | 407 |
408 bool isMarked(); | 408 bool isMarked(); |
409 void unmark(); | 409 void unmark(); |
410 void getStats(HeapStats&); | 410 void getStats(HeapStats&); |
411 void visit(Visitor*); | 411 void trace(Visitor*); |
Erik Corry
2013/12/06 10:30:33
Should this not be mark?
Mads Ager (chromium)
2013/12/06 11:00:10
Yeah, I probably went a little bit too far with th
| |
412 void finalize(); | 412 void finalize(); |
413 virtual bool checkAndVisitPointer(Visitor*, Address); | 413 virtual bool checkAndMarkPointer(Visitor*, Address); |
414 | 414 |
415 private: | 415 private: |
416 friend class Heap; | 416 friend class Heap; |
417 friend class ThreadHeap<Header>; | 417 friend class ThreadHeap<Header>; |
418 | 418 |
419 LargeHeapObject<Header>* m_next; | 419 LargeHeapObject<Header>* m_next; |
420 }; | 420 }; |
421 | 421 |
422 template<typename T> | 422 template<typename T> |
423 void heapAllocatedFinalizer(void* object) | 423 void heapAllocatedFinalizer(void* object) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 HeapPage* next() { return m_next; } | 506 HeapPage* next() { return m_next; } |
507 Address payload() { return address() + sizeof(*this); } | 507 Address payload() { return address() + sizeof(*this); } |
508 static size_t payloadSize() { return (writablePageSize() - sizeof(HeapPage)) & ~allocationMask; } | 508 static size_t payloadSize() { return (writablePageSize() - sizeof(HeapPage)) & ~allocationMask; } |
509 Address end() { return payload() + payloadSize(); } | 509 Address end() { return payload() + payloadSize(); } |
510 | 510 |
511 void getStats(HeapStats&); | 511 void getStats(HeapStats&); |
512 void clearMarks(); | 512 void clearMarks(); |
513 void sweep(); | 513 void sweep(); |
514 void clearObjectStartBitMap(); | 514 void clearObjectStartBitMap(); |
515 void finalize(Header*); | 515 void finalize(Header*); |
516 virtual bool checkAndVisitPointer(Visitor*, Address); | 516 virtual bool checkAndMarkPointer(Visitor*, Address); |
517 ThreadHeap<Header>* heap() { return m_heap; } | 517 ThreadHeap<Header>* heap() { return m_heap; } |
518 #if USE_ASAN | 518 #if USE_ASAN |
519 void poisonUnmarkedObjects(); | 519 void poisonUnmarkedObjects(); |
520 #endif | 520 #endif |
521 | 521 |
522 protected: | 522 protected: |
523 void populateObjectStartBitMap(); | 523 void populateObjectStartBitMap(); |
524 bool isObjectStartBitMapComputed() { return m_union.m_objectStartBitMapCompu ted; } | 524 bool isObjectStartBitMapComputed() { return m_union.m_objectStartBitMapCompu ted; } |
525 TraceCallback traceCallback(Header*); | 525 TraceCallback traceCallback(Header*); |
526 | 526 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 }; | 587 }; |
588 | 588 |
589 static const int numberOfEntriesLog2 = 12; | 589 static const int numberOfEntriesLog2 = 12; |
590 static const int numberOfEntries = 1 << numberOfEntriesLog2; | 590 static const int numberOfEntries = 1 << numberOfEntriesLog2; |
591 | 591 |
592 OwnArrayPtr<HeapContainsCache::Entry> m_entries; | 592 OwnArrayPtr<HeapContainsCache::Entry> m_entries; |
593 | 593 |
594 friend class ThreadState; | 594 friend class ThreadState; |
595 }; | 595 }; |
596 | 596 |
597 enum TraceRequirement { | |
598 // TraceChecker does not perform checks, because there are weak pointers | |
599 // present that cannot be distinguished from pointers that were incorrectly | |
600 // not visited. Later, however, we can check that the weak pointers were | |
601 // cleared by the weak pointer callback. | |
602 NoRequirement, | |
603 // The trace method must visit all member pointers. | |
604 AllPointersMustBeVisited, | |
605 // All member pointers must be marked live if they were not already. This | |
606 // also means that all weak pointers must be cleared if they are not | |
607 // pointing to objects that are marked live. | |
608 AllPointersMustBeMarked | |
609 }; | |
610 | |
611 typedef void (*TraceTrampoline)(VisitorCallback, Visitor*, void*); | 597 typedef void (*TraceTrampoline)(VisitorCallback, Visitor*, void*); |
612 | 598 |
613 class Heap { | 599 class Heap { |
614 public: | 600 public: |
615 static void init(intptr_t* startOfStack); | 601 static void init(intptr_t* startOfStack); |
616 static void shutdown(); | 602 static void shutdown(); |
617 | 603 |
618 static bool contains(Address); | 604 static bool contains(Address); |
619 static bool contains(void* pointer) { return contains(reinterpret_cast<Addre ss>(pointer)); } | 605 static bool contains(void* pointer) { return contains(reinterpret_cast<Addre ss>(pointer)); } |
620 static bool contains(const void* pointer) { return contains(const_cast<void* >(pointer)); } | 606 static bool contains(const void* pointer) { return contains(const_cast<void* >(pointer)); } |
(...skipping 20 matching lines...) Expand all Loading... | |
641 | 627 |
642 enum CollectionType { | 628 enum CollectionType { |
643 Normal, | 629 Normal, |
644 ForcedForTesting | 630 ForcedForTesting |
645 }; | 631 }; |
646 static void collectGarbage(ThreadState::StackState, CollectionType = Normal) ; | 632 static void collectGarbage(ThreadState::StackState, CollectionType = Normal) ; |
647 | 633 |
648 static void prepareForGC(); | 634 static void prepareForGC(); |
649 | 635 |
650 static void visitRoots(Visitor*); | 636 static void visitRoots(Visitor*); |
651 static Address checkAndVisitPointer(Visitor*, Address); | 637 static Address checkAndMarkPointer(Visitor*, Address); |
652 | 638 |
653 static void getStats(HeapStats*); | 639 static void getStats(HeapStats*); |
654 | 640 |
655 static bool isConsistentForGC(); | 641 static bool isConsistentForGC(); |
656 static void makeConsistentForGC(); | 642 static void makeConsistentForGC(); |
657 static BaseHeapPage* heapPageFromAddress(Address); | 643 static BaseHeapPage* heapPageFromAddress(Address); |
658 | 644 |
659 static bool s_heapWasInitialized; | 645 static bool s_heapWasInitialized; |
660 | 646 |
661 #ifdef ENABLE_PERF_STATS | 647 #ifdef ENABLE_PERF_STATS |
(...skipping 18 matching lines...) Expand all Loading... | |
680 }; | 666 }; |
681 | 667 |
682 // Non-template super class used to pass a heap around to other classes. | 668 // Non-template super class used to pass a heap around to other classes. |
683 class BaseHeap { | 669 class BaseHeap { |
684 public: | 670 public: |
685 virtual ~BaseHeap() { } | 671 virtual ~BaseHeap() { } |
686 | 672 |
687 // Large objects and adding pages are handled by the ThreadHeap | 673 // Large objects and adding pages are handled by the ThreadHeap |
688 virtual BaseHeapPage* heapPageFromAddress(Address) = 0; | 674 virtual BaseHeapPage* heapPageFromAddress(Address) = 0; |
689 virtual BaseHeapPage* largeHeapObjectFromAddress(Address) = 0; | 675 virtual BaseHeapPage* largeHeapObjectFromAddress(Address) = 0; |
690 virtual bool checkAndVisitLargeHeapObjects(Visitor*, Address) = 0; | 676 virtual bool checkAndMarkLargeHeapObjects(Visitor*, Address) = 0; |
691 virtual void sweep() = 0; | 677 virtual void sweep() = 0; |
692 virtual void finalizeAll(const void* except = 0) = 0; | 678 virtual void finalizeAll(const void* except = 0) = 0; |
693 virtual bool inFinalizeAll() = 0; | 679 virtual bool inFinalizeAll() = 0; |
694 virtual void clearFreeLists() = 0; | 680 virtual void clearFreeLists() = 0; |
695 virtual void clearMarks() = 0; | 681 virtual void clearMarks() = 0; |
696 #ifndef NDEBUG | 682 #ifndef NDEBUG |
697 virtual void getScannedStats(HeapStats&) = 0; | 683 virtual void getScannedStats(HeapStats&) = 0; |
698 #endif | 684 #endif |
699 | 685 |
700 // Heap can be either ready for allocation or in a consistent state for | 686 // Heap can be either ready for allocation or in a consistent state for |
701 // scanning. | 687 // scanning. |
702 virtual void makeConsistentForGC() = 0; | 688 virtual void makeConsistentForGC() = 0; |
703 virtual bool isConsistentForGC() = 0; | 689 virtual bool isConsistentForGC() = 0; |
704 | 690 |
705 // Returns a bucket number for inserting a FreeListEntry of a given size. | 691 // Returns a bucket number for inserting a FreeListEntry of a given size. |
706 // All FreeListEntries in the given bucket, n, have size >= 2^n. | 692 // All FreeListEntries in the given bucket, n, have size >= 2^n. |
707 static int bucketIndexForSize(size_t); | 693 static int bucketIndexForSize(size_t); |
708 }; | 694 }; |
709 | 695 |
710 template<typename Header> | 696 template<typename Header> |
711 class ThreadHeap : public BaseHeap { | 697 class ThreadHeap : public BaseHeap { |
712 public: | 698 public: |
713 ThreadHeap(ThreadState*); | 699 ThreadHeap(ThreadState*); |
714 virtual ~ThreadHeap(); | 700 virtual ~ThreadHeap(); |
715 | 701 |
716 virtual BaseHeapPage* heapPageFromAddress(Address); | 702 virtual BaseHeapPage* heapPageFromAddress(Address); |
717 virtual BaseHeapPage* largeHeapObjectFromAddress(Address); | 703 virtual BaseHeapPage* largeHeapObjectFromAddress(Address); |
718 virtual bool checkAndVisitLargeHeapObjects(Visitor*, Address); | 704 virtual bool checkAndMarkLargeHeapObjects(Visitor*, Address); |
719 virtual void sweep(); | 705 virtual void sweep(); |
720 virtual void finalizeAll(const void* except = 0); | 706 virtual void finalizeAll(const void* except = 0); |
721 virtual bool inFinalizeAll() { return m_inFinalizeAll; } | 707 virtual bool inFinalizeAll() { return m_inFinalizeAll; } |
722 virtual void clearFreeLists(); | 708 virtual void clearFreeLists(); |
723 virtual void clearMarks(); | 709 virtual void clearMarks(); |
724 #ifndef NDEBUG | 710 #ifndef NDEBUG |
725 virtual void getScannedStats(HeapStats&); | 711 virtual void getScannedStats(HeapStats&); |
726 #endif | 712 #endif |
727 | 713 |
728 // Heap can be either ready for allocation or in a consistent state for | 714 // Heap can be either ready for allocation or in a consistent state for |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1066 void* object() { return m_object; } | 1052 void* object() { return m_object; } |
1067 VisitorCallback callback() { return m_callback; } | 1053 VisitorCallback callback() { return m_callback; } |
1068 | 1054 |
1069 private: | 1055 private: |
1070 void* m_object; | 1056 void* m_object; |
1071 VisitorCallback m_callback; | 1057 VisitorCallback m_callback; |
1072 }; | 1058 }; |
1073 | 1059 |
1074 static void init(CallbackStack** first); | 1060 static void init(CallbackStack** first); |
1075 static void shutdown(CallbackStack** first); | 1061 static void shutdown(CallbackStack** first); |
1076 bool popAndTrace(CallbackStack** first, Visitor*, TraceRequirement, TraceTra mpoline); | 1062 bool popAndTrace(CallbackStack** first, Visitor*, TraceTrampoline); |
1077 | 1063 |
1078 Item* allocateEntry(CallbackStack** first) | 1064 Item* allocateEntry(CallbackStack** first) |
1079 { | 1065 { |
1080 if (m_current < m_limit) | 1066 if (m_current < m_limit) |
1081 return m_current++; | 1067 return m_current++; |
1082 return (new CallbackStack(first))->allocateEntry(first); | 1068 return (new CallbackStack(first))->allocateEntry(first); |
1083 } | 1069 } |
1084 | 1070 |
1085 private: | 1071 private: |
1086 static const int bufferSize = 8000; | 1072 static const int bufferSize = 8000; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1148 int length = header->payloadSize() / sizeof(Value); | 1134 int length = header->payloadSize() / sizeof(Value); |
1149 // The hash table backing is unreachable and is going away, so it is not | 1135 // The hash table backing is unreachable and is going away, so it is not |
1150 // important what is in this memory, but the entries have destructors, and | 1136 // important what is in this memory, but the entries have destructors, and |
1151 // they need to be called. | 1137 // they need to be called. |
1152 for (int i = 0; i < length; i++) { | 1138 for (int i = 0; i < length; i++) { |
1153 if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDeleted Bucket(array[i])) | 1139 if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDeleted Bucket(array[i])) |
1154 array[i].~Value(); | 1140 array[i].~Value(); |
1155 } | 1141 } |
1156 } | 1142 } |
1157 | 1143 |
1158 template<bool visitWeakPointersStrongly, typename T, typename Traits> | 1144 template<bool markWeakPointersStrongly, typename T, typename Traits> |
1159 struct BaseVisitVectorBackingTrait { | 1145 struct BaseVisitVectorBackingTrait { |
1160 static void visit(WebCore::Visitor* visitor, void* self) | 1146 static void mark(WebCore::Visitor* visitor, void* self) |
1161 { | 1147 { |
1162 // The alllocator can oversize the allocation a little, according to | 1148 // The alllocator can oversize the allocation a little, according to |
1163 // the allocation granularity. The extra size is included in the | 1149 // the allocation granularity. The extra size is included in the |
1164 // payloadSize call below, since there is nowhere to store the | 1150 // payloadSize call below, since there is nowhere to store the |
1165 // originally allocated memory. This assert ensures that visiting the | 1151 // originally allocated memory. This assert ensures that visiting the |
1166 // last bit of memory can't cause trouble. | 1152 // last bit of memory can't cause trouble. |
1167 COMPILE_ASSERT(!Traits::needsVisiting || sizeof(T) > allocationGranulari ty || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSpuriousVisits) ; | 1153 COMPILE_ASSERT(!Traits::needsMarking || sizeof(T) > allocationGranularit y || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSpuriousVisits); |
1168 | 1154 |
1169 T* array = reinterpret_cast<T*>(self); | 1155 T* array = reinterpret_cast<T*>(self); |
1170 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); | 1156 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); |
1171 // Use the payload size as recorded by the heap to determine how many | 1157 // Use the payload size as recorded by the heap to determine how many |
1172 // elements to visit. | 1158 // elements to mark. |
1173 int length = header->payloadSize() / sizeof(T); | 1159 int length = header->payloadSize() / sizeof(T); |
1174 for (int i = 0; i < length; i++) | 1160 for (int i = 0; i < length; i++) |
1175 VisitCollectionBackingTrait<Traits::needsVisiting, Traits::isWeak, v isitWeakPointersStrongly, T, Traits>::visit(visitor, array[i]); | 1161 CollectionBackingTraceTrait<Traits::needsMarking, Traits::isWeak, ma rkWeakPointersStrongly, T, Traits>::mark(visitor, array[i]); |
1176 } | 1162 } |
1177 }; | 1163 }; |
1178 | 1164 |
1179 template<bool visitWeakPointersStrongly, typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits> | 1165 template<bool markWeakPointersStrongly, typename Key, typename Value, typename E xtractor, typename Traits, typename KeyTraits> |
1180 struct BaseVisitHashTableBackingTrait { | 1166 struct BaseVisitHashTableBackingTrait { |
1181 static void visit(WebCore::Visitor* visitor, void* self) | 1167 static void mark(WebCore::Visitor* visitor, void* self) |
1182 { | 1168 { |
1183 Value* array = reinterpret_cast<Value*>(self); | 1169 Value* array = reinterpret_cast<Value*>(self); |
1184 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); | 1170 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); |
1185 int length = header->payloadSize() / sizeof(Value); | 1171 int length = header->payloadSize() / sizeof(Value); |
1186 for (int i = 0; i < length; i++) { | 1172 for (int i = 0; i < length; i++) { |
1187 if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDel etedBucket(array[i])) | 1173 if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDel etedBucket(array[i])) |
1188 VisitCollectionBackingTrait<Traits::needsVisiting, Traits::isWea k, visitWeakPointersStrongly, Value, Traits>::visit(visitor, array[i]); | 1174 CollectionBackingTraceTrait<Traits::needsMarking, Traits::isWeak , markWeakPointersStrongly, Value, Traits>::mark(visitor, array[i]); |
1189 } | 1175 } |
1190 } | 1176 } |
1191 }; | 1177 }; |
1192 | 1178 |
1193 template<bool visitWeakPointersStrongly, typename Key, typename Value, typename Traits> | 1179 template<bool markWeakPointersStrongly, typename Key, typename Value, typename T raits> |
1194 struct BaseVisitKeyValuePairTrait { | 1180 struct BaseVisitKeyValuePairTrait { |
1195 static void visit(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& self) | 1181 static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& s elf) |
1196 { | 1182 { |
1197 ASSERT(Traits::needsVisiting || (Traits::isWeak && visitWeakPointersStro ngly)); | 1183 ASSERT(Traits::needsMarking || (Traits::isWeak && markWeakPointersStrong ly)); |
1198 VisitCollectionBackingTrait<Traits::KeyTraits::needsVisiting, Traits::Ke yTraits::isWeak, visitWeakPointersStrongly, Key, typename Traits::KeyTraits>::vi sit(visitor, self.key); | 1184 CollectionBackingTraceTrait<Traits::KeyTraits::needsMarking, Traits::Key Traits::isWeak, markWeakPointersStrongly, Key, typename Traits::KeyTraits>::mark (visitor, self.key); |
1199 VisitCollectionBackingTrait<Traits::ValueTraits::needsVisiting, Traits:: ValueTraits::isWeak, visitWeakPointersStrongly, Value, typename Traits::ValueTra its>::visit(visitor, self.value); | 1185 CollectionBackingTraceTrait<Traits::ValueTraits::needsMarking, Traits::V alueTraits::isWeak, markWeakPointersStrongly, Value, typename Traits::ValueTrait s>::mark(visitor, self.value); |
1200 } | 1186 } |
1201 }; | 1187 }; |
1202 | 1188 |
1203 // FFX - Things that don't need visiting and have no weak pointers. | 1189 // FFX - Things that don't need marking and have no weak pointers. |
1204 template<bool visitWeakPointersStrongly, typename T, typename U> | 1190 template<bool markWeakPointersStrongly, typename T, typename U> |
1205 struct VisitCollectionBackingTrait<false, false, visitWeakPointersStrongly, T, U > { | 1191 struct CollectionBackingTraceTrait<false, false, markWeakPointersStrongly, T, U> { |
1206 static void visit(Visitor*, const T&) { } | 1192 static void mark(Visitor*, const T&) { } |
1207 static void visit(Visitor*, const void*) { } | 1193 static void mark(Visitor*, const void*) { } |
1208 }; | 1194 }; |
1209 | 1195 |
1210 // FTF - Things that don't need visiting. They have weak pointers, but we are | 1196 // FTF - Things that don't need marking. They have weak pointers, but we are |
1211 // not visiting weak pointers in this object in this GC. | 1197 // not marking weak pointers in this object in this GC. |
1212 template<typename T, typename U> | 1198 template<typename T, typename U> |
1213 struct VisitCollectionBackingTrait<false, true, false, T, U> { | 1199 struct CollectionBackingTraceTrait<false, true, false, T, U> { |
1214 static void visit(Visitor*, const T&) { } | 1200 static void mark(Visitor*, const T&) { } |
1215 static void visit(Visitor*, const void*) { } | 1201 static void mark(Visitor*, const void*) { } |
1216 }; | 1202 }; |
1217 | 1203 |
1218 // For each type that we understand we have the FTT case and the TXX case. The | 1204 // For each type that we understand we have the FTT case and the TXX case. The |
1219 // FTT case is where we would not normally need to visit it, but it has weak | 1205 // FTT case is where we would not normally need to mark it, but it has weak |
1220 // pointers, and we are visiting them as strong. The TXX case is the regular | 1206 // pointers, and we are marking them as strong. The TXX case is the regular |
1221 // case for things that need visiting. | 1207 // case for things that need marking. |
1222 | 1208 |
1223 // FTT (vector) | 1209 // FTT (vector) |
1224 template<typename T, typename Traits> | 1210 template<typename T, typename Traits> |
1225 struct VisitCollectionBackingTrait<false, true, true, HeapVectorBacking<T, Trait s>, void> : public BaseVisitVectorBackingTrait<true, T, Traits> { | 1211 struct CollectionBackingTraceTrait<false, true, true, HeapVectorBacking<T, Trait s>, void> : public BaseVisitVectorBackingTrait<true, T, Traits> { |
1226 }; | 1212 }; |
1227 | 1213 |
1228 // TXX (vector) | 1214 // TXX (vector) |
1229 template<bool isWeak, bool visitWeakPointersStrongly, typename T, typename Trait s> | 1215 template<bool isWeak, bool markWeakPointersStrongly, typename T, typename Traits > |
1230 struct VisitCollectionBackingTrait<true, isWeak, visitWeakPointersStrongly, Heap VectorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<visitWeakPo intersStrongly, T, Traits> { | 1216 struct CollectionBackingTraceTrait<true, isWeak, markWeakPointersStrongly, HeapV ectorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<markWeakPoin tersStrongly, T, Traits> { |
1231 }; | 1217 }; |
1232 | 1218 |
1233 // FTT (hash table) | 1219 // FTT (hash table) |
1234 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> | 1220 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> |
1235 struct VisitCollectionBackingTrait<false, true, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTr ait<true, Key, Value, Extractor, Traits, KeyTraits> { | 1221 struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTr ait<true, Key, Value, Extractor, Traits, KeyTraits> { |
1236 }; | 1222 }; |
1237 | 1223 |
1238 // TXX (hash table) | 1224 // TXX (hash table) |
1239 template<bool isWeak, bool visitWeakPointersStrongly, typename Key, typename Val ue, typename Extractor, typename Traits, typename KeyTraits> | 1225 template<bool isWeak, bool markWeakPointersStrongly, typename Key, typename Valu e, typename Extractor, typename Traits, typename KeyTraits> |
1240 struct VisitCollectionBackingTrait<true, isWeak, visitWeakPointersStrongly, Heap HashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseV isitHashTableBackingTrait<visitWeakPointersStrongly, Key, Value, Extractor, Trai ts, KeyTraits> { | 1226 struct CollectionBackingTraceTrait<true, isWeak, markWeakPointersStrongly, HeapH ashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVi sitHashTableBackingTrait<markWeakPointersStrongly, Key, Value, Extractor, Traits , KeyTraits> { |
1241 }; | 1227 }; |
1242 | 1228 |
1243 // FTT (key value pair) | 1229 // FTT (key value pair) |
1244 template<typename Key, typename Value, typename Traits> | 1230 template<typename Key, typename Value, typename Traits> |
1245 struct VisitCollectionBackingTrait<false, true, true, WTF::KeyValuePair<Key, Val ue>, Traits> : public BaseVisitKeyValuePairTrait<true, Key, Value, Traits> { | 1231 struct CollectionBackingTraceTrait<false, true, true, WTF::KeyValuePair<Key, Val ue>, Traits> : public BaseVisitKeyValuePairTrait<true, Key, Value, Traits> { |
1246 }; | 1232 }; |
1247 | 1233 |
1248 // TXX (key value pair) | 1234 // TXX (key value pair) |
1249 template<bool isWeak, bool visitWeakPointersStrongly, typename Key, typename Val ue, typename Traits> | 1235 template<bool isWeak, bool markWeakPointersStrongly, typename Key, typename Valu e, typename Traits> |
1250 struct VisitCollectionBackingTrait<true, isWeak, visitWeakPointersStrongly, WTF: :KeyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<visitWeak PointersStrongly, Key, Value, Traits> { | 1236 struct CollectionBackingTraceTrait<true, isWeak, markWeakPointersStrongly, WTF:: KeyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<markWeakPo intersStrongly, Key, Value, Traits> { |
1251 }; | 1237 }; |
1252 | 1238 |
1253 // TFX (member) | 1239 // TFX (member) |
1254 template<bool visitWeakPointersStrongly, typename T, typename Traits> | 1240 template<bool markWeakPointersStrongly, typename T, typename Traits> |
1255 struct VisitCollectionBackingTrait<true, false, visitWeakPointersStrongly, Membe r<T>, Traits> { | 1241 struct CollectionBackingTraceTrait<true, false, markWeakPointersStrongly, Member <T>, Traits> { |
1256 static void visit(WebCore::Visitor* visitor, Member<T> self) | 1242 static void mark(WebCore::Visitor* visitor, Member<T> self) |
1257 { | 1243 { |
1258 visitor->visit(self.raw()); | 1244 visitor->mark(self.raw()); |
1259 } | 1245 } |
1260 }; | 1246 }; |
1261 | 1247 |
1262 // FTT (weak member) | 1248 // FTT (weak member) |
1263 template<typename T, typename Traits> | 1249 template<typename T, typename Traits> |
1264 struct VisitCollectionBackingTrait<false, true, true, WeakMember<T>, Traits> { | 1250 struct CollectionBackingTraceTrait<false, true, true, WeakMember<T>, Traits> { |
1265 static void visit(WebCore::Visitor* visitor, WeakMember<T> self) | 1251 static void mark(WebCore::Visitor* visitor, WeakMember<T> self) |
1266 { | 1252 { |
1267 // This can visit weak members as if they were strong. The reason we | 1253 // This can mark weak members as if they were strong. The reason we |
1268 // need this is that we don't do weak processing unless we reach the | 1254 // need this is that we don't do weak processing unless we reach the |
1269 // backing only through the hash table. Reaching it in any other way | 1255 // backing only through the hash table. Reaching it in any other way |
1270 // makes it impossible to update the size and deleted slot count of the | 1256 // makes it impossible to update the size and deleted slot count of the |
1271 // table, and exposes us to weak processing during iteration issues. | 1257 // table, and exposes us to weak processing during iteration issues. |
1272 visitor->visit(self.raw()); | 1258 visitor->mark(self.raw()); |
1273 } | 1259 } |
1274 }; | 1260 }; |
1275 | 1261 |
1276 // Catch-all for things that have a way to trace. For things that contain weak | 1262 // Catch-all for things that have a way to trace. For things that contain weak |
1277 // pointers they will generally be visited weakly even if | 1263 // pointers they will generally be visited weakly even if |
1278 // visitWeakPointersStrongly is true. This is what you want. | 1264 // markWeakPointersStrongly is true. This is what you want. |
1279 template<bool isWeak, bool visitWeakPointersStrongly, typename T, typename Trait s> | 1265 template<bool isWeak, bool markWeakPointersStrongly, typename T, typename Traits > |
1280 struct VisitCollectionBackingTrait<true, isWeak, visitWeakPointersStrongly, T, T raits> { | 1266 struct CollectionBackingTraceTrait<true, isWeak, markWeakPointersStrongly, T, Tr aits> { |
1281 static void visit(WebCore::Visitor* visitor, T& t) | 1267 static void mark(WebCore::Visitor* visitor, T& t) |
1282 { | 1268 { |
1283 TraceTrait<T>::trace(visitor, reinterpret_cast<void*>(&t)); | 1269 TraceTrait<T>::trace(visitor, reinterpret_cast<void*>(&t)); |
1284 } | 1270 } |
1285 }; | 1271 }; |
1286 | 1272 |
1287 template<typename T, typename Traits> | 1273 template<typename T, typename Traits> |
1288 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 1274 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
1289 typedef HeapVectorBacking<T, Traits> Backing; | 1275 typedef HeapVectorBacking<T, Traits> Backing; |
1290 static void trace(WebCore::Visitor* visitor, void* self) | 1276 static void trace(WebCore::Visitor* visitor, void* self) |
1291 { | 1277 { |
1292 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectors); | 1278 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectors); |
1293 if (Traits::needsVisiting) | 1279 if (Traits::needsMarking) |
Erik Corry
2013/12/06 10:30:33
I think this should be needsTracing
Mads Ager (chromium)
2013/12/06 11:00:10
Yes, will fix.
| |
1294 VisitCollectionBackingTrait<Traits::needsVisiting, false, false, Hea pVectorBacking<T, Traits>, void>::visit(visitor, self); | 1280 CollectionBackingTraceTrait<Traits::needsMarking, false, false, Heap VectorBacking<T, Traits>, void>::mark(visitor, self); |
1295 } | 1281 } |
1296 static void visit(Visitor* v, const Backing* p) | 1282 static void mark(Visitor* v, const Backing* p) |
1297 { | 1283 { |
1298 v->visit(p, &trace); | 1284 v->mark(p, &trace); |
1299 } | 1285 } |
1300 static void checkTypeMarker(Visitor* visitor, const Backing* t) | 1286 static void checkTypeMarker(Visitor* visitor, const Backing* t) |
1301 { | 1287 { |
1302 #ifndef NDEBUG | 1288 #ifndef NDEBUG |
1303 visitor->checkTypeMarker(const_cast<Backing*>(t), getTypeMarker<Backing> ()); | 1289 visitor->checkTypeMarker(const_cast<Backing*>(t), getTypeMarker<Backing> ()); |
1304 #endif | 1290 #endif |
1305 } | 1291 } |
1306 }; | 1292 }; |
1307 | 1293 |
1308 // The trace trait for the heap hashtable backing is used when we find a | 1294 // The trace trait for the heap hashtable backing is used when we find a |
1309 // direct pointer to the backing from the conservative stack scanner. This | 1295 // direct pointer to the backing from the conservative stack scanner. This |
1310 // normally indicates that there is an ongoing iteration over the table, and so | 1296 // normally indicates that there is an ongoing iteration over the table, and so |
1311 // we disable weak processing of table entries. When the backing is found | 1297 // we disable weak processing of table entries. When the backing is found |
1312 // through the owning hash table we mark differently, in order to do weak | 1298 // through the owning hash table we mark differently, in order to do weak |
1313 // processing. | 1299 // processing. |
1314 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> | 1300 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> |
1315 struct TraceTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > { | 1301 struct TraceTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > { |
1316 typedef HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> Backi ng; | 1302 typedef HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> Backi ng; |
1317 static const bool needsVisiting = (Traits::needsVisiting || Traits::isWeak); | 1303 static const bool needsMarking = (Traits::needsMarking || Traits::isWeak); |
1318 static void trace(WebCore::Visitor* visitor, void* self) | 1304 static void trace(WebCore::Visitor* visitor, void* self) |
1319 { | 1305 { |
1320 if (needsVisiting) | 1306 if (needsMarking) |
1321 VisitCollectionBackingTrait<Traits::needsVisiting, Traits::isWeak, t rue, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void>::visi t(visitor, self); | 1307 CollectionBackingTraceTrait<Traits::needsMarking, Traits::isWeak, tr ue, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void>::mark( visitor, self); |
1322 } | 1308 } |
1323 static void visit(Visitor* v, const Backing* p) | 1309 static void mark(Visitor* v, const Backing* p) |
1324 { | 1310 { |
1325 if (needsVisiting) | 1311 if (needsMarking) |
1326 v->visit(p, &trace); | 1312 v->mark(p, &trace); |
1327 else | 1313 else |
1328 v->visit(p, nullptr); | 1314 v->mark(p, nullptr); |
1329 } | 1315 } |
1330 static void checkTypeMarker(Visitor* visitor, const Backing* t) | 1316 static void checkTypeMarker(Visitor* visitor, const Backing* t) |
1331 { | 1317 { |
1332 #ifndef NDEBUG | 1318 #ifndef NDEBUG |
1333 visitor->checkTypeMarker(const_cast<Backing*>(t), getTypeMarker<Backing> ()); | 1319 visitor->checkTypeMarker(const_cast<Backing*>(t), getTypeMarker<Backing> ()); |
1334 #endif | 1320 #endif |
1335 } | 1321 } |
1336 }; | 1322 }; |
1337 | 1323 |
1338 template<typename T, typename Traits> | 1324 template<typename T, typename Traits> |
1339 class HeapVectorBacking { }; | 1325 class HeapVectorBacking { }; |
1340 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> | 1326 template<typename Key, typename Value, typename Extractor, typename Traits, type name KeyTraits> |
1341 class HeapHashTableBacking { }; | 1327 class HeapHashTableBacking { }; |
1342 | 1328 |
1343 | 1329 |
1344 } // namespace WebCore | 1330 } // namespace WebCore |
1345 | 1331 |
1346 #endif | 1332 #endif |
OLD | NEW |