aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-04-04 23:04:39 +0000
committerJim Grosbach <grosbach@apple.com>2011-04-04 23:04:39 +0000
commitfcbe5b71936b820647dffff0e4f9c60ece3988a5 (patch)
treedd2bae41b7d089760ca4f8477d732a1d1ca22e13
parentc15a91dfc84822037c40ae9d37f63ce1b1a763bb (diff)
Layer the memory manager between the JIT and the runtime Dyld.
The JITMemory manager references LLVM IR constructs directly, while the runtime Dyld works at a lower level and can handle objects which may not originate from LLVM IR. Introduce a new layer for the memory manager to handle the interface between them. For the MCJIT, this layer will be almost entirely simply a call-through w/ translation between the IR objects and symbol names. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128851 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h29
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp11
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h3
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp25
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp21
5 files changed, 64 insertions, 25 deletions
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index ade0047a59..01fc338316 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -21,7 +21,29 @@ namespace llvm {
class RuntimeDyldImpl;
class MemoryBuffer;
-class JITMemoryManager;
+
+// RuntimeDyld clients often want to handle the memory management of
+// what gets placed where. For JIT clients, this is an abstraction layer
+// over the JITMemoryManager, which references objects by their source
+// representations in LLVM IR.
+// FIXME: As the RuntimeDyld fills out, additional routines will be needed
+// for the varying types of objects to be allocated.
+class RTDyldMemoryManager {
+ RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
+ void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
+public:
+ RTDyldMemoryManager() {}
+
+ // Allocate ActualSize bytes, or more, for the named function. Return
+ // a pointer to the allocated memory and update Size to reflect how much
+ // memory was acutally allocated.
+ virtual uint64_t startFunctionBody(const char *Name, uintptr_t &Size) = 0;
+
+ // Mark the end of the function, including how much of the allocated
+ // memory was actually used.
+ virtual void endFunctionBody(const char *Name, uint64_t FunctionStart,
+ uint64_t FunctionEnd) = 0;
+};
class RuntimeDyld {
RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
@@ -31,11 +53,12 @@ class RuntimeDyld {
// interface.
RuntimeDyldImpl *Dyld;
public:
- RuntimeDyld(JITMemoryManager*);
+ RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld();
bool loadObject(MemoryBuffer *InputBuffer);
- void *getSymbolAddress(StringRef Name);
+ uint64_t getSymbolAddress(StringRef Name);
+ void reassignSymbolAddress(StringRef Name, uint64_t Addr);
// FIXME: Should be parameterized to get the memory block associated with
// a particular loaded object.
sys::MemoryBlock getMemoryBlock();
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 2e3c9310fb..148e0d91b4 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "MCJIT.h"
+#include "MCJITMemoryManager.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -57,7 +58,8 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
// If the target supports JIT code generation, create the JIT.
if (TargetJITInfo *TJ = TM->getJITInfo())
- return new MCJIT(M, TM, *TJ, JMM, OptLevel, GVsWithCode);
+ return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM), OptLevel,
+ GVsWithCode);
if (ErrorStr)
*ErrorStr = "target does not support JIT code generation";
@@ -65,9 +67,9 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
}
MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
- JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
+ RTDyldMemoryManager *MM, CodeGenOpt::Level OptLevel,
bool AllocateGVsWithCode)
- : ExecutionEngine(m), TM(tm), M(m), OS(Buffer), Dyld(JMM) {
+ : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {
PM.add(new TargetData(*TM->getTargetData()));
@@ -94,6 +96,7 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
}
MCJIT::~MCJIT() {
+ delete MemMgr;
}
void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
@@ -110,7 +113,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
}
Twine Name = TM->getMCAsmInfo()->getGlobalPrefix() + F->getName();
- return Dyld.getSymbolAddress(Name.str());
+ return (void*)Dyld.getSymbolAddress(Name.str());
}
void *MCJIT::recompileAndRelinkFunction(Function *F) {
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index 915ca0ea1e..1b507663e4 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -24,11 +24,12 @@ namespace llvm {
class MCJIT : public ExecutionEngine {
MCJIT(Module *M, TargetMachine *tm, TargetJITInfo &tji,
- JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
+ RTDyldMemoryManager *MemMgr, CodeGenOpt::Level OptLevel,
bool AllocateGVsWithCode);
TargetMachine *TM;
MCContext *Ctx;
+ RTDyldMemoryManager *MemMgr;
// FIXME: These may need moved to a separate 'jitstate' member like the
// non-MC JIT does for multithreading and such. Just keep them here for now.
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index c041c940de..536013a279 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -35,12 +34,12 @@ class RuntimeDyldImpl {
unsigned CPUType;
unsigned CPUSubtype;
- // The JITMemoryManager to load objects into.
- JITMemoryManager *JMM;
+ // The MemoryManager to load objects into.
+ RTDyldMemoryManager *MemMgr;
// Master symbol table. As modules are loaded and external symbols are
// resolved, their addresses are stored here.
- StringMap<void*> SymbolTable;
+ StringMap<uint64_t> SymbolTable;
// FIXME: Should have multiple data blocks, one for each loaded chunk of
// compiled code.
@@ -72,11 +71,11 @@ class RuntimeDyldImpl {
const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
public:
- RuntimeDyldImpl(JITMemoryManager *jmm) : JMM(jmm), HasError(false) {}
+ RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
bool loadObject(MemoryBuffer *InputBuffer);
- void *getSymbolAddress(StringRef Name) {
+ uint64_t getSymbolAddress(StringRef Name) {
// Use lookup() rather than [] because we don't want to add an entry
// if there isn't one already, which the [] operator does.
return SymbolTable.lookup(Name);
@@ -314,7 +313,7 @@ loadSegment32(const MachOObject *Obj,
void *SectionBase = SectionBases[Index];
// Get the symbol address.
- void *Address = (char*) SectionBase + STE->Value;
+ uint64_t Address = (uint64_t)SectionBase + STE->Value;
// FIXME: Check the symbol type and flags.
if (STE->Type != 0xF)
@@ -335,7 +334,7 @@ loadSegment32(const MachOObject *Obj,
}
// We've loaded the section; now mark the functions in it as executable.
- // FIXME: We really should use the JITMemoryManager for this.
+ // FIXME: We really should use the MemoryManager for this.
sys::Memory::setRangeExecutable(Data.base(), Data.size());
return false;
@@ -414,7 +413,7 @@ loadSegment64(const MachOObject *Obj,
void *SectionBase = SectionBases[Index];
// Get the symbol address.
- void *Address = (char*) SectionBase + STE->Value;
+ uint64_t Address = (uint64_t) SectionBase + STE->Value;
// FIXME: Check the symbol type and flags.
if (STE->Type != 0xF)
@@ -434,7 +433,7 @@ loadSegment64(const MachOObject *Obj,
}
// We've loaded the section; now mark the functions in it as executable.
- // FIXME: We really should use the JITMemoryManager for this.
+ // FIXME: We really should use the MemoryManager for this.
sys::Memory::setRangeExecutable(Data.base(), Data.size());
return false;
@@ -530,8 +529,8 @@ bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
//===----------------------------------------------------------------------===//
// RuntimeDyld class implementation
-RuntimeDyld::RuntimeDyld(JITMemoryManager *JMM) {
- Dyld = new RuntimeDyldImpl(JMM);
+RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *MM) {
+ Dyld = new RuntimeDyldImpl(MM);
}
RuntimeDyld::~RuntimeDyld() {
@@ -542,7 +541,7 @@ bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
return Dyld->loadObject(InputBuffer);
}
-void *RuntimeDyld::getSymbolAddress(StringRef Name) {
+uint64_t RuntimeDyld::getSymbolAddress(StringRef Name) {
return Dyld->getSymbolAddress(Name);
}
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index a670944235..e09f14ad78 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -13,7 +13,6 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/Support/CommandLine.h"
@@ -41,6 +40,20 @@ Action(cl::desc("Action to perform:"),
/* *** */
+// A trivial memory manager that doesn't do anything fancy, just uses the
+// support library allocation routines directly.
+class TrivialMemoryManager : public RTDyldMemoryManager {
+public:
+ uint64_t startFunctionBody(const char *Name, uintptr_t &Size);
+ void endFunctionBody(const char *Name, uint64_t FunctionStart,
+ uint64_t FunctionEnd) {}
+};
+
+uint64_t TrivialMemoryManager::startFunctionBody(const char *Name,
+ uintptr_t &Size) {
+ return (uint64_t)sys::Memory::AllocateRWX(Size, 0, 0).base();
+}
+
static const char *ProgramName;
static void Message(const char *Type, const Twine &Msg) {
@@ -61,7 +74,7 @@ static int executeInput() {
return Error("unable to read input: '" + ec.message() + "'");
// Instantiate a dynamic linker.
- RuntimeDyld Dyld(JITMemoryManager::CreateDefaultMemManager());
+ RuntimeDyld Dyld(new TrivialMemoryManager);
// Load the object file into it.
if (Dyld.loadObject(InputBuffer.take())) {
@@ -69,7 +82,7 @@ static int executeInput() {
}
// Get the address of "_main".
- void *MainAddress = Dyld.getSymbolAddress("_main");
+ uint64_t MainAddress = Dyld.getSymbolAddress("_main");
if (MainAddress == 0)
return Error("no definition for '_main'");
@@ -83,7 +96,7 @@ static int executeInput() {
return Error("unable to mark function executable: '" + ErrorStr + "'");
// Dispatch to _main().
- errs() << "loaded '_main' at: " << MainAddress << "\n";
+ errs() << "loaded '_main' at: " << (void*)MainAddress << "\n";
int (*Main)(int, const char**) =
(int(*)(int,const char**)) uintptr_t(MainAddress);