summaryrefslogtreecommitdiff
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)
downloadllvm-fcbe5b71936b820647dffff0e4f9c60ece3988a5.tar.gz
llvm-fcbe5b71936b820647dffff0e4f9c60ece3988a5.tar.bz2
llvm-fcbe5b71936b820647dffff0e4f9c60ece3988a5.tar.xz
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);