From 9c9f5085e010059c813d2285ddff79b542c76834 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Sun, 24 Nov 2024 14:18:25 -0800 Subject: [SharedCache] Optimize `ReadExportNode` `ReadExportNode` is called a lot during the initial load of the shared cache and thus impacts how long it takes for the UI to become responsive. This is a collection of optimizations that cut the time spent within `ReadExportNode` by 50%: 1. Pass iterators to `ReadExportNode` rather than a `DataBuffer` + offset. The lack of inlining in `DataBuffer`'s `operator[]` kills performance. Ideally this would have used `std::span`, but that would require bumping the minimum C++ version to C++20. 2. Add `MMappedFileAccessor::ReadSpan` so that `ReadExportNode` can operate directly on the mapped data without first copying it. 3. Removes a call to `GetAnalysisFunctionsForAddress` whose result was unused. 4. Use `std::find` to find the nul at the end of strings rather than assembling the string a character at a time. This avoids repeatedly growing the string. 5. Avoid the usual `Symbol` constructor in favor of `BNCreateSymbol`. The `Symbol` constructor has over head in two forms: 1. It has a `NameSpace` as an argument. Creating / destroying this allocates and deallocates memory We could create a single instance and reuse it for all calls, but... 2. The constructor copies all fields of the `NameSpace` to the heap before calling `BNCreateSymbol` and then deallocates them afterwards. This seems unnecessary, and adds a non-trivial amount of overhead. This can go back to directly constructing the `Symbol` once the constructors are improved. --- view/sharedcache/core/SharedCache.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'view/sharedcache/core/SharedCache.h') diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index b5a0491f..7bf8a7e0 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -620,11 +620,11 @@ private: std::optional LoadHeaderForAddress( std::shared_ptr vm, uint64_t address, std::string installName); void InitializeHeader( - Ref view, VM* vm, SharedCacheMachOHeader header, std::vector regionsToLoad); - void ReadExportNode(std::vector>& symbolList, SharedCacheMachOHeader& header, DataBuffer& buffer, - uint64_t textBase, const std::string& currentText, size_t cursor, uint32_t endGuard); + Ref view, VM* vm, const SharedCacheMachOHeader& header, std::vector regionsToLoad); + void ReadExportNode(std::vector>& symbolList, const SharedCacheMachOHeader& header, const uint8_t* begin, + const uint8_t *end, const uint8_t* current, uint64_t textBase, const std::string& currentText); std::vector> ParseExportTrie( - std::shared_ptr linkeditFile, SharedCacheMachOHeader header); + std::shared_ptr linkeditFile, const SharedCacheMachOHeader& header); Ref TypeLibraryForImage(const std::string& installName); -- cgit v1.3.1