diff options
author | Keno Fischer <kfischer@college.harvard.edu> | 2015-10-01 02:45:07 +0000 |
---|---|---|
committer | Keno Fischer <kfischer@college.harvard.edu> | 2015-10-01 02:45:07 +0000 |
commit | 17433bd10259761a673390a01c63d3fa7766ae4a (patch) | |
tree | dd9647c63f7640930c73d15ba2827b798e6c9772 /llvm/lib/ExecutionEngine/SectionMemoryManager.cpp | |
parent | 9143378db0ec22c92a0af0c51fcfbcbfd24c359d (diff) | |
download | bcm5719-llvm-17433bd10259761a673390a01c63d3fa7766ae4a.tar.gz bcm5719-llvm-17433bd10259761a673390a01c63d3fa7766ae4a.zip |
Fix performance problem in long-running SectionMemoryManagers
Summary:
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.
Reviewers: lhames
Subscribers: reames, llvm-commits
Differential Revision: http://reviews.llvm.org/D13156
llvm-svn: 248981
Diffstat (limited to 'llvm/lib/ExecutionEngine/SectionMemoryManager.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/SectionMemoryManager.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp b/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp index b22c6db8c37..5e89a945b80 100644 --- a/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp +++ b/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp @@ -83,7 +83,7 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, // 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,6 +138,14 @@ bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) // relocations) will get to the data cache but not to the instruction cache. invalidateInstructionCache(); + // 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()); + CodeMem.PendingMem.clear(); + + RODataMem.AllocatedMem.append(RODataMem.PendingMem.begin(),RODataMem.PendingMem.end()); + RODataMem.PendingMem.clear(); + return false; } @@ -145,7 +153,7 @@ std::error_code 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; @@ -153,14 +161,17 @@ SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, } void SectionMemoryManager::invalidateInstructionCache() { - for (sys::MemoryBlock &Block : CodeMem.AllocatedMem) + for (sys::MemoryBlock &Block : CodeMem.PendingMem) sys::Memory::InvalidateInstructionCache(Block.base(), Block.size()); } SectionMemoryManager::~SectionMemoryManager() { - for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) + for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) { for (sys::MemoryBlock &Block : Group->AllocatedMem) sys::Memory::releaseMappedMemory(Block); + for (sys::MemoryBlock &Block : Group->PendingMem) + sys::Memory::releaseMappedMemory(Block); + } } } // namespace llvm |