SectionMemoryManager shouldn't be a JITMemoryManager. Previously, the

EngineBuilder interface required a JITMemoryManager even if it was being used 
to construct an MCJIT. But the MCJIT actually wants a RTDyldMemoryManager. 
Consequently, the SectionMemoryManager, which is meant for MCJIT, derived 
from the JITMemoryManager and then stubbed out a bunch of JITMemoryManager 
methods that weren't relevant to the MCJIT.

This patch fixes the situation: it teaches the EngineBuilder that 
RTDyldMemoryManager is a supertype of JITMemoryManager, and that it's 
appropriate to pass a RTDyldMemoryManager instead of a JITMemoryManager if 
we're using the MCJIT. This allows us to remove the stub methods from 
SectionMemoryManager, and make SectionMemoryManager a direct subtype of 
RTDyldMemoryManager.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181820 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Filip Pizlo
2013-05-14 19:29:00 +00:00
parent a29a8965e2
commit 13a3cf1928
7 changed files with 57 additions and 74 deletions

View File

@ -34,6 +34,7 @@ namespace llvm {
struct GenericValue; struct GenericValue;
class Constant; class Constant;
class DataLayout;
class ExecutionEngine; class ExecutionEngine;
class Function; class Function;
class GlobalVariable; class GlobalVariable;
@ -44,7 +45,7 @@ class MachineCodeInfo;
class Module; class Module;
class MutexGuard; class MutexGuard;
class ObjectCache; class ObjectCache;
class DataLayout; class RTDyldMemoryManager;
class Triple; class Triple;
class Type; class Type;
@ -142,7 +143,7 @@ protected:
static ExecutionEngine *(*MCJITCtor)( static ExecutionEngine *(*MCJITCtor)(
Module *M, Module *M,
std::string *ErrorStr, std::string *ErrorStr,
JITMemoryManager *JMM, RTDyldMemoryManager *MCJMM,
bool GVsWithCode, bool GVsWithCode,
TargetMachine *TM); TargetMachine *TM);
static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
@ -496,6 +497,7 @@ private:
EngineKind::Kind WhichEngine; EngineKind::Kind WhichEngine;
std::string *ErrorStr; std::string *ErrorStr;
CodeGenOpt::Level OptLevel; CodeGenOpt::Level OptLevel;
RTDyldMemoryManager *MCJMM;
JITMemoryManager *JMM; JITMemoryManager *JMM;
bool AllocateGVsWithCode; bool AllocateGVsWithCode;
TargetOptions Options; TargetOptions Options;
@ -511,6 +513,7 @@ private:
WhichEngine = EngineKind::Either; WhichEngine = EngineKind::Either;
ErrorStr = NULL; ErrorStr = NULL;
OptLevel = CodeGenOpt::Default; OptLevel = CodeGenOpt::Default;
MCJMM = NULL;
JMM = NULL; JMM = NULL;
Options = TargetOptions(); Options = TargetOptions();
AllocateGVsWithCode = false; AllocateGVsWithCode = false;
@ -533,11 +536,28 @@ public:
return *this; return *this;
} }
/// setJITMemoryManager - Sets the memory manager to use. This allows /// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows
/// clients to customize their memory allocation policies. If create() is /// clients to customize their memory allocation policies for the MCJIT. This
/// called and is successful, the created engine takes ownership of the /// is only appropriate for the MCJIT; setting this and configuring the builder
/// memory manager. This option defaults to NULL. /// 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 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) { EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
MCJMM = NULL;
JMM = jmm; JMM = jmm;
return *this; return *this;
} }

View File

@ -16,7 +16,7 @@
#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H #define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Memory.h" #include "llvm/Support/Memory.h"
@ -35,7 +35,7 @@ namespace llvm {
/// in the JITed object. Permissions can be applied either by calling /// in the JITed object. Permissions can be applied either by calling
/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions /// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions
/// directly. Clients of MCJIT should call MCJIT::finalizeObject. /// directly. Clients of MCJIT should call MCJIT::finalizeObject.
class SectionMemoryManager : public JITMemoryManager { class SectionMemoryManager : public RTDyldMemoryManager {
SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
@ -108,54 +108,6 @@ private:
MemoryGroup CodeMem; MemoryGroup CodeMem;
MemoryGroup RWDataMem; MemoryGroup RWDataMem;
MemoryGroup RODataMem; 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!");
}
}; };
} }

View File

@ -14,6 +14,7 @@
#define DEBUG_TYPE "jit" #define DEBUG_TYPE "jit"
#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/GenericValue.h"
@ -47,7 +48,7 @@ ExecutionEngine *(*ExecutionEngine::JITCtor)(
ExecutionEngine *(*ExecutionEngine::MCJITCtor)( ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
Module *M, Module *M,
std::string *ErrorStr, std::string *ErrorStr,
JITMemoryManager *JMM, RTDyldMemoryManager *MCJMM,
bool GVsWithCode, bool GVsWithCode,
TargetMachine *TM) = 0; TargetMachine *TM) = 0;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
@ -455,10 +456,12 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr)) if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
return 0; return 0;
assert(!(JMM && MCJMM));
// If the user specified a memory manager but didn't specify which engine to // 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 // create, we assume they only want the JIT, and we fail if they only want
// the interpreter. // the interpreter.
if (JMM) { if (JMM || MCJMM) {
if (WhichEngine & EngineKind::JIT) if (WhichEngine & EngineKind::JIT)
WhichEngine = EngineKind::JIT; WhichEngine = EngineKind::JIT;
else { else {
@ -468,6 +471,14 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
} }
} }
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, // Unless the interpreter was explicitly selected or the JIT is not linked,
// try making a JIT. // try making a JIT.
if ((WhichEngine & EngineKind::JIT) && TheTM) { if ((WhichEngine & EngineKind::JIT) && TheTM) {
@ -480,7 +491,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
if (UseMCJIT && ExecutionEngine::MCJITCtor) { if (UseMCJIT && ExecutionEngine::MCJITCtor) {
ExecutionEngine *EE = ExecutionEngine *EE =
ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
AllocateGVsWithCode, TheTM.take()); AllocateGVsWithCode, TheTM.take());
if (EE) return EE; if (EE) return EE;
} else if (ExecutionEngine::JITCtor) { } else if (ExecutionEngine::JITCtor) {

View File

@ -39,7 +39,7 @@ extern "C" void LLVMLinkInMCJIT() {
ExecutionEngine *MCJIT::createJIT(Module *M, ExecutionEngine *MCJIT::createJIT(Module *M,
std::string *ErrorStr, std::string *ErrorStr,
JITMemoryManager *JMM, RTDyldMemoryManager *MemMgr,
bool GVsWithCode, bool GVsWithCode,
TargetMachine *TM) { TargetMachine *TM) {
// Try to register the program as a source of symbols to resolve against. // Try to register the program as a source of symbols to resolve against.
@ -47,13 +47,13 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
// FIXME: Don't do this here. // FIXME: Don't do this here.
sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 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, MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
bool AllocateGVsWithCode) bool AllocateGVsWithCode)
: ExecutionEngine(m), TM(tm), Ctx(0), : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM),
MemMgr(MM ? MM : new SectionMemoryManager()), Dyld(MemMgr),
IsLoaded(false), M(m), ObjCache(0) { IsLoaded(false), M(m), ObjCache(0) {
setDataLayout(TM->getDataLayout()); setDataLayout(TM->getDataLayout());

View File

@ -98,7 +98,7 @@ public:
static ExecutionEngine *createJIT(Module *M, static ExecutionEngine *createJIT(Module *M,
std::string *ErrorStr, std::string *ErrorStr,
JITMemoryManager *JMM, RTDyldMemoryManager *MemMgr,
bool GVsWithCode, bool GVsWithCode,
TargetMachine *TM); TargetMachine *TM);

View File

@ -337,14 +337,14 @@ int main(int argc, char **argv, char * const *envp) {
Mod->setTargetTriple(Triple::normalize(TargetTriple)); Mod->setTargetTriple(Triple::normalize(TargetTriple));
// Enable MCJIT if desired. // Enable MCJIT if desired.
JITMemoryManager *JMM = 0; RTDyldMemoryManager *RTDyldMM = 0;
if (UseMCJIT && !ForceInterpreter) { if (UseMCJIT && !ForceInterpreter) {
builder.setUseMCJIT(true); builder.setUseMCJIT(true);
if (RemoteMCJIT) if (RemoteMCJIT)
JMM = new RecordingMemoryManager(); RTDyldMM = new RecordingMemoryManager();
else else
JMM = new SectionMemoryManager(); RTDyldMM = new SectionMemoryManager();
builder.setJITMemoryManager(JMM); builder.setMCJITMemoryManager(RTDyldMM);
} else { } else {
if (RemoteMCJIT) { if (RemoteMCJIT) {
errs() << "error: Remote process execution requires -use-mcjit\n"; errs() << "error: Remote process execution requires -use-mcjit\n";
@ -461,7 +461,7 @@ int main(int argc, char **argv, char * const *envp) {
int Result; int Result;
if (RemoteMCJIT) { 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 // Everything is prepared now, so lay out our program for the target
// address space, assign the section addresses to resolve any relocations, // address space, assign the section addresses to resolve any relocations,
// and send it to the target. // and send it to the target.
@ -495,8 +495,8 @@ int main(int argc, char **argv, char * const *envp) {
// invalidated will be known. // invalidated will be known.
(void)EE->getPointerToFunction(EntryFn); (void)EE->getPointerToFunction(EntryFn);
// Clear instruction cache before code will be executed. // Clear instruction cache before code will be executed.
if (JMM) if (RTDyldMM)
static_cast<SectionMemoryManager*>(JMM)->invalidateInstructionCache(); static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache();
// Run main. // Run main.
Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp); Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);

View File

@ -165,7 +165,7 @@ protected:
std::string Error; std::string Error;
TheJIT.reset(EB.setEngineKind(EngineKind::JIT) TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
.setUseMCJIT(true) /* can this be folded into the EngineKind enum? */ .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
.setJITMemoryManager(MM) .setMCJITMemoryManager(MM)
.setErrorStr(&Error) .setErrorStr(&Error)
.setOptLevel(CodeGenOpt::None) .setOptLevel(CodeGenOpt::None)
.setAllocateGVsWithCode(false) /*does this do anything?*/ .setAllocateGVsWithCode(false) /*does this do anything?*/
@ -188,7 +188,7 @@ protected:
OwningPtr<TargetMachine> TM; OwningPtr<TargetMachine> TM;
OwningPtr<ExecutionEngine> TheJIT; OwningPtr<ExecutionEngine> TheJIT;
IRBuilder<> Builder; IRBuilder<> Builder;
JITMemoryManager *MM; RTDyldMemoryManager *MM;
OwningPtr<Module> M; OwningPtr<Module> M;
}; };