diff --git a/lib/Interpreter/IncrementalJIT.cpp b/lib/Interpreter/IncrementalJIT.cpp index 1f608205..c58c66b6 100644 --- a/lib/Interpreter/IncrementalJIT.cpp +++ b/lib/Interpreter/IncrementalJIT.cpp @@ -61,6 +61,64 @@ namespace cling { class Azog: public RTDyldMemoryManager { cling::IncrementalJIT& m_jit; + struct AllocInfo { + uint8_t *m_Start = nullptr; + uint8_t *m_End = nullptr; + uint8_t *m_Current = nullptr; + + void allocate(RTDyldMemoryManager *exeMM, + uintptr_t Size, uint32_t Align, + bool code, bool isReadOnly) { + + uintptr_t RequiredSize = 2*Size; // Space for internal alignment. + if (code) + m_Start = exeMM->allocateCodeSection(RequiredSize, Align, + 0 /* SectionID */, + "codeReserve"); + else if (isReadOnly) + m_Start = exeMM->allocateDataSection(RequiredSize, Align, + 0 /* SectionID */, + "rodataReserve",isReadOnly); + else + m_Start = exeMM->allocateDataSection(RequiredSize, Align, + 0 /* SectionID */, + "rwataReserve",isReadOnly); + m_Current = m_Start; + m_End = m_Start + RequiredSize; + } + + uint8_t* getNextAddr(uintptr_t Size, unsigned Alignment) { + if (!Alignment) + Alignment = 16; + + assert(!(Alignment & (Alignment - 1)) && "Alignment must be a power of two."); + + uintptr_t RequiredSize = Alignment * ((Size + Alignment - 1)/Alignment + 1); + if ( (m_Current + RequiredSize) > m_End ) { + fprintf(stderr,"Error ... did not reserved enough memory: need %ld(%ld) and have %ld\n", + Size,RequiredSize,(m_End - m_Current)); + return nullptr; + } + + uintptr_t Addr = (uintptr_t)m_Current; + + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + + m_Current = (uint8_t*)(Addr + Size); + + return (uint8_t*)Addr; + } + + operator bool() { + return m_Current != nullptr; + } + }; + + AllocInfo m_Code; + AllocInfo m_ROData; + AllocInfo m_RWData; + public: Azog(cling::IncrementalJIT& Jit): m_jit(Jit) {} @@ -69,31 +127,50 @@ public: uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override { - uint8_t *Addr = - getExeMM()->allocateCodeSection(Size, Alignment, SectionID, SectionName); - m_jit.m_SectionsAllocatedSinceLastLoad.insert(Addr); + uint8_t *Addr = nullptr; + if (m_Code) { + Addr = m_Code.getNextAddr(Size, Alignment); + } + if (!Addr) { + Addr = getExeMM()->allocateCodeSection(Size, Alignment, SectionID, SectionName); + m_jit.m_SectionsAllocatedSinceLastLoad.insert(Addr); + } + return Addr; } uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly) override { - uint8_t *Addr = getExeMM()->allocateDataSection(Size, Alignment, SectionID, - SectionName, IsReadOnly); - m_jit.m_SectionsAllocatedSinceLastLoad.insert(Addr); + + uint8_t *Addr = nullptr; + if (IsReadOnly && m_ROData) { + Addr = m_ROData.getNextAddr(Size,Alignment); + } else if (m_RWData) { + Addr = m_RWData.getNextAddr(Size,Alignment); + } + if (!Addr) { + Addr = getExeMM()->allocateDataSection(Size, Alignment, SectionID, + SectionName, IsReadOnly); + m_jit.m_SectionsAllocatedSinceLastLoad.insert(Addr); + } return Addr; } void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t RODataSize, uint32_t RODataAlign, uintptr_t RWDataSize, uint32_t RWDataAlign) override { - return getExeMM()->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, - RODataAlign, RWDataSize, - RWDataAlign); + m_Code.allocate(getExeMM(),CodeSize, CodeAlign, true, false); + m_ROData.allocate(getExeMM(),RODataSize, RODataAlign, false, true); + m_RWData.allocate(getExeMM(),RWDataSize, RWDataAlign, false, false); + + m_jit.m_SectionsAllocatedSinceLastLoad.insert(m_Code.m_Start); + m_jit.m_SectionsAllocatedSinceLastLoad.insert(m_ROData.m_Start); + m_jit.m_SectionsAllocatedSinceLastLoad.insert(m_RWData.m_Start); } bool needsToReserveAllocationSpace() override { - return getExeMM()->needsToReserveAllocationSpace(); + return true; // getExeMM()->needsToReserveAllocationSpace(); } void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,