struct GenericValue;
class Constant;
+class DataLayout;
class ExecutionEngine;
class Function;
class GlobalVariable;
class Module;
class MutexGuard;
class ObjectCache;
-class DataLayout;
+class RTDyldMemoryManager;
class Triple;
class Type;
static ExecutionEngine *(*MCJITCtor)(
Module *M,
std::string *ErrorStr,
- JITMemoryManager *JMM,
+ RTDyldMemoryManager *MCJMM,
bool GVsWithCode,
TargetMachine *TM);
static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
EngineKind::Kind WhichEngine;
std::string *ErrorStr;
CodeGenOpt::Level OptLevel;
+ RTDyldMemoryManager *MCJMM;
JITMemoryManager *JMM;
bool AllocateGVsWithCode;
TargetOptions Options;
WhichEngine = EngineKind::Either;
ErrorStr = NULL;
OptLevel = CodeGenOpt::Default;
+ MCJMM = NULL;
JMM = NULL;
Options = TargetOptions();
AllocateGVsWithCode = false;
WhichEngine = w;
return *this;
}
+
+ /// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows
+ /// clients to customize their memory allocation policies for the MCJIT. This
+ /// is only appropriate for the MCJIT; setting this and configuring the builder
+ /// to create anything other than MCJIT will cause a runtime error. If create()
+ /// is called and is successful, the created engine takes ownership of the
+ /// memory manager. This option defaults to NULL. Using this option nullifies
+ /// the setJITMemoryManager() option.
+ EngineBuilder &setMCJITMemoryManager(RTDyldMemoryManager *mcjmm) {
+ MCJMM = mcjmm;
+ JMM = NULL;
+ return *this;
+ }
- /// setJITMemoryManager - Sets the memory manager to use. This allows
- /// clients to customize their memory allocation policies. If create() is
- /// called and is successful, the created engine takes ownership of the
- /// memory manager. This option defaults to NULL.
+ /// setJITMemoryManager - Sets the JIT memory manager to use. This allows
+ /// clients to customize their memory allocation policies. This is only
+ /// appropriate for either JIT or MCJIT; setting this and configuring the
+ /// builder to create an interpreter will cause a runtime error. If create()
+ /// is called and is successful, the created engine takes ownership of the
+ /// memory manager. This option defaults to NULL. This option overrides
+ /// setMCJITMemoryManager() as well.
EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
+ MCJMM = NULL;
JMM = jmm;
return *this;
}
#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Memory.h"
/// in the JITed object. Permissions can be applied either by calling
/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions
/// directly. Clients of MCJIT should call MCJIT::finalizeObject.
-class SectionMemoryManager : public JITMemoryManager {
+class SectionMemoryManager : public RTDyldMemoryManager {
SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
MemoryGroup CodeMem;
MemoryGroup RWDataMem;
MemoryGroup RODataMem;
-
-public:
- ///
- /// Functions below are not used by MCJIT or RuntimeDyld, but must be
- /// implemented because they are declared as pure virtuals in the base class.
- ///
-
- virtual void setMemoryWritable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setMemoryExecutable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setPoisonMemory(bool poison) {
- llvm_unreachable("Unexpected call!");
- }
- virtual void AllocateGOT() {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *getGOTBase() const {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *startFunctionBody(const Function *F,
- uintptr_t &ActualSize){
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
- unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void deallocateFunctionBody(void *Body) {
- llvm_unreachable("Unexpected call!");
- }
};
}
#define DEBUG_TYPE "jit"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ExecutionEngine/GenericValue.h"
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
Module *M,
std::string *ErrorStr,
- JITMemoryManager *JMM,
+ RTDyldMemoryManager *MCJMM,
bool GVsWithCode,
TargetMachine *TM) = 0;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
return 0;
+ assert(!(JMM && MCJMM));
+
// If the user specified a memory manager but didn't specify which engine to
// create, we assume they only want the JIT, and we fail if they only want
// the interpreter.
- if (JMM) {
+ if (JMM || MCJMM) {
if (WhichEngine & EngineKind::JIT)
WhichEngine = EngineKind::JIT;
else {
return 0;
}
}
+
+ if (MCJMM && ! UseMCJIT) {
+ if (ErrorStr)
+ *ErrorStr =
+ "Cannot create a legacy JIT with a runtime dyld memory "
+ "manager.";
+ return 0;
+ }
// Unless the interpreter was explicitly selected or the JIT is not linked,
// try making a JIT.
if (UseMCJIT && ExecutionEngine::MCJITCtor) {
ExecutionEngine *EE =
- ExecutionEngine::MCJITCtor(M, ErrorStr, JMM,
+ ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
AllocateGVsWithCode, TheTM.take());
if (EE) return EE;
} else if (ExecutionEngine::JITCtor) {
ExecutionEngine *MCJIT::createJIT(Module *M,
std::string *ErrorStr,
- JITMemoryManager *JMM,
+ RTDyldMemoryManager *MemMgr,
bool GVsWithCode,
TargetMachine *TM) {
// Try to register the program as a source of symbols to resolve against.
// FIXME: Don't do this here.
sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
- return new MCJIT(M, TM, JMM ? JMM : new SectionMemoryManager(), GVsWithCode);
+ return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(),
+ GVsWithCode);
}
MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
bool AllocateGVsWithCode)
- : ExecutionEngine(m), TM(tm), Ctx(0),
- MemMgr(MM ? MM : new SectionMemoryManager()), Dyld(MemMgr),
- IsLoaded(false), M(m), ObjCache(0) {
+ : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM),
+ IsLoaded(false), M(m), ObjCache(0) {
setDataLayout(TM->getDataLayout());
}
static ExecutionEngine *createJIT(Module *M,
std::string *ErrorStr,
- JITMemoryManager *JMM,
+ RTDyldMemoryManager *MemMgr,
bool GVsWithCode,
TargetMachine *TM);
Mod->setTargetTriple(Triple::normalize(TargetTriple));
// Enable MCJIT if desired.
- JITMemoryManager *JMM = 0;
+ RTDyldMemoryManager *RTDyldMM = 0;
if (UseMCJIT && !ForceInterpreter) {
builder.setUseMCJIT(true);
if (RemoteMCJIT)
- JMM = new RecordingMemoryManager();
+ RTDyldMM = new RecordingMemoryManager();
else
- JMM = new SectionMemoryManager();
- builder.setJITMemoryManager(JMM);
+ RTDyldMM = new SectionMemoryManager();
+ builder.setMCJITMemoryManager(RTDyldMM);
} else {
if (RemoteMCJIT) {
errs() << "error: Remote process execution requires -use-mcjit\n";
int Result;
if (RemoteMCJIT) {
- RecordingMemoryManager *MM = static_cast<RecordingMemoryManager*>(JMM);
+ RecordingMemoryManager *MM = static_cast<RecordingMemoryManager*>(RTDyldMM);
// Everything is prepared now, so lay out our program for the target
// address space, assign the section addresses to resolve any relocations,
// and send it to the target.
// invalidated will be known.
(void)EE->getPointerToFunction(EntryFn);
// Clear instruction cache before code will be executed.
- if (JMM)
- static_cast<SectionMemoryManager*>(JMM)->invalidateInstructionCache();
+ if (RTDyldMM)
+ static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache();
// Run main.
Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);
std::string Error;
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
.setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
- .setJITMemoryManager(MM)
+ .setMCJITMemoryManager(MM)
.setErrorStr(&Error)
.setOptLevel(CodeGenOpt::None)
.setAllocateGVsWithCode(false) /*does this do anything?*/
OwningPtr<TargetMachine> TM;
OwningPtr<ExecutionEngine> TheJIT;
IRBuilder<> Builder;
- JITMemoryManager *MM;
+ RTDyldMemoryManager *MM;
OwningPtr<Module> M;
};