Index: llvm/trunk/include/llvm/ExecutionEngine/SectionMemoryManager.h =================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ llvm/trunk/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -84,8 +84,23 @@ private: struct MemoryGroup { - SmallVector AllocatedMem; + // PendingMem contains all allocated memory blocks + // which have not yet had their permissions set. Note + // that this tracks memory blocks that have been given to + // this memory manager by the system, not those + // given out to the user. In particular, the memory manager + // will give out subblocks of these MemoryBlocks in response + // to user requests. We track which subblocks have not beeen + // given out yet in `FreeMem`. + SmallVector PendingMem; SmallVector FreeMem; + + // All allocated memory blocks that have had their permissions + // set (i.e. that have been finalized). Because of this, we may + // not give out subblocks of this memory to the user anymore, + // even if those subblocks have not been previously given out. + SmallVector AllocatedMem; + sys::MemoryBlock Near; }; Index: llvm/trunk/lib/ExecutionEngine/SectionMemoryManager.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/SectionMemoryManager.cpp +++ llvm/trunk/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,6 +138,14 @@ // 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 @@ 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 @@ } 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