Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/platform/heap/HeapPage.cpp

Issue 2684633004: Remove orphaned pages from Oilpan (Closed)
Patch Set: temp Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 : m_firstPage(nullptr), 109 : m_firstPage(nullptr),
110 m_firstUnsweptPage(nullptr), 110 m_firstUnsweptPage(nullptr),
111 m_threadState(state), 111 m_threadState(state),
112 m_index(index) {} 112 m_index(index) {}
113 113
114 BaseArena::~BaseArena() { 114 BaseArena::~BaseArena() {
115 ASSERT(!m_firstPage); 115 ASSERT(!m_firstPage);
116 ASSERT(!m_firstUnsweptPage); 116 ASSERT(!m_firstUnsweptPage);
117 } 117 }
118 118
119 void BaseArena::cleanupPages() { 119 void BaseArena::removeAllPages() {
120 clearFreeLists(); 120 clearFreeLists();
121 121
122 ASSERT(!m_firstUnsweptPage); 122 ASSERT(!m_firstUnsweptPage);
123 // Add the BaseArena's pages to the orphanedPagePool. 123 while (m_firstPage) {
124 for (BasePage* page = m_firstPage; page; page = page->next()) { 124 BasePage* page = m_firstPage;
125 getThreadState()->heap().heapStats().decreaseAllocatedSpace(page->size()); 125 page->unlink(&m_firstPage);
126 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage( 126 page->removeFromHeap();
127 arenaIndex(), page);
128 } 127 }
129 m_firstPage = nullptr;
130 } 128 }
131 129
132 void BaseArena::takeSnapshot(const String& dumpBaseName, 130 void BaseArena::takeSnapshot(const String& dumpBaseName,
133 ThreadState::GCSnapshotInfo& info) { 131 ThreadState::GCSnapshotInfo& info) {
134 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName" 132 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName"
135 base::trace_event::MemoryAllocatorDump* allocatorDump = 133 base::trace_event::MemoryAllocatorDump* allocatorDump =
136 BlinkGCMemoryDumpProvider::instance() 134 BlinkGCMemoryDumpProvider::instance()
137 ->createMemoryAllocatorDumpForCurrentGC(dumpBaseName); 135 ->createMemoryAllocatorDumpForCurrentGC(dumpBaseName);
138 size_t pageCount = 0; 136 size_t pageCount = 0;
139 BasePage::HeapSnapshotInfo heapInfo; 137 BasePage::HeapSnapshotInfo heapInfo;
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 for (size_t i = 0; i < page->payloadSize(); i++) 648 for (size_t i = 0; i < page->payloadSize(); i++)
651 address[i] = reuseAllowedZapValue; 649 address[i] = reuseAllowedZapValue;
652 ASAN_POISON_MEMORY_REGION(page->payload(), page->payloadSize()); 650 ASAN_POISON_MEMORY_REGION(page->payload(), page->payloadSize());
653 #endif 651 #endif
654 addToFreeList(page->payload(), page->payloadSize()); 652 addToFreeList(page->payload(), page->payloadSize());
655 } 653 }
656 654
657 void NormalPageArena::freePage(NormalPage* page) { 655 void NormalPageArena::freePage(NormalPage* page) {
658 getThreadState()->heap().heapStats().decreaseAllocatedSpace(page->size()); 656 getThreadState()->heap().heapStats().decreaseAllocatedSpace(page->size());
659 657
660 if (page->terminating()) { 658 PageMemory* memory = page->storage();
661 // The thread is shutting down and this page is being removed as a part 659 page->~NormalPage();
662 // of the thread local GC. In that case the object could be traced in 660 getThreadState()->heap().getFreePagePool()->addFreePage(arenaIndex(), memory);
663 // the next global GC if there is a dangling pointer from a live thread
664 // heap to this dead thread heap. To guard against this, we put the
665 // page into the orphaned page pool and zap the page memory. This
666 // ensures that tracing the dangling pointer in the next global GC just
667 // crashes instead of causing use-after-frees. After the next global
668 // GC, the orphaned pages are removed.
669 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage(
670 arenaIndex(), page);
671 } else {
672 PageMemory* memory = page->storage();
673 page->~NormalPage();
674 getThreadState()->heap().getFreePagePool()->addFreePage(arenaIndex(),
675 memory);
676 }
677 } 661 }
678 662
679 bool NormalPageArena::coalesce() { 663 bool NormalPageArena::coalesce() {
680 // Don't coalesce arenas if there are not enough promptly freed entries 664 // Don't coalesce arenas if there are not enough promptly freed entries
681 // to be coalesced. 665 // to be coalesced.
682 // 666 //
683 // FIXME: This threshold is determined just to optimize blink_perf 667 // FIXME: This threshold is determined just to optimize blink_perf
684 // benchmarks. Coalescing is very sensitive to the threashold and 668 // benchmarks. Coalescing is very sensitive to the threashold and
685 // we need further investigations on the coalescing scheme. 669 // we need further investigations on the coalescing scheme.
686 if (m_promptlyFreedSize < 1024 * 1024) 670 if (m_promptlyFreedSize < 1024 * 1024)
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 object->payloadSize()); 1032 object->payloadSize());
1049 getThreadState()->heap().heapStats().decreaseAllocatedSpace(object->size()); 1033 getThreadState()->heap().heapStats().decreaseAllocatedSpace(object->size());
1050 1034
1051 // Unpoison the object header and allocationGranularity bytes after the 1035 // Unpoison the object header and allocationGranularity bytes after the
1052 // object before freeing. 1036 // object before freeing.
1053 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), 1037 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(),
1054 sizeof(HeapObjectHeader)); 1038 sizeof(HeapObjectHeader));
1055 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(), 1039 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(),
1056 allocationGranularity); 1040 allocationGranularity);
1057 1041
1058 if (object->terminating()) { 1042 PageMemory* memory = object->storage();
1059 ASSERT(ThreadState::current()->isTerminating()); 1043 object->~LargeObjectPage();
1060 // The thread is shutting down and this page is being removed as a part 1044 delete memory;
1061 // of the thread local GC. In that case the object could be traced in
1062 // the next global GC if there is a dangling pointer from a live thread
1063 // heap to this dead thread heap. To guard against this, we put the
1064 // page into the orphaned page pool and zap the page memory. This
1065 // ensures that tracing the dangling pointer in the next global GC just
1066 // crashes instead of causing use-after-frees. After the next global
1067 // GC, the orphaned pages are removed.
1068 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage(
1069 arenaIndex(), object);
1070 } else {
1071 ASSERT(!ThreadState::current()->isTerminating());
1072 PageMemory* memory = object->storage();
1073 object->~LargeObjectPage();
1074 delete memory;
1075 }
1076 } 1045 }
1077 1046
1078 Address LargeObjectArena::lazySweepPages(size_t allocationSize, 1047 Address LargeObjectArena::lazySweepPages(size_t allocationSize,
1079 size_t gcInfoIndex) { 1048 size_t gcInfoIndex) {
1080 Address result = nullptr; 1049 Address result = nullptr;
1081 size_t sweptSize = 0; 1050 size_t sweptSize = 0;
1082 while (m_firstUnsweptPage) { 1051 while (m_firstUnsweptPage) {
1083 BasePage* page = m_firstUnsweptPage; 1052 BasePage* page = m_firstUnsweptPage;
1084 if (page->isEmpty()) { 1053 if (page->isEmpty()) {
1085 sweptSize += static_cast<LargeObjectPage*>(page)->payloadSize() + 1054 sweptSize += static_cast<LargeObjectPage*>(page)->payloadSize() +
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 1240
1272 BasePage::BasePage(PageMemory* storage, BaseArena* arena) 1241 BasePage::BasePage(PageMemory* storage, BaseArena* arena)
1273 : m_storage(storage), 1242 : m_storage(storage),
1274 m_arena(arena), 1243 m_arena(arena),
1275 m_next(nullptr), 1244 m_next(nullptr),
1276 m_terminating(false), 1245 m_terminating(false),
1277 m_swept(true) { 1246 m_swept(true) {
1278 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); 1247 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this)));
1279 } 1248 }
1280 1249
1281 void BasePage::markOrphaned() {
1282 m_arena = nullptr;
1283 m_terminating = false;
1284 // Since we zap the page payload for orphaned pages we need to mark it as
1285 // unused so a conservative pointer won't interpret the object headers.
1286 storage()->markUnused();
1287 }
1288
1289 NormalPage::NormalPage(PageMemory* storage, BaseArena* arena) 1250 NormalPage::NormalPage(PageMemory* storage, BaseArena* arena)
1290 : BasePage(storage, arena), m_objectStartBitMapComputed(false) { 1251 : BasePage(storage, arena), m_objectStartBitMapComputed(false) {
1291 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); 1252 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this)));
1292 } 1253 }
1293 1254
1294 size_t NormalPage::objectPayloadSizeForTesting() { 1255 size_t NormalPage::objectPayloadSizeForTesting() {
1295 size_t objectPayloadSize = 0; 1256 size_t objectPayloadSize = 0;
1296 Address headerAddress = payload(); 1257 Address headerAddress = payload();
1297 markAsSwept(); 1258 markAsSwept();
1298 ASSERT(headerAddress != payloadEnd()); 1259 ASSERT(headerAddress != payloadEnd());
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 MarkedPointerCallbackForTesting callback) { 1631 MarkedPointerCallbackForTesting callback) {
1671 DCHECK(contains(address)); 1632 DCHECK(contains(address));
1672 HeapObjectHeader* header = findHeaderFromAddress(address); 1633 HeapObjectHeader* header = findHeaderFromAddress(address);
1673 if (!header) 1634 if (!header)
1674 return; 1635 return;
1675 if (!callback(header)) 1636 if (!callback(header))
1676 markPointer(visitor, header); 1637 markPointer(visitor, header);
1677 } 1638 }
1678 #endif 1639 #endif
1679 1640
1680 void NormalPage::markOrphaned() {
1681 // Zap the payload with a recognizable value to detect any incorrect
1682 // cross thread pointer usage.
1683 #if defined(ADDRESS_SANITIZER)
1684 // This needs to zap poisoned memory as well.
1685 // Force unpoison memory before memset.
1686 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize());
1687 #endif
1688 OrphanedPagePool::asanDisabledMemset(
1689 payload(), OrphanedPagePool::orphanedZapValue, payloadSize());
1690 BasePage::markOrphaned();
1691 }
1692
1693 void NormalPage::takeSnapshot(base::trace_event::MemoryAllocatorDump* pageDump, 1641 void NormalPage::takeSnapshot(base::trace_event::MemoryAllocatorDump* pageDump,
1694 ThreadState::GCSnapshotInfo& info, 1642 ThreadState::GCSnapshotInfo& info,
1695 HeapSnapshotInfo& heapInfo) { 1643 HeapSnapshotInfo& heapInfo) {
1696 HeapObjectHeader* header = nullptr; 1644 HeapObjectHeader* header = nullptr;
1697 size_t liveCount = 0; 1645 size_t liveCount = 0;
1698 size_t deadCount = 0; 1646 size_t deadCount = 0;
1699 size_t freeCount = 0; 1647 size_t freeCount = 0;
1700 size_t liveSize = 0; 1648 size_t liveSize = 0;
1701 size_t deadSize = 0; 1649 size_t deadSize = 0;
1702 size_t freeSize = 0; 1650 size_t freeSize = 0;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 Address address, 1749 Address address,
1802 MarkedPointerCallbackForTesting callback) { 1750 MarkedPointerCallbackForTesting callback) {
1803 DCHECK(contains(address)); 1751 DCHECK(contains(address));
1804 if (!containedInObjectPayload(address)) 1752 if (!containedInObjectPayload(address))
1805 return; 1753 return;
1806 if (!callback(heapObjectHeader())) 1754 if (!callback(heapObjectHeader()))
1807 markPointer(visitor, heapObjectHeader()); 1755 markPointer(visitor, heapObjectHeader());
1808 } 1756 }
1809 #endif 1757 #endif
1810 1758
1811 void LargeObjectPage::markOrphaned() {
1812 // Zap the payload with a recognizable value to detect any incorrect
1813 // cross thread pointer usage.
1814 OrphanedPagePool::asanDisabledMemset(
1815 payload(), OrphanedPagePool::orphanedZapValue, payloadSize());
1816 BasePage::markOrphaned();
1817 }
1818
1819 void LargeObjectPage::takeSnapshot( 1759 void LargeObjectPage::takeSnapshot(
1820 base::trace_event::MemoryAllocatorDump* pageDump, 1760 base::trace_event::MemoryAllocatorDump* pageDump,
1821 ThreadState::GCSnapshotInfo& info, 1761 ThreadState::GCSnapshotInfo& info,
1822 HeapSnapshotInfo&) { 1762 HeapSnapshotInfo&) {
1823 size_t liveSize = 0; 1763 size_t liveSize = 0;
1824 size_t deadSize = 0; 1764 size_t deadSize = 0;
1825 size_t liveCount = 0; 1765 size_t liveCount = 0;
1826 size_t deadCount = 0; 1766 size_t deadCount = 0;
1827 HeapObjectHeader* header = heapObjectHeader(); 1767 HeapObjectHeader* header = heapObjectHeader();
1828 size_t gcInfoIndex = header->gcInfoIndex(); 1768 size_t gcInfoIndex = header->gcInfoIndex();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 1826
1887 m_hasEntries = true; 1827 m_hasEntries = true;
1888 size_t index = hash(address); 1828 size_t index = hash(address);
1889 ASSERT(!(index & 1)); 1829 ASSERT(!(index & 1));
1890 Address cachePage = roundToBlinkPageStart(address); 1830 Address cachePage = roundToBlinkPageStart(address);
1891 m_entries[index + 1] = m_entries[index]; 1831 m_entries[index + 1] = m_entries[index];
1892 m_entries[index] = cachePage; 1832 m_entries[index] = cachePage;
1893 } 1833 }
1894 1834
1895 } // namespace blink 1835 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/HeapPage.h ('k') | third_party/WebKit/Source/platform/heap/PagePool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698