From 9dc78338ad962236af8b663bb739a3532536532a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 2 Feb 2020 20:59:26 +0100 Subject: [PATCH] ProfileViewer: Only show live allocations by default For memory profiles, we now keep track of which allocations are still live at the end of the selected timeline range and only show those. This is really cool, I have to admit. :^) --- DevTools/ProfileViewer/Profile.cpp | 34 ++++++++++++++++++++++++++++++ DevTools/ProfileViewer/Profile.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/DevTools/ProfileViewer/Profile.cpp b/DevTools/ProfileViewer/Profile.cpp index 716dc2f528..2f00350382 100644 --- a/DevTools/ProfileViewer/Profile.cpp +++ b/DevTools/ProfileViewer/Profile.cpp @@ -26,6 +26,7 @@ #include "Profile.h" #include "ProfileModel.h" +#include #include #include #include @@ -57,6 +58,15 @@ Profile::Profile(const JsonArray& json) Sample sample; sample.timestamp = sample_object.get("timestamp").to_number(); + sample.type = sample_object.get("type").to_string(); + + if (sample.type == "malloc") { + sample.ptr = sample_object.get("ptr").to_number(); + sample.size = sample_object.get("size").to_number(); + } else if (sample.type == "free") { + sample.ptr = sample_object.get("ptr").to_number(); + } + auto frames_value = sample_object.get("frames"); auto& frames_array = frames_value.as_array(); @@ -110,6 +120,8 @@ void Profile::rebuild_tree() return new_root; }; + HashTable live_allocations; + for (auto& sample : m_samples) { if (has_timestamp_filter_range()) { auto timestamp = sample.timestamp; @@ -117,6 +129,25 @@ void Profile::rebuild_tree() continue; } + if (sample.type == "malloc") + live_allocations.set(sample.ptr); + else if (sample.type == "free") + live_allocations.remove(sample.ptr); + } + + for (auto& sample : m_samples) { + if (has_timestamp_filter_range()) { + auto timestamp = sample.timestamp; + if (timestamp < m_timestamp_filter_range_start || timestamp > m_timestamp_filter_range_end) + continue; + } + + if (sample.type == "malloc" && !live_allocations.contains(sample.ptr)) + continue; + + if (sample.type == "free") + continue; + ProfileNode* node = nullptr; auto for_each_frame = [&](Callback callback) @@ -198,6 +229,9 @@ OwnPtr Profile::load_from_perfcore_file(const StringView& path) JsonObject object; object.set("timestamp", perf_event.get("timestamp")); + object.set("type", perf_event.get("type")); + object.set("ptr", perf_event.get("ptr")); + object.set("size", perf_event.get("size")); JsonArray frames_array; auto stack_array = perf_event.get("stack").as_array(); diff --git a/DevTools/ProfileViewer/Profile.h b/DevTools/ProfileViewer/Profile.h index 4ccde6f94a..3988b720e3 100644 --- a/DevTools/ProfileViewer/Profile.h +++ b/DevTools/ProfileViewer/Profile.h @@ -120,6 +120,9 @@ public: struct Sample { u64 timestamp { 0 }; + String type; + uintptr_t ptr { 0 }; + size_t size { 0 }; bool in_kernel { false }; Vector frames; };