Index: Source/platform/heap/Heap.cpp |
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
index 6290a6d9ba803928b7d8350fb51f1a3d58a8c7d2..8173e34ef50d0899d3be5c43ad60e8c7be8a4332 100644 |
--- a/Source/platform/heap/Heap.cpp |
+++ b/Source/platform/heap/Heap.cpp |
@@ -548,6 +548,11 @@ ThreadHeap::ThreadHeap(ThreadState* state, int index) |
, m_threadState(state) |
, m_index(index) |
, m_promptlyFreedSize(0) |
+#if ENABLE(GC_PROFILING) |
+ , m_cumulativeAllocationSize(0) |
+ , m_allocationCount(0) |
+ , m_inlineAllocationCount(0) |
+#endif |
{ |
clearFreeLists(); |
} |
@@ -616,6 +621,10 @@ Address ThreadHeap::outOfLineAllocate(size_t allocationSize, size_t gcInfoIndex) |
ASSERT(allocationSize > remainingAllocationSize()); |
ASSERT(allocationSize >= allocationGranularity); |
+#if ENABLE(GC_PROFILING) |
+ m_threadState->snapshotFreeListIfNecessary(); |
+#endif |
+ |
// 1. If this allocation is big enough, allocate a large object. |
if (allocationSize >= largeObjectSizeThreshold) |
return allocateLargeObject(allocationSize, gcInfoIndex); |
@@ -1493,6 +1502,39 @@ void ThreadHeap::clearFreeLists() |
m_freeList.clear(); |
} |
+#if ENABLE(GC_PROFILING) |
+void ThreadHeap::snapshotFreeList(TracedValue& json) |
+{ |
+ json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); |
+ json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocationCount) / m_allocationCount); |
+ json.setInteger("inlineAllocationCount", m_inlineAllocationCount); |
+ json.setInteger("allocationCount", m_allocationCount); |
+ size_t pageCount = 0; |
+ size_t totalPageSize = 0; |
+ for (HeapPage* page = m_firstPage; page; page = page->next()) { |
+ ++pageCount; |
+ totalPageSize += page->payloadSize(); |
+ } |
+ json.setInteger("pageCount", pageCount); |
+ json.setInteger("totalPageSize", totalPageSize); |
+ |
+ FreeList::PerBucketFreeListStats bucketStats[blinkPageSizeLog2]; |
+ size_t totalFreeSize; |
+ m_freeList.getFreeSizeStats(bucketStats, totalFreeSize); |
+ json.setInteger("totalFreeSize", totalFreeSize); |
+ |
+ json.beginArray("perBucketEntryCount"); |
+ for (size_t i = 0; i < blinkPageSizeLog2; ++i) |
+ json.pushInteger(bucketStats[i].entryCount); |
+ json.endArray(); |
+ |
+ json.beginArray("perBucketFreeSize"); |
+ for (size_t i = 0; i < blinkPageSizeLog2; ++i) |
+ json.pushInteger(bucketStats[i].freeSize); |
+ json.endArray(); |
+} |
+#endif |
+ |
void FreeList::clear() |
{ |
m_biggestFreeListIndex = 0; |
@@ -1511,6 +1553,22 @@ int FreeList::bucketIndexForSize(size_t size) |
return index; |
} |
+#if ENABLE(GC_PROFILING) |
+void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalFreeSize) const |
+{ |
+ totalFreeSize = 0; |
+ for (size_t i = 0; i < blinkPageSizeLog2; i++) { |
+ size_t& entryCount = bucketStats[i].entryCount; |
+ size_t& freeSize = bucketStats[i].freeSize; |
+ for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next()) { |
+ ++entryCount; |
+ freeSize += entry->size(); |
+ } |
+ totalFreeSize += freeSize; |
+ } |
+} |
+#endif |
+ |
HeapPage::HeapPage(PageMemory* storage, ThreadHeap* heap) |
: BaseHeapPage(storage, heap) |
, m_next(nullptr) |