[PATCH] D13156: Fix performance problem in long-running SectionMemoryManagers

Keno Fischer via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 22:46:01 PDT 2015

loladiro created this revision.
loladiro added a reviewer: lhames.
loladiro added a subscriber: llvm-commits.
loladiro set the repository for this revision to rL LLVM.

Without this patch, the memory manager would call `mprotect` on every memory region it ever allocated whenever it wanted to finalize memory (i.e. not just the ones it just allocated). This caused terrible performance problems for long running memory managers. In one particular compile heavy julia benchmark, we were spending 50% of time in `mprotect` if running under MCJIT. Fix this by splitting
allocated memory blocks into those on which memory permissions have been set and those on which
they haven't and only running `mprotect` on the latter.




Index: lib/ExecutionEngine/SectionMemoryManager.cpp
--- lib/ExecutionEngine/SectionMemoryManager.cpp
+++ lib/ExecutionEngine/SectionMemoryManager.cpp
@@ -83,7 +83,7 @@
   // Save this address as the basis for our next request
   MemGroup.Near = MB;
-  MemGroup.AllocatedMem.push_back(MB);
+  MemGroup.PendingMem.push_back(MB);
   Addr = (uintptr_t)MB.base();
   uintptr_t EndOfBlock = Addr + MB.size();
@@ -138,22 +138,29 @@
   // relocations) will get to the data cache but not to the instruction cache.
+  // Now, remember that we have successfully applied the permissions to avoid
+  // having to apply them again.
+  CodeMem.AllocatedMem.append(CodeMem.PendingMem.begin(),CodeMem.PendingMem.end());
+  RODataMem.AllocatedMem.append(RODataMem.PendingMem.begin(),RODataMem.PendingMem.end());
+  CodeMem.PendingMem.clear();
+  RODataMem.PendingMem.clear();
   return false;
 SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup,
                                                   unsigned Permissions) {
-  for (sys::MemoryBlock &MB : MemGroup.AllocatedMem)
+  for (sys::MemoryBlock &MB : MemGroup.PendingMem)
     if (std::error_code EC = sys::Memory::protectMappedMemory(MB, Permissions))
       return EC;
   return std::error_code();
 void SectionMemoryManager::invalidateInstructionCache() {
-  for (sys::MemoryBlock &Block : CodeMem.AllocatedMem)
+  for (sys::MemoryBlock &Block : CodeMem.PendingMem)
     sys::Memory::InvalidateInstructionCache(Block.base(), Block.size());
Index: include/llvm/ExecutionEngine/SectionMemoryManager.h
--- include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -84,6 +84,7 @@
   struct MemoryGroup {
+      SmallVector<sys::MemoryBlock, 16> PendingMem;
       SmallVector<sys::MemoryBlock, 16> AllocatedMem;
       SmallVector<sys::MemoryBlock, 16> FreeMem;
       sys::MemoryBlock Near;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13156.35701.patch
Type: text/x-patch
Size: 2127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150925/fd4a44ad/attachment.bin>

More information about the llvm-commits mailing list