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 };