Hook up the MCJIT to the RuntimeDyld library.

Lots of cleanup to make the interfaces prettier, use the JITMemoryManager,
handle multiple functions and modules, etc.. This gets far enough that
the MCJIT compiles and runs code, though.

llvm-svn: 128052
This commit is contained in:
Jim Grosbach 2011-03-22 01:06:42 +00:00
parent c6f4af028d
commit 348a548381
3 changed files with 22 additions and 3 deletions

View File

@ -11,8 +11,11 @@
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Target/TargetData.h"
using namespace llvm;
@ -81,6 +84,12 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
PM.run(*M);
// Flush the output buffer so the SmallVector gets its data.
OS.flush();
// Load the object into the dynamic linker.
// FIXME: It would be nice to avoid making yet another copy.
MemoryBuffer *MB = MemoryBuffer::getMemBufferCopy(StringRef(Buffer.data(),
Buffer.size()));
Dyld.loadObject(MB);
}
MCJIT::~MCJIT() {
@ -92,7 +101,8 @@ void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
}
void *MCJIT::getPointerToFunction(Function *F) {
return 0;
Twine Name = TM->getMCAsmInfo()->getGlobalPrefix() + F->getName();
return Dyld.getSymbolAddress(Name.str());
}
void *MCJIT::recompileAndRelinkFunction(Function *F) {

View File

@ -12,6 +12,7 @@
#include "llvm/PassManager.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
@ -37,6 +38,8 @@ class MCJIT : public ExecutionEngine {
SmallVector<char, 4096> Buffer; // Working buffer into which we JIT.
raw_svector_ostream OS;
RuntimeDyld Dyld;
public:
~MCJIT();

View File

@ -145,6 +145,10 @@ loadSegment32(const MachOObject *Obj,
SymbolTable[Name] = Address;
}
// We've loaded the section; now mark the functions in it as executable.
// FIXME: We really should use the JITMemoryManager for this.
sys::Memory::setRangeExecutable(Data.base(), Data.size());
delete SectionBases;
return false;
}
@ -220,12 +224,14 @@ loadSegment64(const MachOObject *Obj,
SymbolTable[Name] = Address;
}
// We've loaded the section; now mark the functions in it as executable.
// FIXME: We really should use the JITMemoryManager for this.
sys::Memory::setRangeExecutable(Data.base(), Data.size());
delete SectionBases;
return false;
}
bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
// If the linker is in an error state, don't do anything.
if (hasError())