summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan/asan_memory_profile.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/asan/asan_memory_profile.cc')
-rw-r--r--compiler-rt/lib/asan/asan_memory_profile.cc66
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,
OpenPOWER on IntegriCloud