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 13 matching lines...) Expand all Loading... |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "platform/heap/HeapPage.h" | 32 #include "platform/heap/HeapPage.h" |
33 | 33 |
| 34 #include "base/trace_event/memory_allocator_dump.h" |
| 35 #include "base/trace_event/process_memory_dump.h" |
34 #include "platform/ScriptForbiddenScope.h" | 36 #include "platform/ScriptForbiddenScope.h" |
35 #include "platform/Task.h" | 37 #include "platform/Task.h" |
36 #include "platform/TraceEvent.h" | 38 #include "platform/TraceEvent.h" |
37 #include "platform/heap/BlinkGCMemoryDumpProvider.h" | 39 #include "platform/heap/BlinkGCMemoryDumpProvider.h" |
38 #include "platform/heap/CallbackStack.h" | 40 #include "platform/heap/CallbackStack.h" |
39 #include "platform/heap/Heap.h" | 41 #include "platform/heap/Heap.h" |
40 #include "platform/heap/MarkingVisitor.h" | 42 #include "platform/heap/MarkingVisitor.h" |
41 #include "platform/heap/PageMemory.h" | 43 #include "platform/heap/PageMemory.h" |
42 #include "platform/heap/PagePool.h" | 44 #include "platform/heap/PagePool.h" |
43 #include "platform/heap/SafePoint.h" | 45 #include "platform/heap/SafePoint.h" |
44 #include "platform/heap/ThreadState.h" | 46 #include "platform/heap/ThreadState.h" |
45 #include "public/platform/Platform.h" | 47 #include "public/platform/Platform.h" |
46 #include "public/platform/WebMemoryAllocatorDump.h" | |
47 #include "public/platform/WebProcessMemoryDump.h" | |
48 #include "wtf/Assertions.h" | 48 #include "wtf/Assertions.h" |
49 #include "wtf/ContainerAnnotations.h" | 49 #include "wtf/ContainerAnnotations.h" |
50 #include "wtf/LeakAnnotations.h" | 50 #include "wtf/LeakAnnotations.h" |
51 #include "wtf/MainThread.h" | 51 #include "wtf/MainThread.h" |
52 #include "wtf/PageAllocator.h" | 52 #include "wtf/PageAllocator.h" |
53 #include "wtf/Partitions.h" | 53 #include "wtf/Partitions.h" |
54 #include "wtf/PassOwnPtr.h" | 54 #include "wtf/PassOwnPtr.h" |
55 #if ENABLE(GC_PROFILING) | 55 #if ENABLE(GC_PROFILING) |
56 #include "platform/TracedValue.h" | 56 #include "platform/TracedValue.h" |
57 #include "wtf/HashMap.h" | 57 #include "wtf/HashMap.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 static_cast<LargeObjectPage*>(largePage)->setIsVectorBackingPage(); \ | 90 static_cast<LargeObjectPage*>(largePage)->setIsVectorBackingPage(); \ |
91 } | 91 } |
92 #else | 92 #else |
93 #define ENABLE_ASAN_CONTAINER_ANNOTATIONS 0 | 93 #define ENABLE_ASAN_CONTAINER_ANNOTATIONS 0 |
94 #define ASAN_RETIRE_CONTAINER_ANNOTATION(payload, payloadSize) | 94 #define ASAN_RETIRE_CONTAINER_ANNOTATION(payload, payloadSize) |
95 #define ASAN_MARK_LARGE_VECTOR_CONTAINER(heap, largeObject) | 95 #define ASAN_MARK_LARGE_VECTOR_CONTAINER(heap, largeObject) |
96 #endif | 96 #endif |
97 | 97 |
98 namespace blink { | 98 namespace blink { |
99 | 99 |
| 100 using base::trace_event::MemoryAllocatorDump; |
| 101 |
100 #if ENABLE(GC_PROFILING) | 102 #if ENABLE(GC_PROFILING) |
101 static String classOf(const void* object) | 103 static String classOf(const void* object) |
102 { | 104 { |
103 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_
cast<void*>(object)))) | 105 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_
cast<void*>(object)))) |
104 return gcInfo->className(); | 106 return gcInfo->className(); |
105 return "unknown"; | 107 return "unknown"; |
106 } | 108 } |
107 #endif | 109 #endif |
108 | 110 |
109 #if ENABLE(ASSERT) | 111 #if ENABLE(ASSERT) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 for (BasePage* page = m_firstPage; page; page = page->next()) { | 149 for (BasePage* page = m_firstPage; page; page = page->next()) { |
148 Heap::decreaseAllocatedSpace(page->size()); | 150 Heap::decreaseAllocatedSpace(page->size()); |
149 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); | 151 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); |
150 } | 152 } |
151 m_firstPage = nullptr; | 153 m_firstPage = nullptr; |
152 } | 154 } |
153 | 155 |
154 void BaseHeap::takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotI
nfo& info) | 156 void BaseHeap::takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotI
nfo& info) |
155 { | 157 { |
156 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName" | 158 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName" |
157 WebMemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance(
)->createMemoryAllocatorDumpForCurrentGC(dumpBaseName); | 159 MemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance()->
createMemoryAllocatorDumpForCurrentGC(dumpBaseName); |
158 size_t pageIndex = 0; | 160 size_t pageIndex = 0; |
159 size_t heapTotalFreeSize = 0; | 161 size_t heapTotalFreeSize = 0; |
160 size_t heapTotalFreeCount = 0; | 162 size_t heapTotalFreeCount = 0; |
161 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { | 163 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { |
162 size_t heapPageFreeSize = 0; | 164 size_t heapPageFreeSize = 0; |
163 size_t heapPageFreeCount = 0; | 165 size_t heapPageFreeCount = 0; |
164 page->takeSnapshot(dumpBaseName, pageIndex, info, &heapPageFreeSize, &he
apPageFreeCount); | 166 page->takeSnapshot(dumpBaseName, pageIndex, info, &heapPageFreeSize, &he
apPageFreeCount); |
165 heapTotalFreeSize += heapPageFreeSize; | 167 heapTotalFreeSize += heapPageFreeSize; |
166 heapTotalFreeCount += heapPageFreeCount; | 168 heapTotalFreeCount += heapPageFreeCount; |
167 pageIndex++; | 169 pageIndex++; |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 if (page->contains(address)) | 473 if (page->contains(address)) |
472 return true; | 474 return true; |
473 } | 475 } |
474 return false; | 476 return false; |
475 } | 477 } |
476 #endif | 478 #endif |
477 | 479 |
478 void NormalPageHeap::takeFreelistSnapshot(const String& dumpName) | 480 void NormalPageHeap::takeFreelistSnapshot(const String& dumpName) |
479 { | 481 { |
480 if (m_freeList.takeSnapshot(dumpName)) { | 482 if (m_freeList.takeSnapshot(dumpName)) { |
481 WebMemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instanc
e()->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets"); | 483 MemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instance()
->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets"); |
482 WebMemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance(
)->createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages"); | 484 MemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance()->
createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages"); |
483 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->AddOw
nershipEdge(pagesDump->guid(), bucketsDump->guid()); | 485 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->AddOw
nershipEdge(pagesDump->guid(), bucketsDump->guid()); |
484 } | 486 } |
485 } | 487 } |
486 | 488 |
487 #if ENABLE(GC_PROFILING) | 489 #if ENABLE(GC_PROFILING) |
488 void NormalPageHeap::snapshotFreeList(TracedValue& json) | 490 void NormalPageHeap::snapshotFreeList(TracedValue& json) |
489 { | 491 { |
490 json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); | 492 json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); |
491 json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocatio
nCount) / m_allocationCount); | 493 json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocatio
nCount) / m_allocationCount); |
492 json.setInteger("inlineAllocationCount", m_inlineAllocationCount); | 494 json.setInteger("inlineAllocationCount", m_inlineAllocationCount); |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 bool didDumpBucketStats = false; | 1135 bool didDumpBucketStats = false; |
1134 for (size_t i = 0; i < blinkPageSizeLog2; ++i) { | 1136 for (size_t i = 0; i < blinkPageSizeLog2; ++i) { |
1135 size_t entryCount = 0; | 1137 size_t entryCount = 0; |
1136 size_t freeSize = 0; | 1138 size_t freeSize = 0; |
1137 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next()
) { | 1139 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next()
) { |
1138 ++entryCount; | 1140 ++entryCount; |
1139 freeSize += entry->size(); | 1141 freeSize += entry->size(); |
1140 } | 1142 } |
1141 | 1143 |
1142 String dumpName = dumpBaseName + String::format("/buckets/bucket_%lu", s
tatic_cast<unsigned long>(1 << i)); | 1144 String dumpName = dumpBaseName + String::format("/buckets/bucket_%lu", s
tatic_cast<unsigned long>(1 << i)); |
1143 WebMemoryAllocatorDump* bucketDump = BlinkGCMemoryDumpProvider::instance
()->createMemoryAllocatorDumpForCurrentGC(dumpName); | 1145 MemoryAllocatorDump* bucketDump = BlinkGCMemoryDumpProvider::instance()-
>createMemoryAllocatorDumpForCurrentGC(dumpName); |
1144 bucketDump->AddScalar("free_count", "objects", entryCount); | 1146 bucketDump->AddScalar("free_count", "objects", entryCount); |
1145 bucketDump->AddScalar("free_size", "bytes", freeSize); | 1147 bucketDump->AddScalar("free_size", "bytes", freeSize); |
1146 didDumpBucketStats = true; | 1148 didDumpBucketStats = true; |
1147 } | 1149 } |
1148 return didDumpBucketStats; | 1150 return didDumpBucketStats; |
1149 } | 1151 } |
1150 | 1152 |
1151 #if ENABLE(GC_PROFILING) | 1153 #if ENABLE(GC_PROFILING) |
1152 void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& to
talFreeSize) const | 1154 void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& to
talFreeSize) const |
1153 { | 1155 { |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1482 // Force unpoison memory before memset. | 1484 // Force unpoison memory before memset. |
1483 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); | 1485 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); |
1484 #endif | 1486 #endif |
1485 OrphanedPagePool::asanDisabledMemset(payload(), OrphanedPagePool::orphanedZa
pValue, payloadSize()); | 1487 OrphanedPagePool::asanDisabledMemset(payload(), OrphanedPagePool::orphanedZa
pValue, payloadSize()); |
1486 BasePage::markOrphaned(); | 1488 BasePage::markOrphaned(); |
1487 } | 1489 } |
1488 | 1490 |
1489 void NormalPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadState::GC
SnapshotInfo& info, size_t* outFreeSize, size_t* outFreeCount) | 1491 void NormalPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadState::GC
SnapshotInfo& info, size_t* outFreeSize, size_t* outFreeCount) |
1490 { | 1492 { |
1491 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long>
(pageIndex))); | 1493 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long>
(pageIndex))); |
1492 WebMemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->cr
eateMemoryAllocatorDumpForCurrentGC(dumpName); | 1494 MemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->creat
eMemoryAllocatorDumpForCurrentGC(dumpName); |
1493 | 1495 |
1494 HeapObjectHeader* header = nullptr; | 1496 HeapObjectHeader* header = nullptr; |
1495 size_t liveCount = 0; | 1497 size_t liveCount = 0; |
1496 size_t deadCount = 0; | 1498 size_t deadCount = 0; |
1497 size_t freeCount = 0; | 1499 size_t freeCount = 0; |
1498 size_t liveSize = 0; | 1500 size_t liveSize = 0; |
1499 size_t deadSize = 0; | 1501 size_t deadSize = 0; |
1500 size_t freeSize = 0; | 1502 size_t freeSize = 0; |
1501 for (Address headerAddress = payload(); headerAddress < payloadEnd(); header
Address += header->size()) { | 1503 for (Address headerAddress = payload(); headerAddress < payloadEnd(); header
Address += header->size()) { |
1502 header = reinterpret_cast<HeapObjectHeader*>(headerAddress); | 1504 header = reinterpret_cast<HeapObjectHeader*>(headerAddress); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 { | 1703 { |
1702 // Zap the payload with a recognizable value to detect any incorrect | 1704 // Zap the payload with a recognizable value to detect any incorrect |
1703 // cross thread pointer usage. | 1705 // cross thread pointer usage. |
1704 OrphanedPagePool::asanDisabledMemset(payload(), OrphanedPagePool::orphanedZa
pValue, payloadSize()); | 1706 OrphanedPagePool::asanDisabledMemset(payload(), OrphanedPagePool::orphanedZa
pValue, payloadSize()); |
1705 BasePage::markOrphaned(); | 1707 BasePage::markOrphaned(); |
1706 } | 1708 } |
1707 | 1709 |
1708 void LargeObjectPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadStat
e::GCSnapshotInfo& info, size_t* outFreeSize, size_t* outFreeCount) | 1710 void LargeObjectPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadStat
e::GCSnapshotInfo& info, size_t* outFreeSize, size_t* outFreeCount) |
1709 { | 1711 { |
1710 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long>
(pageIndex))); | 1712 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long>
(pageIndex))); |
1711 WebMemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->cr
eateMemoryAllocatorDumpForCurrentGC(dumpName); | 1713 MemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->creat
eMemoryAllocatorDumpForCurrentGC(dumpName); |
1712 | 1714 |
1713 size_t liveSize = 0; | 1715 size_t liveSize = 0; |
1714 size_t deadSize = 0; | 1716 size_t deadSize = 0; |
1715 size_t liveCount = 0; | 1717 size_t liveCount = 0; |
1716 size_t deadCount = 0; | 1718 size_t deadCount = 0; |
1717 HeapObjectHeader* header = heapObjectHeader(); | 1719 HeapObjectHeader* header = heapObjectHeader(); |
1718 size_t gcInfoIndex = header->gcInfoIndex(); | 1720 size_t gcInfoIndex = header->gcInfoIndex(); |
1719 if (header->isMarked()) { | 1721 if (header->isMarked()) { |
1720 liveCount = 1; | 1722 liveCount = 1; |
1721 liveSize += header->payloadSize(); | 1723 liveSize += header->payloadSize(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 | 1842 |
1841 m_hasEntries = true; | 1843 m_hasEntries = true; |
1842 size_t index = hash(address); | 1844 size_t index = hash(address); |
1843 ASSERT(!(index & 1)); | 1845 ASSERT(!(index & 1)); |
1844 Address cachePage = roundToBlinkPageStart(address); | 1846 Address cachePage = roundToBlinkPageStart(address); |
1845 m_entries[index + 1] = m_entries[index]; | 1847 m_entries[index + 1] = m_entries[index]; |
1846 m_entries[index] = cachePage; | 1848 m_entries[index] = cachePage; |
1847 } | 1849 } |
1848 | 1850 |
1849 } // namespace blink | 1851 } // namespace blink |
OLD | NEW |