llvm.org GIT mirror llvm / cb4ab73
[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 Lang Hames 3 years ago
5 changed file(s) with 36 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
123123 ///
124124 /// Note that by default the callback is disabled. To enable it
125125 /// redefine the method needsToReserveAllocationSpace to return true.
126 virtual void reserveAllocationSpace(uintptr_t CodeSize,
127 uintptr_t DataSizeRO,
128 uintptr_t DataSizeRW) {}
126 virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
127 uintptr_t RODataSize,
128 uint32_t RODataAlign,
129 uintptr_t RWDataSize,
130 uint32_t RWDataAlign) {}
129131
130132 /// Override to return true to enable the reserveAllocationSpace callback.
131133 virtual bool needsToReserveAllocationSpace() { return false; }
5353 return Addr;
5454 }
5555
56 void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
57 uintptr_t DataSizeRW) override {
58 return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO,
59 DataSizeRW);
56 void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
57 uintptr_t RODataSize, uint32_t RODataAlign,
58 uintptr_t RWDataSize,
59 uint32_t RWDataAlign) override {
60 return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign,
61 RODataSize, RODataAlign,
62 RWDataSize, RWDataAlign);
6063 }
6164
6265 bool needsToReserveAllocationSpace() override {
145145 // Compute the memory size required to load all sections to be loaded
146146 // and pass this information to the memory manager
147147 if (MemMgr.needsToReserveAllocationSpace()) {
148 uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
149 computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
150 MemMgr.reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
148 uint64_t CodeSize = 0, RODataSize = 0, RWDataSize = 0;
149 uint32_t CodeAlign = 1, RODataAlign = 1, RWDataAlign = 1;
150 computeTotalAllocSize(Obj, CodeSize, CodeAlign, RODataSize, RODataAlign,
151 RWDataSize, RWDataAlign);
152 MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
153 RWDataSize, RWDataAlign);
151154 }
152155
153156 // Used sections from the object file
334337 // sections
335338 void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
336339 uint64_t &CodeSize,
337 uint64_t &DataSizeRO,
338 uint64_t &DataSizeRW) {
340 uint32_t &CodeAlign,
341 uint64_t &RODataSize,
342 uint32_t &RODataAlign,
343 uint64_t &RWDataSize,
344 uint32_t &RWDataAlign) {
339345 // Compute the size of all sections required for execution
340346 std::vector CodeSectionSizes;
341347 std::vector ROSectionSizes;
342348 std::vector RWSectionSizes;
343 uint64_t MaxAlignment = sizeof(void *);
344349
345350 // Collect sizes of all sections to be loaded;
346351 // also determine the max alignment of all sections
375380 SectionSize = 1;
376381
377382 if (IsCode) {
383 CodeAlign = std::max(CodeAlign, Alignment);
378384 CodeSectionSizes.push_back(SectionSize);
379385 } else if (IsReadOnly) {
386 RODataAlign = std::max(RODataAlign, Alignment);
380387 ROSectionSizes.push_back(SectionSize);
381388 } else {
389 RWDataAlign = std::max(RWDataAlign, Alignment);
382390 RWSectionSizes.push_back(SectionSize);
383 }
384
385 // update the max alignment
386 if (Alignment > MaxAlignment) {
387 MaxAlignment = Alignment;
388391 }
389392 }
390393 }
409412 // allocated with the max alignment. Note that we cannot compute with the
410413 // individual alignments of the sections, because then the required size
411414 // depends on the order, in which the sections are allocated.
412 CodeSize = computeAllocationSizeForSections(CodeSectionSizes, MaxAlignment);
413 DataSizeRO = computeAllocationSizeForSections(ROSectionSizes, MaxAlignment);
414 DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment);
415 CodeSize = computeAllocationSizeForSections(CodeSectionSizes, CodeAlign);
416 RODataSize = computeAllocationSizeForSections(ROSectionSizes, RODataAlign);
417 RWDataSize = computeAllocationSizeForSections(RWSectionSizes, RWDataAlign);
415418 }
416419
417420 // compute stub buffer size for the given section
410410
411411 // \brief Compute an upper bound of the memory that is required to load all
412412 // sections
413 void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
414 uint64_t &DataSizeRO, uint64_t &DataSizeRW);
413 void computeTotalAllocSize(const ObjectFile &Obj,
414 uint64_t &CodeSize, uint32_t &CodeAlign,
415 uint64_t &RODataSize, uint32_t &RODataAlign,
416 uint64_t &RWDataSize, uint32_t &RWDataAlign);
415417
416418 // \brief Compute the stub buffer size required for a section
417419 unsigned computeSectionStubBufSize(const ObjectFile &Obj,
8787
8888 bool needsToReserveAllocationSpace() override { return true; }
8989
90 void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
91 uintptr_t DataSizeRW) override {
90 void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
91 uintptr_t DataSizeRO, uint32_t RODataAlign,
92 uintptr_t DataSizeRW, uint32_t RWDataAlign) override {
9293 ReservedCodeSize = CodeSize;
9394 ReservedDataSizeRO = DataSizeRO;
9495 ReservedDataSizeRW = DataSizeRW;