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 |