summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/VM.h
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2025-01-13 22:19:17 -0800
committerkat <kat@vector35.com>2025-01-15 09:49:10 -0500
commitb14f86d5373eb7a4a8a40c9a23c3a9faf2732eeb (patch)
treeba09ec39132d6c02b01f391867b44ed0872cda4e /view/sharedcache/core/VM.h
parent0cea9333ac85d372cfa4be639e2fa4148153b3dc (diff)
[SharedCache] Avoid copying strings on each call to VM::MappingAtAddress
`PageMapping` was storing the path to the file it points within. This was causing unnecessary work within `VM::MappingAtAddress` as the `PageMapping`, and thus the path, is copied into the return value. This copying was more expensive than the map lookup. The file path is now stored within a `LazyMappedFileAccessor` class that wraps the `SelfAllocatingWeakPtr`. This means the path is still available via the `PageMapping`, but it does not need to be copied as often. This includes two additional improvements / optimizations while I was touching the code in question: 1. `MMappedFileAccessor::Open` no longer performs two hash lookups when a file accessor already exists. 2. `VM::MapPages` takes the path by const reference to avoid an unnecessary copy.
Diffstat (limited to 'view/sharedcache/core/VM.h')
-rw-r--r--view/sharedcache/core/VM.h26
1 files changed, 19 insertions, 7 deletions
diff --git a/view/sharedcache/core/VM.h b/view/sharedcache/core/VM.h
index e47cf15e..955dcbec 100644
--- a/view/sharedcache/core/VM.h
+++ b/view/sharedcache/core/VM.h
@@ -104,12 +104,25 @@ class MMAP {
void Unmap();
};
+class LazyMappedFileAccessor : public SelfAllocatingWeakPtr<MMappedFileAccessor> {
+public:
+ LazyMappedFileAccessor(std::string filePath, std::function<std::shared_ptr<MMappedFileAccessor>()> allocator,
+ std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAlloc)
+ : SelfAllocatingWeakPtr(std::move(allocator), std::move(postAlloc)), m_filePath(std::move(filePath)) {
+ }
+
+ std::string_view filePath() const { return m_filePath; }
+
+private:
+ std::string m_filePath;
+};
+
static uint64_t maxFPLimit;
static std::mutex fileAccessorDequeMutex;
static std::unordered_map<uint64_t, std::deque<std::shared_ptr<MMappedFileAccessor>>> fileAccessorReferenceHolder;
static std::set<uint64_t> blockedSessionIDs;
static std::mutex fileAccessorsMutex;
-static std::unordered_map<std::string, std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor>>> fileAccessors;
+static std::unordered_map<std::string, std::shared_ptr<LazyMappedFileAccessor>> fileAccessors;
static counting_semaphore fileAccessorSemaphore(0);
static std::atomic<uint64_t> mmapCount = 0;
@@ -123,7 +136,7 @@ public:
MMappedFileAccessor(const std::string &path);
~MMappedFileAccessor();
- static std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor>> Open(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string &path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine = nullptr);
+ static std::shared_ptr<LazyMappedFileAccessor> Open(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string &path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine = nullptr);
static void CloseAll(const uint64_t sessionID);
@@ -179,11 +192,10 @@ public:
struct PageMapping {
- std::string filePath;
- std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor>> fileAccessor;
+ std::shared_ptr<LazyMappedFileAccessor> fileAccessor;
size_t fileOffset;
- PageMapping(std::string filePath, std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor>> fileAccessor, size_t fileOffset)
- : filePath(std::move(filePath)), fileAccessor(std::move(fileAccessor)), fileOffset(fileOffset) {}
+ PageMapping(std::shared_ptr<LazyMappedFileAccessor> fileAccessor, size_t fileOffset)
+ : fileAccessor(std::move(fileAccessor)), fileOffset(fileOffset) {}
};
@@ -249,7 +261,7 @@ public:
~VM();
- void MapPages(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t sessionID, size_t vm_address, size_t fileoff, size_t size, std::string filePath, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine);
+ void MapPages(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t sessionID, size_t vm_address, size_t fileoff, size_t size, const std::string& filePath, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine);
bool AddressIsMapped(uint64_t address);