Index: Source/platform/heap/Heap.cpp |
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
index 784bdc0613d7d4ded03de783d25768611c835425..0635deefb2cedbaaf9b315872b551fc4392c5991 100644 |
--- a/Source/platform/heap/Heap.cpp |
+++ b/Source/platform/heap/Heap.cpp |
@@ -681,12 +681,16 @@ void ThreadHeap<Header>::cleanupPages() |
clearFreeLists(); |
// Add the ThreadHeap's pages to the orphanedPagePool. |
- for (HeapPage<Header>* page = m_firstPage; page; page = page->m_next) |
+ for (HeapPage<Header>* page = m_firstPage; page; page = page->m_next) { |
+ Heap::decreaseAllocatedSpace(blinkPageSize); |
Heap::orphanedPagePool()->addOrphanedPage(m_index, page); |
+ } |
m_firstPage = 0; |
- for (LargeHeapObject<Header>* largeObject = m_firstLargeHeapObject; largeObject; largeObject = largeObject->m_next) |
+ for (LargeHeapObject<Header>* largeObject = m_firstLargeHeapObject; largeObject; largeObject = largeObject->m_next) { |
+ Heap::decreaseAllocatedSpace(largeObject->size()); |
Heap::orphanedPagePool()->addOrphanedPage(m_index, largeObject); |
+ } |
m_firstLargeHeapObject = 0; |
} |
@@ -694,7 +698,7 @@ template<typename Header> |
void ThreadHeap<Header>::updateRemainingAllocationSize() |
{ |
if (m_lastRemainingAllocationSize > remainingAllocationSize()) { |
- stats().increaseObjectSpace(m_lastRemainingAllocationSize - remainingAllocationSize()); |
+ Heap::increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remainingAllocationSize()); |
m_lastRemainingAllocationSize = remainingAllocationSize(); |
} |
ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize()); |
@@ -962,7 +966,7 @@ bool ThreadHeap<Header>::coalesce(size_t minSize) |
ASSERT(basicHeader->size() < blinkPagePayloadSize()); |
if (basicHeader->isPromptlyFreed()) { |
- stats().decreaseObjectSpace(reinterpret_cast<Header*>(basicHeader)->size()); |
+ Heap::decreaseAllocatedObjectSize(reinterpret_cast<Header*>(basicHeader)->size()); |
size_t size = basicHeader->size(); |
ASSERT(size >= sizeof(Header)); |
#if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) |
@@ -1046,8 +1050,8 @@ Address ThreadHeap<Header>::allocateLargeObject(size_t size, const GCInfo* gcInf |
ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); |
ASAN_POISON_MEMORY_REGION(largeObject->address() + largeObject->size(), allocationGranularity); |
largeObject->link(&m_firstLargeHeapObject); |
- stats().increaseAllocatedSpace(largeObject->size()); |
- stats().increaseObjectSpace(largeObject->size()); |
+ Heap::increaseAllocatedSpace(largeObject->size()); |
+ Heap::increaseAllocatedObjectSize(largeObject->size()); |
return result; |
} |
@@ -1056,6 +1060,7 @@ void ThreadHeap<Header>::freeLargeObject(LargeHeapObject<Header>* object, LargeH |
{ |
object->unlink(previousNext); |
object->finalize(); |
+ Heap::decreaseAllocatedSpace(object->size()); |
// Unpoison the object header and allocationGranularity bytes after the |
// object before freeing. |
@@ -1277,6 +1282,8 @@ void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo* gcInfo) |
template <typename Header> |
void ThreadHeap<Header>::removePageFromHeap(HeapPage<Header>* page) |
{ |
+ Heap::decreaseAllocatedSpace(blinkPageSize); |
+ |
MutexLocker locker(m_threadState->sweepMutex()); |
if (page->terminating()) { |
// The thread is shutting down so this page is being removed as part |
@@ -1330,6 +1337,7 @@ void ThreadHeap<Header>::allocatePage(const GCInfo* gcInfo) |
} |
} |
HeapPage<Header>* page = new (pageMemory->writableStart()) HeapPage<Header>(pageMemory, this, gcInfo); |
+ Heap::increaseAllocatedSpace(blinkPageSize); |
// Use a separate list for pages allocated during sweeping to make |
// sure that we do not accidentally sweep objects that have been |
// allocated during sweeping. |
@@ -1367,17 +1375,19 @@ bool ThreadHeap<Header>::pagesAllocatedDuringSweepingContains(Address address) |
#endif |
template<typename Header> |
-void ThreadHeap<Header>::getStatsForTesting(HeapStats& stats) |
+size_t ThreadHeap<Header>::objectPayloadSizeForTesting() |
{ |
ASSERT(!m_firstPageAllocatedDuringSweeping); |
+ size_t objectPayloadSize = 0; |
for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) |
- page->getStatsForTesting(stats); |
+ objectPayloadSize += page->objectPayloadSizeForTesting(); |
for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; current = current->next()) |
- current->getStatsForTesting(stats); |
+ objectPayloadSize += current->objectPayloadSizeForTesting(); |
+ return objectPayloadSize; |
} |
template<typename Header> |
-void ThreadHeap<Header>::sweepNormalPages(HeapStats* stats) |
+void ThreadHeap<Header>::sweepNormalPages() |
{ |
TRACE_EVENT0("blink_gc", "ThreadHeap::sweepNormalPages"); |
HeapPage<Header>* page = m_firstPage; |
@@ -1393,7 +1403,7 @@ void ThreadHeap<Header>::sweepNormalPages(HeapStats* stats) |
HeapPage<Header>::unlink(this, unused, previousNext); |
--m_numberOfNormalPages; |
} else { |
- page->sweep(stats, this); |
+ page->sweep(this); |
previousNext = &page->m_next; |
previous = page; |
page = page->next(); |
@@ -1402,14 +1412,13 @@ void ThreadHeap<Header>::sweepNormalPages(HeapStats* stats) |
} |
template<typename Header> |
-void ThreadHeap<Header>::sweepLargePages(HeapStats* stats) |
+void ThreadHeap<Header>::sweepLargePages() |
{ |
TRACE_EVENT0("blink_gc", "ThreadHeap::sweepLargePages"); |
LargeHeapObject<Header>** previousNext = &m_firstLargeHeapObject; |
for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current;) { |
if (current->isMarked()) { |
- stats->increaseAllocatedSpace(current->size()); |
- stats->increaseObjectSpace(current->size()); |
+ Heap::increaseMarkedObjectSize(current->size()); |
current->unmark(); |
previousNext = ¤t->m_next; |
current = current->next(); |
@@ -1430,7 +1439,7 @@ void ThreadHeap<Header>::sweepLargePages(HeapStats* stats) |
#define STRICT_ASAN_FINALIZATION_CHECKING 0 |
template<typename Header> |
-void ThreadHeap<Header>::sweep(HeapStats* stats) |
+void ThreadHeap<Header>::sweep() |
{ |
ASSERT(isConsistentForSweeping()); |
#if defined(ADDRESS_SANITIZER) && STRICT_ASAN_FINALIZATION_CHECKING |
@@ -1441,8 +1450,8 @@ void ThreadHeap<Header>::sweep(HeapStats* stats) |
for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) |
page->poisonUnmarkedObjects(); |
#endif |
- sweepNormalPages(stats); |
- sweepLargePages(stats); |
+ sweepNormalPages(); |
+ sweepLargePages(); |
} |
template<typename Header> |
@@ -1542,7 +1551,6 @@ HeapPage<Header>::HeapPage(PageMemory* storage, ThreadHeap<Header>* heap, const |
COMPILE_ASSERT(!(sizeof(HeapPage<Header>) & allocationMask), page_header_incorrectly_aligned); |
m_objectStartBitMapComputed = false; |
ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
- heap->stats().increaseAllocatedSpace(blinkPageSize); |
} |
template<typename Header> |
@@ -1560,20 +1568,21 @@ void HeapPage<Header>::unlink(ThreadHeap<Header>* heap, HeapPage* unused, HeapPa |
} |
template<typename Header> |
-void HeapPage<Header>::getStatsForTesting(HeapStats& stats) |
+size_t HeapPage<Header>::objectPayloadSizeForTesting() |
{ |
- stats.increaseAllocatedSpace(blinkPageSize); |
+ size_t objectPayloadSize = 0; |
Address headerAddress = payload(); |
ASSERT(headerAddress != end()); |
do { |
Header* header = reinterpret_cast<Header*>(headerAddress); |
if (!header->isFree()) { |
- stats.increaseObjectSpace(header->payloadSize()); |
+ objectPayloadSize += header->payloadSize(); |
} |
ASSERT(header->size() < blinkPagePayloadSize()); |
headerAddress += header->size(); |
ASSERT(headerAddress <= end()); |
} while (headerAddress < end()); |
+ return objectPayloadSize; |
} |
template<typename Header> |
@@ -1584,10 +1593,9 @@ bool HeapPage<Header>::isEmpty() |
} |
template<typename Header> |
-void HeapPage<Header>::sweep(HeapStats* stats, ThreadHeap<Header>* heap) |
+void HeapPage<Header>::sweep(ThreadHeap<Header>* heap) |
{ |
clearObjectStartBitMap(); |
- stats->increaseAllocatedSpace(blinkPageSize); |
Address startOfGap = payload(); |
for (Address headerAddress = startOfGap; headerAddress < end(); ) { |
BasicObjectHeader* basicHeader = reinterpret_cast<BasicObjectHeader*>(headerAddress); |
@@ -1633,7 +1641,7 @@ void HeapPage<Header>::sweep(HeapStats* stats, ThreadHeap<Header>* heap) |
heap->addToFreeList(startOfGap, headerAddress - startOfGap); |
header->unmark(); |
headerAddress += header->size(); |
- stats->increaseObjectSpace(header->size()); |
+ Heap::increaseMarkedObjectSize(header->size()); |
startOfGap = headerAddress; |
} |
if (startOfGap != end()) |
@@ -1859,10 +1867,9 @@ inline bool HeapPage<FinalizedHeapObjectHeader>::hasVTable(FinalizedHeapObjectHe |
} |
template<typename Header> |
-void LargeHeapObject<Header>::getStatsForTesting(HeapStats& stats) |
+size_t LargeHeapObject<Header>::objectPayloadSizeForTesting() |
{ |
- stats.increaseAllocatedSpace(size()); |
- stats.increaseObjectSpace(payloadSize()); |
+ return payloadSize(); |
} |
#if ENABLE(GC_PROFILE_HEAP) |
@@ -2202,6 +2209,9 @@ void Heap::init() |
s_freePagePool = new FreePagePool(); |
s_orphanedPagePool = new OrphanedPagePool(); |
s_markingThreads = new Vector<OwnPtr<WebThread>>(); |
+ s_allocatedObjectSize = 0; |
+ s_allocatedSpace = 0; |
+ s_markedObjectSize = 0; |
if (Platform::current()) { |
int processors = Platform::current()->numberOfProcessors(); |
int numberOfMarkingThreads = std::min(processors, maxNumberOfMarkingThreads); |
@@ -2245,6 +2255,7 @@ void Heap::doShutdown() |
delete s_regionTree; |
s_regionTree = 0; |
ThreadState::shutdown(); |
+ ASSERT(Heap::allocatedSpace() == 0); |
} |
BaseHeapPage* Heap::contains(Address address) |
@@ -2497,6 +2508,9 @@ void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::Cause |
s_lastGCWasConservative = false; |
+ Heap::resetMarkedObjectSize(); |
+ Heap::resetAllocatedObjectSize(); |
+ |
TRACE_EVENT2("blink_gc", "Heap::collectGarbage", |
"precise", stackState == ThreadState::NoHeapPointersOnStack, |
"forced", cause == ThreadState::ForcedGC); |
@@ -2555,12 +2569,9 @@ void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::Cause |
#endif |
if (Platform::current()) { |
- uint64_t objectSpaceSize; |
- uint64_t allocatedSpaceSize; |
- getHeapSpaceSize(&objectSpaceSize, &allocatedSpaceSize); |
Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50); |
- Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", objectSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); |
- Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", allocatedSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); |
+ Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap::allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); |
+ Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", Heap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); |
} |
if (state->isMainThread()) |
@@ -2799,31 +2810,17 @@ void ThreadHeap<Header>::merge(PassOwnPtr<BaseHeap> splitOffBase) |
} |
} |
-void Heap::getHeapSpaceSize(uint64_t* objectSpaceSize, uint64_t* allocatedSpaceSize) |
-{ |
- *objectSpaceSize = 0; |
- *allocatedSpaceSize = 0; |
- ASSERT(ThreadState::isAnyThreadInGC()); |
- ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads(); |
- typedef ThreadState::AttachedThreadStateSet::iterator ThreadStateIterator; |
- for (ThreadStateIterator it = threads.begin(), end = threads.end(); it != end; ++it) { |
- *objectSpaceSize += (*it)->stats().totalObjectSpace(); |
- *allocatedSpaceSize += (*it)->stats().totalAllocatedSpace(); |
- } |
-} |
- |
-void Heap::getStatsForTesting(HeapStats* stats) |
+size_t Heap::objectPayloadSizeForTesting() |
{ |
- stats->clear(); |
+ size_t objectPayloadSize = 0; |
ASSERT(ThreadState::isAnyThreadInGC()); |
makeConsistentForSweeping(); |
ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads(); |
typedef ThreadState::AttachedThreadStateSet::iterator ThreadStateIterator; |
for (ThreadStateIterator it = threads.begin(), end = threads.end(); it != end; ++it) { |
- HeapStats temp; |
- (*it)->getStatsForTesting(temp); |
- stats->add(&temp); |
+ objectPayloadSize += (*it)->objectPayloadSizeForTesting(); |
} |
+ return objectPayloadSize; |
} |
#if ENABLE(ASSERT) |
@@ -3009,5 +3006,8 @@ bool Heap::s_lastGCWasConservative = false; |
FreePagePool* Heap::s_freePagePool; |
OrphanedPagePool* Heap::s_orphanedPagePool; |
Heap::RegionTree* Heap::s_regionTree = 0; |
+size_t Heap::s_allocatedObjectSize = 0; |
+size_t Heap::s_allocatedSpace = 0; |
+size_t Heap::s_markedObjectSize = 0; |
} // namespace blink |