diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-07 16:41:42 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-07 16:41:42 +0200 |
commit | a31ef54a2a97864187bba71618aed5abeaeef70a (patch) | |
tree | b713a1a0e8e73cc4a87253e7aa737f7494955e3e | |
parent | 992d8e450c20bb5083cb3279e5f4a19016f6a5c7 (diff) | |
download | serenity-a31ef54a2a97864187bba71618aed5abeaeef70a.zip |
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. :^)
-rw-r--r-- | Libraries/LibELF/ELFLoader.cpp | 26 | ||||
-rw-r--r-- | Libraries/LibELF/ELFLoader.h | 7 |
2 files changed, 24 insertions, 9 deletions
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<Kernel::Region> m_sorted_symbols_region; |