Chromium Code Reviews| 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 |