From a31ef54a2a97864187bba71618aed5abeaeef70a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 7 Apr 2020 16:41:42 +0200 Subject: LibELF: Cache symbol counts + demangled names (userspace only) To make repeated symbolication requests faster, we now cache the symbol count on ELFLoader instead of looking it up in the image each time. We also cache the demangled versions of names after looking them up the first time. This is a huge speedup for ProfileViewer. :^) --- Libraries/LibELF/ELFLoader.cpp | 26 ++++++++++++++++++-------- Libraries/LibELF/ELFLoader.h | 7 ++++++- 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'Libraries') diff --git a/Libraries/LibELF/ELFLoader.cpp b/Libraries/LibELF/ELFLoader.cpp index e5a30b31fe..b2952d1ad5 100644 --- a/Libraries/LibELF/ELFLoader.cpp +++ b/Libraries/LibELF/ELFLoader.cpp @@ -41,6 +41,7 @@ ELFLoader::ELFLoader(const u8* buffer, size_t size) : m_image(buffer, size) { + m_symbol_count = m_image.symbol_count(); } ELFLoader::~ELFLoader() @@ -152,7 +153,7 @@ char* ELFLoader::symbol_ptr(const char* name) String ELFLoader::symbolicate(u32 address, u32* out_offset) const { - if (!m_image.symbol_count()) { + if (!m_symbol_count) { if (out_offset) *out_offset = 0; return "??"; @@ -160,14 +161,14 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const SortedSymbol* sorted_symbols = nullptr; #ifdef KERNEL if (!m_sorted_symbols_region) { - m_sorted_symbols_region = MM.allocate_kernel_region(PAGE_ROUND_UP(m_image.symbol_count() * sizeof(SortedSymbol)), "Sorted symbols", Kernel::Region::Access::Read | Kernel::Region::Access::Write); + m_sorted_symbols_region = MM.allocate_kernel_region(PAGE_ROUND_UP(m_symbol_count * sizeof(SortedSymbol)), "Sorted symbols", Kernel::Region::Access::Read | Kernel::Region::Access::Write); sorted_symbols = (SortedSymbol*)m_sorted_symbols_region->vaddr().as_ptr(); size_t index = 0; m_image.for_each_symbol([&](auto& symbol) { sorted_symbols[index++] = { symbol.value(), symbol.name() }; return IterationDecision::Continue; }); - quick_sort(sorted_symbols, sorted_symbols + m_image.symbol_count(), [](auto& a, auto& b) { + quick_sort(sorted_symbols, sorted_symbols + m_symbol_count, [](auto& a, auto& b) { return a.address < b.address; }); } else { @@ -175,9 +176,9 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const } #else if (m_sorted_symbols.is_empty()) { - m_sorted_symbols.ensure_capacity(m_image.symbol_count()); + m_sorted_symbols.ensure_capacity(m_symbol_count); m_image.for_each_symbol([this](auto& symbol) { - m_sorted_symbols.append({ symbol.value(), symbol.name() }); + m_sorted_symbols.append({ symbol.value(), symbol.name(), {} }); return IterationDecision::Continue; }); quick_sort(m_sorted_symbols, [](auto& a, auto& b) { @@ -187,7 +188,7 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const sorted_symbols = m_sorted_symbols.data(); #endif - for (size_t i = 0; i < m_image.symbol_count(); ++i) { + for (size_t i = 0; i < m_symbol_count; ++i) { if (sorted_symbols[i].address > address) { if (i == 0) { if (out_offset) @@ -195,11 +196,20 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const return "!!"; } auto& symbol = sorted_symbols[i - 1]; + +#ifdef KERNEL + auto demangled_name = demangle(symbol.name); +#else + auto& demangled_name = symbol.demangled_name; + if (demangled_name.is_null()) + demangled_name = demangle(symbol.name); +#endif + if (out_offset) { *out_offset = address - symbol.address; - return demangle(symbol.name); + return demangled_name; } - return String::format("%s +%u", demangle(symbol.name).characters(), address - symbol.address); + return String::format("%s +%u", demangled_name.characters(), address - symbol.address); } } if (out_offset) diff --git a/Libraries/LibELF/ELFLoader.h b/Libraries/LibELF/ELFLoader.h index f0e51bc8ea..d2ab9627ac 100644 --- a/Libraries/LibELF/ELFLoader.h +++ b/Libraries/LibELF/ELFLoader.h @@ -54,7 +54,7 @@ public: #endif char* symbol_ptr(const char* name); - bool has_symbols() const { return m_image.symbol_count(); } + bool has_symbols() const { return m_symbol_count; } String symbolicate(u32 address, u32* offset = nullptr) const; @@ -78,9 +78,14 @@ private: }; ELFImage m_image; + size_t m_symbol_count { 0 }; + struct SortedSymbol { u32 address; StringView name; +#ifndef KERNEL + String demangled_name; +#endif }; #ifdef KERNEL mutable OwnPtr m_sorted_symbols_region; -- cgit v1.2.3