diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-10-26 18:34:33 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-31 16:54:02 +0100 |
commit | b883652a834663de04cc23bf05c7942d15a240a2 (patch) | |
tree | 97576ccb508c4b0725f9fb595642b1c445fec22c /Userland/DevTools | |
parent | 8e1f882ac938c813e497a866498b8da31a956ccd (diff) | |
download | serenity-b883652a834663de04cc23bf05c7942d15a240a2.zip |
Profiler: Cache parsed DWARF debug information in disassembly view
This changes browsing through disassembled functions in Profiler from a
painfully sluggish experience into quite a swift one. It's especially
true for profiling the kernel, as it has more than 10 megabytes of DWARF
data to churn through.
Diffstat (limited to 'Userland/DevTools')
-rw-r--r-- | Userland/DevTools/Profiler/DisassemblyModel.cpp | 8 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/Process.cpp | 9 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/Process.h | 4 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/Profile.cpp | 1 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/Profile.h | 1 |
5 files changed, 19 insertions, 4 deletions
diff --git a/Userland/DevTools/Profiler/DisassemblyModel.cpp b/Userland/DevTools/Profiler/DisassemblyModel.cpp index 3fe4da9c20..6ac30d28df 100644 --- a/Userland/DevTools/Profiler/DisassemblyModel.cpp +++ b/Userland/DevTools/Profiler/DisassemblyModel.cpp @@ -54,7 +54,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) , m_node(node) { FlatPtr base_address = 0; - OwnPtr<Debug::DebugInfo> debug_info; + const Debug::DebugInfo* debug_info; const ELF::Image* elf; if (auto maybe_kernel_base = Symbolication::kernel_base(); maybe_kernel_base.has_value() && m_node.address() >= *maybe_kernel_base) { if (!g_kernel_debuginfo_object.has_value()) @@ -63,7 +63,9 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) elf = try_load_kernel_binary(); if (elf == nullptr) return; - debug_info = make<Debug::DebugInfo>(g_kernel_debuginfo_object->elf, String::empty(), base_address); + if (g_kernel_debug_info == nullptr) + g_kernel_debug_info = make<Debug::DebugInfo>(g_kernel_debuginfo_object->elf, String::empty(), base_address); + debug_info = g_kernel_debug_info.ptr(); } else { auto& process = node.process(); auto library_data = process.library_metadata.library_containing(node.address()); @@ -73,7 +75,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) } base_address = library_data->base; elf = &library_data->object->elf; - debug_info = make<Debug::DebugInfo>(library_data->object->elf, String::empty(), base_address); + debug_info = &library_data->load_debug_info(base_address); } VERIFY(elf != nullptr); diff --git a/Userland/DevTools/Profiler/Process.cpp b/Userland/DevTools/Profiler/Process.cpp index d48b1b257a..af9a4d2a9d 100644 --- a/Userland/DevTools/Profiler/Process.cpp +++ b/Userland/DevTools/Profiler/Process.cpp @@ -102,10 +102,17 @@ void LibraryMetadata::handle_mmap(FlatPtr base, size_t size, const String& name) if (!mapped_object) return; } - m_libraries.set(path_string, adopt_own(*new Library { base, size, path_string, mapped_object })); + m_libraries.set(path_string, adopt_own(*new Library { base, size, path_string, mapped_object, {} })); } } +const Debug::DebugInfo& LibraryMetadata::Library::load_debug_info(FlatPtr base_address) const +{ + if (debug_info == nullptr) + debug_info = make<Debug::DebugInfo>(object->elf, String::empty(), base_address); + return *debug_info.ptr(); +} + String LibraryMetadata::Library::symbolicate(FlatPtr ptr, u32* offset) const { if (!object) diff --git a/Userland/DevTools/Profiler/Process.h b/Userland/DevTools/Profiler/Process.h index 6c4c3357c3..322a5ff098 100644 --- a/Userland/DevTools/Profiler/Process.h +++ b/Userland/DevTools/Profiler/Process.h @@ -11,6 +11,7 @@ #include <AK/MappedFile.h> #include <AK/OwnPtr.h> #include <AK/Vector.h> +#include <LibDebug/DebugInfo.h> #include <LibELF/Image.h> namespace Profiler { @@ -29,8 +30,11 @@ public: size_t size; String name; MappedObject* object { nullptr }; + // This is loaded lazily because we only need it in disassembly view + mutable OwnPtr<Debug::DebugInfo> debug_info; String symbolicate(FlatPtr, u32* offset) const; + const Debug::DebugInfo& load_debug_info(FlatPtr base_address) const; }; void handle_mmap(FlatPtr base, size_t size, const String& name); diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index e40785e2a4..0fdc742651 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -212,6 +212,7 @@ void Profile::rebuild_tree() } Optional<MappedObject> g_kernel_debuginfo_object; +OwnPtr<Debug::DebugInfo> g_kernel_debug_info; Result<NonnullOwnPtr<Profile>, String> Profile::load_from_perfcore_file(const StringView& path) { diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index 4549c90288..df89641da4 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -29,6 +29,7 @@ namespace Profiler { extern Optional<MappedObject> g_kernel_debuginfo_object; +extern OwnPtr<Debug::DebugInfo> g_kernel_debug_info; class ProfileNode : public RefCounted<ProfileNode> { public: |