Skip to content

Commit

Permalink
Implemenation a section level allocator in cling's RTDyldMemoryManage…
Browse files Browse the repository at this point in the history
…r (Azog).

This allow for a single allocation at the beginning of the module and insure that
all the section of the module with be contiguous in memory.

This is a better fix for Fix ROOT-8523 and replace commit
3f74182 (see more detail about
the problem it the log of that commit)
  • Loading branch information
pcanal committed Jan 31, 2017
1 parent 8d506b5 commit a7b0b3e
Showing 1 changed file with 87 additions and 10 deletions.
97 changes: 87 additions & 10 deletions interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}

Expand All @@ -69,31 +127,50 @@ class Azog: public RTDyldMemoryManager {
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,
Expand Down

0 comments on commit a7b0b3e

Please sign in to comment.