From 340180ba057096d8cca917d2774c5a75c4b15975 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 27 Feb 2021 17:45:41 +0100 Subject: [PATCH] Profiler: Move ELF object name to its own profile graph column This way you don't have to look at all the library names if you don't want to. Since we're pretty good about namespacing our things, the library names are slightly redundant information. --- Userland/DevTools/Profiler/Profile.cpp | 42 ++++++++++++++------- Userland/DevTools/Profiler/Profile.h | 20 +++++----- Userland/DevTools/Profiler/ProfileModel.cpp | 4 ++ Userland/DevTools/Profiler/ProfileModel.h | 1 + 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index 8e8e986841..bbed5cefcc 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -28,12 +28,12 @@ #include "DisassemblyModel.h" #include "ProfileModel.h" #include +#include #include #include #include #include #include -#include #include static void sort_profile_nodes(Vector>& nodes) @@ -77,14 +77,14 @@ void Profile::rebuild_tree() u32 filtered_event_count = 0; Vector> roots; - auto find_or_create_root = [&roots](const String& symbol, u32 address, u32 offset, u64 timestamp) -> ProfileNode& { + auto find_or_create_root = [&roots](FlyString object_name, String symbol, u32 address, u32 offset, u64 timestamp) -> ProfileNode& { for (size_t i = 0; i < roots.size(); ++i) { auto& root = roots[i]; if (root->symbol() == symbol) { return root; } } - auto new_root = ProfileNode::create(symbol, address, offset, timestamp); + auto new_root = ProfileNode::create(move(object_name), move(symbol), address, offset, timestamp); roots.append(new_root); return new_root; }; @@ -135,6 +135,7 @@ void Profile::rebuild_tree() if (!m_show_top_functions) { ProfileNode* node = nullptr; for_each_frame([&](const Frame& frame, bool is_innermost_frame) { + auto& object_name = frame.object_name; auto& symbol = frame.symbol; auto& address = frame.address; auto& offset = frame.offset; @@ -143,9 +144,9 @@ void Profile::rebuild_tree() return IterationDecision::Break; if (!node) - node = &find_or_create_root(symbol, address, offset, event.timestamp); + node = &find_or_create_root(object_name, symbol, address, offset, event.timestamp); else - node = &node->find_or_create_child(symbol, address, offset, event.timestamp); + node = &node->find_or_create_child(object_name, symbol, address, offset, event.timestamp); node->increment_event_count(); if (is_innermost_frame) { @@ -160,6 +161,7 @@ void Profile::rebuild_tree() ProfileNode* root = nullptr; for (size_t j = i; j < event.frames.size(); ++j) { auto& frame = event.frames.at(j); + auto& object_name = frame.object_name; auto& symbol = frame.symbol; auto& address = frame.address; auto& offset = frame.offset; @@ -167,11 +169,11 @@ void Profile::rebuild_tree() break; if (!node) { - node = &find_or_create_root(symbol, address, offset, event.timestamp); + node = &find_or_create_root(object_name, symbol, address, offset, event.timestamp); root = node; root->will_track_seen_events(m_events.size()); } else { - node = &node->find_or_create_child(symbol, address, offset, event.timestamp); + node = &node->find_or_create_child(object_name, symbol, address, offset, event.timestamp); } if (!root->has_seen_event(event_index)) { @@ -257,6 +259,7 @@ Result, String> Profile::load_from_perfcore_file(const St auto& frame = stack_array.at(i); auto ptr = frame.to_number(); u32 offset = 0; + FlyString object_name; String symbol; if (ptr >= 0xc0000000) { @@ -266,10 +269,15 @@ Result, String> Profile::load_from_perfcore_file(const St symbol = "??"; } } else { - symbol = library_metadata->symbolicate(ptr, offset); + if (auto* library = library_metadata->library_containing(ptr)) { + object_name = library->name; + symbol = library->elf.symbolicate(ptr - library->base, &offset); + } else { + symbol = "??"; + } } - event.frames.append({ symbol, ptr, offset }); + event.frames.append({ object_name, symbol, ptr, offset }); } if (event.frames.size() < 2) @@ -391,9 +399,17 @@ const Profile::LibraryMetadata::Library* Profile::LibraryMetadata::library_conta return nullptr; } -String Profile::LibraryMetadata::symbolicate(FlatPtr ptr, u32& offset) const +ProfileNode::ProfileNode(const String& object_name, String symbol, u32 address, u32 offset, u64 timestamp) + : m_symbol(move(symbol)) + , m_address(address) + , m_offset(offset) + , m_timestamp(timestamp) { - if (auto* library = library_containing(ptr)) - return String::formatted("[{}] {}", library->name, library->elf.symbolicate(ptr - library->base, &offset)); - return "??"; + String object; + if (object_name.ends_with(": .text")) { + object = object_name.view().substring_view(0, object_name.length() - 7); + } else { + object = object_name; + } + m_object_name = LexicalPath(object).basename(); } diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index 18a93c75a9..65ad5fb608 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include #include #include @@ -43,9 +44,9 @@ class DisassemblyModel; class ProfileNode : public RefCounted { public: - static NonnullRefPtr create(const String& symbol, u32 address, u32 offset, u64 timestamp) + static NonnullRefPtr create(FlyString object_name, String symbol, u32 address, u32 offset, u64 timestamp) { - return adopt(*new ProfileNode(symbol, address, offset, timestamp)); + return adopt(*new ProfileNode(move(object_name), move(symbol), address, offset, timestamp)); } // These functions are only relevant for root nodes @@ -57,6 +58,7 @@ public: bool has_seen_event(size_t event_index) const { return m_seen_events.get(event_index); } void did_see_event(size_t event_index) { m_seen_events.set(event_index, true); } + const FlyString& object_name() const { return m_object_name; } const String& symbol() const { return m_symbol; } u32 address() const { return m_address; } u32 offset() const { return m_offset; } @@ -77,7 +79,7 @@ public: m_children.append(child); } - ProfileNode& find_or_create_child(const String& symbol, u32 address, u32 offset, u64 timestamp) + ProfileNode& find_or_create_child(FlyString object_name, String symbol, u32 address, u32 offset, u64 timestamp) { for (size_t i = 0; i < m_children.size(); ++i) { auto& child = m_children[i]; @@ -85,7 +87,7 @@ public: return child; } } - auto new_child = ProfileNode::create(symbol, address, offset, timestamp); + auto new_child = ProfileNode::create(move(object_name), move(symbol), address, offset, timestamp); add_child(new_child); return new_child; }; @@ -109,15 +111,10 @@ public: } private: - explicit ProfileNode(const String& symbol, u32 address, u32 offset, u64 timestamp) - : m_symbol(symbol) - , m_address(address) - , m_offset(offset) - , m_timestamp(timestamp) - { - } + explicit ProfileNode(const String& object_name, String symbol, u32 address, u32 offset, u64 timestamp); ProfileNode* m_parent { nullptr }; + FlyString m_object_name; String m_symbol; u32 m_address { 0 }; u32 m_offset { 0 }; @@ -142,6 +139,7 @@ public: const Vector>& roots() const { return m_roots; } struct Frame { + FlyString object_name; String symbol; u32 address { 0 }; u32 offset { 0 }; diff --git a/Userland/DevTools/Profiler/ProfileModel.cpp b/Userland/DevTools/Profiler/ProfileModel.cpp index d9798069f1..4e1af6cfde 100644 --- a/Userland/DevTools/Profiler/ProfileModel.cpp +++ b/Userland/DevTools/Profiler/ProfileModel.cpp @@ -100,6 +100,8 @@ String ProfileModel::column_name(int column) const return m_profile.show_percentages() ? "% Samples" : "# Samples"; case Column::SelfCount: return m_profile.show_percentages() ? "% Self" : "# Self"; + case Column::ObjectName: + return "Object"; case Column::StackFrame: return "Stack Frame"; default: @@ -134,6 +136,8 @@ GUI::Variant ProfileModel::data(const GUI::ModelIndex& index, GUI::ModelRole rol return ((float)node->self_count() / (float)m_profile.filtered_event_count()) * 100.0f; return node->self_count(); } + if (index.column() == Column::ObjectName) + return node->object_name(); if (index.column() == Column::StackFrame) return node->symbol(); return {}; diff --git a/Userland/DevTools/Profiler/ProfileModel.h b/Userland/DevTools/Profiler/ProfileModel.h index 9b61dd5137..edf64c9fd7 100644 --- a/Userland/DevTools/Profiler/ProfileModel.h +++ b/Userland/DevTools/Profiler/ProfileModel.h @@ -40,6 +40,7 @@ public: enum Column { SampleCount, SelfCount, + ObjectName, StackFrame, __Count };