From cb4ab730d69bd35072edf024c59c630ffb89f4aa Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 10 Jan 2016 18:51:50 +0000 Subject: [PATCH] [RuntimeDyld] Add alignment arguments to the reserveAllocationSpace method of RuntimeDyld::MemoryManager. The RuntimeDyld::MemoryManager::reserveAllocationSpace method is called when object files are loaded, and gives clients a chance to pre-allocate memory for all segments. Previously only the size of each segment (code, ro-data, rw-data) was supplied but not the alignment. This hasn't caused any problems so far, as most clients allocate via the MemoryBlock interface which returns page-aligned blocks. Adding alignment arguments enables finer grained allocation while still satisfying alignment restrictions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257294 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ExecutionEngine/RuntimeDyld.h | 8 +++-- lib/ExecutionEngine/Orc/OrcMCJITReplacement.h | 11 ++++--- .../RuntimeDyld/RuntimeDyld.cpp | 31 ++++++++++--------- .../RuntimeDyld/RuntimeDyldImpl.h | 6 ++-- .../ExecutionEngine/MCJIT/MCJITCAPITest.cpp | 5 +-- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index afd8de64913..fe736bb00cc 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -124,9 +124,11 @@ public: /// /// Note that by default the callback is disabled. To enable it /// redefine the method needsToReserveAllocationSpace to return true. - virtual void reserveAllocationSpace(uintptr_t CodeSize, - uintptr_t DataSizeRO, - uintptr_t DataSizeRW) {} + virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, + uintptr_t RODataSize, + uint32_t RODataAlign, + uintptr_t RWDataSize, + uint32_t RWDataAlign) {} /// Override to return true to enable the reserveAllocationSpace callback. virtual bool needsToReserveAllocationSpace() { return false; } diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 38a27cff5b2..61d8ec99451 100644 --- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -54,10 +54,13 @@ class OrcMCJITReplacement : public ExecutionEngine { return Addr; } - void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO, - uintptr_t DataSizeRW) override { - return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO, - DataSizeRW); + void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, + uintptr_t RODataSize, uint32_t RODataAlign, + uintptr_t RWDataSize, + uint32_t RWDataAlign) override { + return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign, + RODataSize, RODataAlign, + RWDataSize, RWDataAlign); } bool needsToReserveAllocationSpace() override { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 24b911c190a..716e7f0c097 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -146,9 +146,12 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Compute the memory size required to load all sections to be loaded // and pass this information to the memory manager if (MemMgr.needsToReserveAllocationSpace()) { - uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0; - computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW); - MemMgr.reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); + uint64_t CodeSize = 0, RODataSize = 0, RWDataSize = 0; + uint32_t CodeAlign = 1, RODataAlign = 1, RWDataAlign = 1; + computeTotalAllocSize(Obj, CodeSize, CodeAlign, RODataSize, RODataAlign, + RWDataSize, RWDataAlign); + MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, + RWDataSize, RWDataAlign); } // Used sections from the object file @@ -335,13 +338,15 @@ static bool isZeroInit(const SectionRef Section) { // sections void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, - uint64_t &DataSizeRO, - uint64_t &DataSizeRW) { + uint32_t &CodeAlign, + uint64_t &RODataSize, + uint32_t &RODataAlign, + uint64_t &RWDataSize, + uint32_t &RWDataAlign) { // Compute the size of all sections required for execution std::vector CodeSectionSizes; std::vector ROSectionSizes; std::vector RWSectionSizes; - uint64_t MaxAlignment = sizeof(void *); // Collect sizes of all sections to be loaded; // also determine the max alignment of all sections @@ -376,17 +381,15 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, SectionSize = 1; if (IsCode) { + CodeAlign = std::max(CodeAlign, Alignment); CodeSectionSizes.push_back(SectionSize); } else if (IsReadOnly) { + RODataAlign = std::max(RODataAlign, Alignment); ROSectionSizes.push_back(SectionSize); } else { + RWDataAlign = std::max(RWDataAlign, Alignment); RWSectionSizes.push_back(SectionSize); } - - // update the max alignment - if (Alignment > MaxAlignment) { - MaxAlignment = Alignment; - } } } @@ -410,9 +413,9 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, // allocated with the max alignment. Note that we cannot compute with the // individual alignments of the sections, because then the required size // depends on the order, in which the sections are allocated. - CodeSize = computeAllocationSizeForSections(CodeSectionSizes, MaxAlignment); - DataSizeRO = computeAllocationSizeForSections(ROSectionSizes, MaxAlignment); - DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment); + CodeSize = computeAllocationSizeForSections(CodeSectionSizes, CodeAlign); + RODataSize = computeAllocationSizeForSections(ROSectionSizes, RODataAlign); + RWDataSize = computeAllocationSizeForSections(RWSectionSizes, RWDataAlign); } // compute stub buffer size for the given section diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index dafd3c8793c..ab732c69ee2 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -411,8 +411,10 @@ protected: // \brief Compute an upper bound of the memory that is required to load all // sections - void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, - uint64_t &DataSizeRO, uint64_t &DataSizeRW); + void computeTotalAllocSize(const ObjectFile &Obj, + uint64_t &CodeSize, uint32_t &CodeAlign, + uint64_t &RODataSize, uint32_t &RODataAlign, + uint64_t &RWDataSize, uint32_t &RWDataAlign); // \brief Compute the stub buffer size required for a section unsigned computeSectionStubBufSize(const ObjectFile &Obj, diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp index 7704e5a2f79..c8c244d22ed 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -88,8 +88,9 @@ public: bool needsToReserveAllocationSpace() override { return true; } - void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO, - uintptr_t DataSizeRW) override { + void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, + uintptr_t DataSizeRO, uint32_t RODataAlign, + uintptr_t DataSizeRW, uint32_t RWDataAlign) override { ReservedCodeSize = CodeSize; ReservedDataSizeRO = DataSizeRO; ReservedDataSizeRW = DataSizeRW; -- 2.34.1