Implemenation a section level allocator in cling's RTDyldMemoryManager (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 3f7418269714e12d9fc4f17d197fde7199dbae7d (see more detail about the problem it the log of that commit)
This commit is contained in:
parent
e7c289878a
commit
aad9a7a391
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user