diff options
Diffstat (limited to 'compiler-rt/lib/asan/asan_memory_profile.cc')
-rw-r--r-- | compiler-rt/lib/asan/asan_memory_profile.cc | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/compiler-rt/lib/asan/asan_memory_profile.cc b/compiler-rt/lib/asan/asan_memory_profile.cc index c55264ef5d5..c2678b974fe 100644 --- a/compiler-rt/lib/asan/asan_memory_profile.cc +++ b/compiler-rt/lib/asan/asan_memory_profile.cc @@ -32,18 +32,20 @@ struct AllocationSite { class HeapProfile { public: HeapProfile() : allocations_(1024) {} - void Insert(u32 id, uptr size) { - total_allocated_ += size; - total_count_++; - // Linear lookup will be good enough for most cases (although not all). - for (uptr i = 0; i < allocations_.size(); i++) { - if (allocations_[i].id == id) { - allocations_[i].total_size += size; - allocations_[i].count++; - return; - } + + void ProcessChunk(const AsanChunkView& cv) { + if (cv.IsAllocated()) { + total_allocated_user_size_ += cv.UsedSize(); + total_allocated_count_++; + u32 id = cv.GetAllocStackId(); + if (id) + Insert(id, cv.UsedSize()); + } else if (cv.IsQuarantined()) { + total_quarantined_user_size_ += cv.UsedSize(); + total_quarantined_count_++; + } else { + total_other_count_++; } - allocations_.push_back({id, size, 1}); } void Print(uptr top_percent) { @@ -51,34 +53,50 @@ class HeapProfile { [](const AllocationSite &a, const AllocationSite &b) { return a.total_size > b.total_size; }); - CHECK(total_allocated_); + CHECK(total_allocated_user_size_); uptr total_shown = 0; - Printf("Live Heap Allocations: %zd bytes from %zd allocations; " - "showing top %zd%%\n", total_allocated_, total_count_, top_percent); + Printf("Live Heap Allocations: %zd bytes in %zd chunks; quarantined: " + "%zd bytes in %zd chunks; %zd other chunks; total chunks: %zd; " + "showing top %zd%%\n", + total_allocated_user_size_, total_allocated_count_, + total_quarantined_user_size_, total_quarantined_count_, + total_other_count_, total_allocated_count_ + + total_quarantined_count_ + total_other_count_, top_percent); for (uptr i = 0; i < allocations_.size(); i++) { auto &a = allocations_[i]; Printf("%zd byte(s) (%zd%%) in %zd allocation(s)\n", a.total_size, - a.total_size * 100 / total_allocated_, a.count); + a.total_size * 100 / total_allocated_user_size_, a.count); StackDepotGet(a.id).Print(); total_shown += a.total_size; - if (total_shown * 100 / total_allocated_ > top_percent) + if (total_shown * 100 / total_allocated_user_size_ > top_percent) break; } } private: - uptr total_allocated_ = 0; - uptr total_count_ = 0; + uptr total_allocated_user_size_ = 0; + uptr total_allocated_count_ = 0; + uptr total_quarantined_user_size_ = 0; + uptr total_quarantined_count_ = 0; + uptr total_other_count_ = 0; InternalMmapVector<AllocationSite> allocations_; + + void Insert(u32 id, uptr size) { + // Linear lookup will be good enough for most cases (although not all). + for (uptr i = 0; i < allocations_.size(); i++) { + if (allocations_[i].id == id) { + allocations_[i].total_size += size; + allocations_[i].count++; + return; + } + } + allocations_.push_back({id, size, 1}); + } }; static void ChunkCallback(uptr chunk, void *arg) { - HeapProfile *hp = reinterpret_cast<HeapProfile*>(arg); - AsanChunkView cv = FindHeapChunkByAllocBeg(chunk); - if (!cv.IsAllocated()) return; - u32 id = cv.GetAllocStackId(); - if (!id) return; - hp->Insert(id, cv.UsedSize()); + reinterpret_cast<HeapProfile*>(arg)->ProcessChunk( + FindHeapChunkByAllocBeg(chunk)); } static void MemoryProfileCB(const SuspendedThreadsList &suspended_threads_list, |