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 19 matching lines...) Expand all Loading... | |
30 | 30 |
31 #ifndef Heap_h | 31 #ifndef Heap_h |
32 #define Heap_h | 32 #define Heap_h |
33 | 33 |
34 #include "platform/PlatformExport.h" | 34 #include "platform/PlatformExport.h" |
35 #include "platform/heap/AddressSanitizer.h" | 35 #include "platform/heap/AddressSanitizer.h" |
36 #include "platform/heap/ThreadState.h" | 36 #include "platform/heap/ThreadState.h" |
37 #include "platform/heap/Visitor.h" | 37 #include "platform/heap/Visitor.h" |
38 #include "public/platform/WebThread.h" | 38 #include "public/platform/WebThread.h" |
39 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
40 #include "wtf/Atomics.h" | |
40 #include "wtf/HashCountedSet.h" | 41 #include "wtf/HashCountedSet.h" |
41 #include "wtf/LinkedHashSet.h" | 42 #include "wtf/LinkedHashSet.h" |
42 #include "wtf/ListHashSet.h" | 43 #include "wtf/ListHashSet.h" |
43 #include "wtf/OwnPtr.h" | 44 #include "wtf/OwnPtr.h" |
44 #include "wtf/PassRefPtr.h" | 45 #include "wtf/PassRefPtr.h" |
45 #include "wtf/ThreadSafeRefCounted.h" | 46 #include "wtf/ThreadSafeRefCounted.h" |
46 | 47 |
47 #include <stdint.h> | 48 #include <stdint.h> |
48 | 49 |
49 // FIXME: We temporarily disable parallel marking because the current | 50 // FIXME: We temporarily disable parallel marking because the current |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 #endif | 110 #endif |
110 | 111 |
111 const int numberOfPagesToConsiderForCoalescing = 100; | 112 const int numberOfPagesToConsiderForCoalescing = 100; |
112 | 113 |
113 enum CallbackInvocationMode { | 114 enum CallbackInvocationMode { |
114 GlobalMarking, | 115 GlobalMarking, |
115 ThreadLocalMarking, | 116 ThreadLocalMarking, |
116 }; | 117 }; |
117 | 118 |
118 class CallbackStack; | 119 class CallbackStack; |
119 class HeapStats; | |
120 class PageMemory; | 120 class PageMemory; |
121 template<ThreadAffinity affinity> class ThreadLocalPersistents; | 121 template<ThreadAffinity affinity> class ThreadLocalPersistents; |
122 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr ait<T>::Affinity > > class Persistent; | 122 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr ait<T>::Affinity > > class Persistent; |
123 | 123 |
124 #if ENABLE(GC_PROFILE_HEAP) | 124 #if ENABLE(GC_PROFILE_HEAP) |
125 class TracedValue; | 125 class TracedValue; |
126 #endif | 126 #endif |
127 | 127 |
128 PLATFORM_EXPORT size_t osPageSize(); | 128 PLATFORM_EXPORT size_t osPageSize(); |
129 | 129 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } | 256 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } |
257 | 257 |
258 Header* heapObjectHeader() | 258 Header* heapObjectHeader() |
259 { | 259 { |
260 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he aderPadding<Header>(); | 260 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he aderPadding<Header>(); |
261 return reinterpret_cast<Header*>(headerAddress); | 261 return reinterpret_cast<Header*>(headerAddress); |
262 } | 262 } |
263 | 263 |
264 bool isMarked(); | 264 bool isMarked(); |
265 void unmark(); | 265 void unmark(); |
266 void getStatsForTesting(HeapStats&); | 266 size_t objectPayloadSizeForTesting(); |
267 void mark(Visitor*); | 267 void mark(Visitor*); |
268 void finalize(); | 268 void finalize(); |
269 void setDeadMark(); | 269 void setDeadMark(); |
270 virtual void markOrphaned() | 270 virtual void markOrphaned() |
271 { | 271 { |
272 // Zap the payload with a recognizable value to detect any incorrect | 272 // Zap the payload with a recognizable value to detect any incorrect |
273 // cross thread pointer usage. | 273 // cross thread pointer usage. |
274 memset(payload(), orphanedZapValue, payloadSize()); | 274 memset(payload(), orphanedZapValue, payloadSize()); |
275 BaseHeapPage::markOrphaned(); | 275 BaseHeapPage::markOrphaned(); |
276 } | 276 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 return address() + sizeof(*this) + headerPadding<Header>(); | 527 return address() + sizeof(*this) + headerPadding<Header>(); |
528 } | 528 } |
529 | 529 |
530 static size_t payloadSize() | 530 static size_t payloadSize() |
531 { | 531 { |
532 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header >()) & ~allocationMask; | 532 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header >()) & ~allocationMask; |
533 } | 533 } |
534 | 534 |
535 Address end() { return payload() + payloadSize(); } | 535 Address end() { return payload() + payloadSize(); } |
536 | 536 |
537 void getStatsForTesting(HeapStats&); | 537 size_t objectPayloadSizeForTesting(); |
538 void clearLiveAndMarkDead(); | 538 void clearLiveAndMarkDead(); |
539 void sweep(HeapStats*, ThreadHeap<Header>*); | 539 void sweep(ThreadHeap<Header>*); |
540 void clearObjectStartBitMap(); | 540 void clearObjectStartBitMap(); |
541 void finalize(Header*); | 541 void finalize(Header*); |
542 virtual void checkAndMarkPointer(Visitor*, Address) override; | 542 virtual void checkAndMarkPointer(Visitor*, Address) override; |
543 #if ENABLE(GC_PROFILE_MARKING) | 543 #if ENABLE(GC_PROFILE_MARKING) |
544 const GCInfo* findGCInfo(Address) override; | 544 const GCInfo* findGCInfo(Address) override; |
545 #endif | 545 #endif |
546 #if ENABLE(GC_PROFILE_HEAP) | 546 #if ENABLE(GC_PROFILE_HEAP) |
547 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 547 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
548 #endif | 548 #endif |
549 | 549 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
696 #if ENABLE(GC_PROFILE_MARKING) | 696 #if ENABLE(GC_PROFILE_MARKING) |
697 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; | 697 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; |
698 #endif | 698 #endif |
699 | 699 |
700 #if ENABLE(GC_PROFILE_HEAP) | 700 #if ENABLE(GC_PROFILE_HEAP) |
701 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; | 701 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; |
702 #endif | 702 #endif |
703 | 703 |
704 // Sweep this part of the Blink heap. This finalizes dead objects | 704 // Sweep this part of the Blink heap. This finalizes dead objects |
705 // and builds freelists for all the unused memory. | 705 // and builds freelists for all the unused memory. |
706 virtual void sweep(HeapStats*) = 0; | 706 virtual void sweep() = 0; |
707 virtual void postSweepProcessing() = 0; | 707 virtual void postSweepProcessing() = 0; |
708 | 708 |
709 virtual void clearFreeLists() = 0; | 709 virtual void clearFreeLists() = 0; |
710 virtual void clearLiveAndMarkDead() = 0; | 710 virtual void clearLiveAndMarkDead() = 0; |
711 | 711 |
712 virtual void makeConsistentForSweeping() = 0; | 712 virtual void makeConsistentForSweeping() = 0; |
713 #if ENABLE(ASSERT) | 713 #if ENABLE(ASSERT) |
714 virtual bool isConsistentForSweeping() = 0; | 714 virtual bool isConsistentForSweeping() = 0; |
715 #endif | 715 #endif |
716 virtual void getStatsForTesting(HeapStats&) = 0; | 716 virtual size_t objectPayloadSizeForTesting() = 0; |
717 | 717 |
718 virtual void updateRemainingAllocationSize() = 0; | 718 virtual void updateRemainingAllocationSize() = 0; |
719 | 719 |
720 virtual void prepareHeapForTermination() = 0; | 720 virtual void prepareHeapForTermination() = 0; |
721 | 721 |
722 virtual int normalPageCount() = 0; | 722 virtual int normalPageCount() = 0; |
723 | 723 |
724 virtual PassOwnPtr<BaseHeap> split(int normalPages) = 0; | 724 virtual PassOwnPtr<BaseHeap> split(int normalPages) = 0; |
725 virtual void merge(PassOwnPtr<BaseHeap> other) = 0; | 725 virtual void merge(PassOwnPtr<BaseHeap> other) = 0; |
726 }; | 726 }; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
766 virtual void cleanupPages() override; | 766 virtual void cleanupPages() override; |
767 | 767 |
768 virtual BaseHeapPage* heapPageFromAddress(Address) override; | 768 virtual BaseHeapPage* heapPageFromAddress(Address) override; |
769 #if ENABLE(GC_PROFILE_MARKING) | 769 #if ENABLE(GC_PROFILE_MARKING) |
770 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) override; | 770 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) override; |
771 #endif | 771 #endif |
772 #if ENABLE(GC_PROFILE_HEAP) | 772 #if ENABLE(GC_PROFILE_HEAP) |
773 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 773 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
774 #endif | 774 #endif |
775 | 775 |
776 virtual void sweep(HeapStats*) override; | 776 virtual void sweep() override; |
777 virtual void postSweepProcessing() override; | 777 virtual void postSweepProcessing() override; |
778 | 778 |
779 virtual void clearFreeLists() override; | 779 virtual void clearFreeLists() override; |
780 virtual void clearLiveAndMarkDead() override; | 780 virtual void clearLiveAndMarkDead() override; |
781 | 781 |
782 virtual void makeConsistentForSweeping() override; | 782 virtual void makeConsistentForSweeping() override; |
783 #if ENABLE(ASSERT) | 783 #if ENABLE(ASSERT) |
784 virtual bool isConsistentForSweeping() override; | 784 virtual bool isConsistentForSweeping() override; |
785 #endif | 785 #endif |
786 virtual void getStatsForTesting(HeapStats&) override; | 786 virtual size_t objectPayloadSizeForTesting() override; |
787 | 787 |
788 virtual void updateRemainingAllocationSize() override; | 788 virtual void updateRemainingAllocationSize() override; |
789 | 789 |
790 ThreadState* threadState() { return m_threadState; } | 790 ThreadState* threadState() { return m_threadState; } |
791 HeapStats& stats() { return m_threadState->stats(); } | |
792 | 791 |
793 void addToFreeList(Address address, size_t size) | 792 void addToFreeList(Address address, size_t size) |
794 { | 793 { |
795 ASSERT(heapPageFromAddress(address)); | 794 ASSERT(heapPageFromAddress(address)); |
796 ASSERT(heapPageFromAddress(address + size - 1)); | 795 ASSERT(heapPageFromAddress(address + size - 1)); |
797 m_freeList.addToFreeList(address, size); | 796 m_freeList.addToFreeList(address, size); |
798 } | 797 } |
799 | 798 |
800 inline Address allocate(size_t, const GCInfo*); | 799 inline Address allocate(size_t, const GCInfo*); |
801 inline static size_t roundedAllocationSize(size_t size) | 800 inline static size_t roundedAllocationSize(size_t size) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 bool allocateFromFreeList(size_t); | 833 bool allocateFromFreeList(size_t); |
835 | 834 |
836 void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**); | 835 void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**); |
837 void allocatePage(const GCInfo*); | 836 void allocatePage(const GCInfo*); |
838 | 837 |
839 #if ENABLE(ASSERT) | 838 #if ENABLE(ASSERT) |
840 bool pagesToBeSweptContains(Address); | 839 bool pagesToBeSweptContains(Address); |
841 bool pagesAllocatedDuringSweepingContains(Address); | 840 bool pagesAllocatedDuringSweepingContains(Address); |
842 #endif | 841 #endif |
843 | 842 |
844 void sweepNormalPages(HeapStats*); | 843 void sweepNormalPages(); |
845 void sweepLargePages(HeapStats*); | 844 void sweepLargePages(); |
846 bool coalesce(size_t); | 845 bool coalesce(size_t); |
847 | 846 |
848 Address m_currentAllocationPoint; | 847 Address m_currentAllocationPoint; |
849 size_t m_remainingAllocationSize; | 848 size_t m_remainingAllocationSize; |
850 size_t m_lastRemainingAllocationSize; | 849 size_t m_lastRemainingAllocationSize; |
851 | 850 |
852 HeapPage<Header>* m_firstPage; | 851 HeapPage<Header>* m_firstPage; |
853 LargeHeapObject<Header>* m_firstLargeHeapObject; | 852 LargeHeapObject<Header>* m_firstLargeHeapObject; |
854 | 853 |
855 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; | 854 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
956 static void dumpPathToObjectOnNextGC(void* p); | 955 static void dumpPathToObjectOnNextGC(void* p); |
957 | 956 |
958 // Forcibly find GCInfo of the object at Address. | 957 // Forcibly find GCInfo of the object at Address. |
959 // This is slow and should only be used for debug purposes. | 958 // This is slow and should only be used for debug purposes. |
960 // It involves finding the heap page and scanning the heap page for an objec t header. | 959 // It involves finding the heap page and scanning the heap page for an objec t header. |
961 static const GCInfo* findGCInfo(Address); | 960 static const GCInfo* findGCInfo(Address); |
962 | 961 |
963 static String createBacktraceString(); | 962 static String createBacktraceString(); |
964 #endif | 963 #endif |
965 | 964 |
966 // Collect heap stats for all threads attached to the Blink | 965 static size_t objectPayloadSizeForTesting(); |
967 // garbage collector. Should only be called during garbage | |
968 // collection where threads are known to be at safe points. | |
969 static void getStats(HeapStats*); | |
970 | |
971 static void getStatsForTesting(HeapStats*); | |
972 | 966 |
973 static void getHeapSpaceSize(uint64_t*, uint64_t*); | 967 static void getHeapSpaceSize(uint64_t*, uint64_t*); |
974 | 968 |
975 static void makeConsistentForSweeping(); | 969 static void makeConsistentForSweeping(); |
976 | 970 |
977 #if ENABLE(ASSERT) | 971 #if ENABLE(ASSERT) |
978 static bool isConsistentForSweeping(); | 972 static bool isConsistentForSweeping(); |
979 #endif | 973 #endif |
980 | 974 |
981 static void flushHeapDoesNotContainCache(); | 975 static void flushHeapDoesNotContainCache(); |
982 | 976 |
983 // Return true if the last GC found a pointer into a heap page | 977 // Return true if the last GC found a pointer into a heap page |
984 // during conservative scanning. | 978 // during conservative scanning. |
985 static bool lastGCWasConservative() { return s_lastGCWasConservative; } | 979 static bool lastGCWasConservative() { return s_lastGCWasConservative; } |
986 | 980 |
987 static FreePagePool* freePagePool() { return s_freePagePool; } | 981 static FreePagePool* freePagePool() { return s_freePagePool; } |
988 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } | 982 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } |
989 | 983 |
990 // This look-up uses the region search tree and a negative contains cache to | 984 // This look-up uses the region search tree and a negative contains cache to |
991 // provide an efficient mapping from arbitrary addresses to the containing | 985 // provide an efficient mapping from arbitrary addresses to the containing |
992 // heap-page if one exists. | 986 // heap-page if one exists. |
993 static BaseHeapPage* lookup(Address); | 987 static BaseHeapPage* lookup(Address); |
994 static void addPageMemoryRegion(PageMemoryRegion*); | 988 static void addPageMemoryRegion(PageMemoryRegion*); |
995 static void removePageMemoryRegion(PageMemoryRegion*); | 989 static void removePageMemoryRegion(PageMemoryRegion*); |
996 | 990 |
991 static void resetAllocatedObjectSize() { s_allocatedObjectSize = 0; } | |
sof
2014/11/14 12:44:20
Add a comment to make it clearer why this doesn't
haraken
2014/11/14 15:15:00
Added ASSERT(ThreadState::isAnyThreadInGC()).
sof
2014/11/14 16:37:21
An assert is even better. I suppose there isn't a
haraken
2014/11/17 01:05:02
Done.
| |
992 static void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&s_allocat edObjectSize, delta); } | |
993 static void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&s_al locatedObjectSize, delta); } | |
994 static size_t allocatedObjectSize() { return s_allocatedObjectSize; } | |
995 static void resetLiveObjectSize() { s_liveObjectSize = 0; } | |
996 static void increaseLiveObjectSize(size_t delta) { atomicAdd(&s_liveObjectSi ze, delta); } | |
997 static size_t liveObjectSize() { return s_liveObjectSize; } | |
998 static void increaseAllocatedSpace(size_t delta) { atomicAdd(&s_allocatedSpa ce, delta); } | |
999 static void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&s_allocat edSpace, delta); } | |
1000 static size_t allocatedSpace() { return s_allocatedSpace; } | |
1001 | |
997 private: | 1002 private: |
998 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 1003 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
999 // by base addresses. | 1004 // by base addresses. |
1000 class RegionTree { | 1005 class RegionTree { |
1001 public: | 1006 public: |
1002 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (0), m_right(0) { } | 1007 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (0), m_right(0) { } |
1003 ~RegionTree() | 1008 ~RegionTree() |
1004 { | 1009 { |
1005 delete m_left; | 1010 delete m_left; |
1006 delete m_right; | 1011 delete m_right; |
(...skipping 12 matching lines...) Expand all Loading... | |
1019 static CallbackStack* s_markingStack; | 1024 static CallbackStack* s_markingStack; |
1020 static CallbackStack* s_postMarkingCallbackStack; | 1025 static CallbackStack* s_postMarkingCallbackStack; |
1021 static CallbackStack* s_weakCallbackStack; | 1026 static CallbackStack* s_weakCallbackStack; |
1022 static CallbackStack* s_ephemeronStack; | 1027 static CallbackStack* s_ephemeronStack; |
1023 static HeapDoesNotContainCache* s_heapDoesNotContainCache; | 1028 static HeapDoesNotContainCache* s_heapDoesNotContainCache; |
1024 static bool s_shutdownCalled; | 1029 static bool s_shutdownCalled; |
1025 static bool s_lastGCWasConservative; | 1030 static bool s_lastGCWasConservative; |
1026 static FreePagePool* s_freePagePool; | 1031 static FreePagePool* s_freePagePool; |
1027 static OrphanedPagePool* s_orphanedPagePool; | 1032 static OrphanedPagePool* s_orphanedPagePool; |
1028 static RegionTree* s_regionTree; | 1033 static RegionTree* s_regionTree; |
1034 static size_t s_allocatedSpace; | |
1035 static size_t s_allocatedObjectSize; | |
1036 static size_t s_liveObjectSize; | |
1029 friend class ThreadState; | 1037 friend class ThreadState; |
1030 }; | 1038 }; |
1031 | 1039 |
1032 // The NoAllocationScope class is used in debug mode to catch unwanted | 1040 // The NoAllocationScope class is used in debug mode to catch unwanted |
1033 // allocations. E.g. allocations during GC. | 1041 // allocations. E.g. allocations during GC. |
1034 template<ThreadAffinity Affinity> | 1042 template<ThreadAffinity Affinity> |
1035 class NoAllocationScope { | 1043 class NoAllocationScope { |
1036 public: | 1044 public: |
1037 NoAllocationScope() : m_active(true) { enter(); } | 1045 NoAllocationScope() : m_active(true) { enter(); } |
1038 | 1046 |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2418 }; | 2426 }; |
2419 | 2427 |
2420 template<typename T> | 2428 template<typename T> |
2421 struct IfWeakMember<WeakMember<T> > { | 2429 struct IfWeakMember<WeakMember<T> > { |
2422 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } | 2430 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } |
2423 }; | 2431 }; |
2424 | 2432 |
2425 } // namespace blink | 2433 } // namespace blink |
2426 | 2434 |
2427 #endif // Heap_h | 2435 #endif // Heap_h |
OLD | NEW |