From 13a3cf192887233fb9452ec5b7f841e4652c33c7 Mon Sep 17 00:00:00 2001 From: Filip Pizlo Date: Tue, 14 May 2013 19:29:00 +0000 Subject: [PATCH] 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 --- .../llvm/ExecutionEngine/ExecutionEngine.h | 32 +++++++++--- .../ExecutionEngine/SectionMemoryManager.h | 52 +------------------ lib/ExecutionEngine/ExecutionEngine.cpp | 17 ++++-- lib/ExecutionEngine/MCJIT/MCJIT.cpp | 10 ++-- lib/ExecutionEngine/MCJIT/MCJIT.h | 2 +- tools/lli/lli.cpp | 14 ++--- .../ExecutionEngine/MCJIT/MCJITTestBase.h | 4 +- 7 files changed, 57 insertions(+), 74 deletions(-) diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index bbaebc6f906..83a672de2b6 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -34,6 +34,7 @@ namespace llvm { struct GenericValue; class Constant; +class DataLayout; class ExecutionEngine; class Function; class GlobalVariable; @@ -44,7 +45,7 @@ class MachineCodeInfo; class Module; class MutexGuard; class ObjectCache; -class DataLayout; +class RTDyldMemoryManager; class Triple; class Type; @@ -142,7 +143,7 @@ protected: static ExecutionEngine *(*MCJITCtor)( Module *M, std::string *ErrorStr, - JITMemoryManager *JMM, + RTDyldMemoryManager *MCJMM, bool GVsWithCode, TargetMachine *TM); static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); @@ -496,6 +497,7 @@ private: EngineKind::Kind WhichEngine; std::string *ErrorStr; CodeGenOpt::Level OptLevel; + RTDyldMemoryManager *MCJMM; JITMemoryManager *JMM; bool AllocateGVsWithCode; TargetOptions Options; @@ -511,6 +513,7 @@ private: WhichEngine = EngineKind::Either; ErrorStr = NULL; OptLevel = CodeGenOpt::Default; + MCJMM = NULL; JMM = NULL; Options = TargetOptions(); AllocateGVsWithCode = false; @@ -532,12 +535,29 @@ public: 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; } diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h index 07e6832324f..305a96619a0 100644 --- a/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -16,7 +16,7 @@ #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" @@ -35,7 +35,7 @@ namespace llvm { /// 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; @@ -108,54 +108,6 @@ private: 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!"); - } }; } diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index e43ba4f1dd0..01916363073 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -14,6 +14,7 @@ #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" @@ -47,7 +48,7 @@ ExecutionEngine *(*ExecutionEngine::JITCtor)( ExecutionEngine *(*ExecutionEngine::MCJITCtor)( Module *M, std::string *ErrorStr, - JITMemoryManager *JMM, + RTDyldMemoryManager *MCJMM, bool GVsWithCode, TargetMachine *TM) = 0; ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, @@ -455,10 +456,12 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { 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 { @@ -467,6 +470,14 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { 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. @@ -480,7 +491,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { 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) { diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 38aa5474a3b..ced567205aa 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -39,7 +39,7 @@ extern "C" void LLVMLinkInMCJIT() { 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. @@ -47,14 +47,14 @@ ExecutionEngine *MCJIT::createJIT(Module *M, // 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()); } diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 8c4bf6e1dbc..7f247e2dee5 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -98,7 +98,7 @@ public: static ExecutionEngine *createJIT(Module *M, std::string *ErrorStr, - JITMemoryManager *JMM, + RTDyldMemoryManager *MemMgr, bool GVsWithCode, TargetMachine *TM); diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 1866403cf80..ac7db20aed8 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -337,14 +337,14 @@ int main(int argc, char **argv, char * const *envp) { 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"; @@ -461,7 +461,7 @@ int main(int argc, char **argv, char * const *envp) { int Result; if (RemoteMCJIT) { - RecordingMemoryManager *MM = static_cast(JMM); + RecordingMemoryManager *MM = static_cast(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. @@ -495,8 +495,8 @@ int main(int argc, char **argv, char * const *envp) { // invalidated will be known. (void)EE->getPointerToFunction(EntryFn); // Clear instruction cache before code will be executed. - if (JMM) - static_cast(JMM)->invalidateInstructionCache(); + if (RTDyldMM) + static_cast(RTDyldMM)->invalidateInstructionCache(); // Run main. Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp); diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h index b0e98a88def..e99aa991604 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h +++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h @@ -165,7 +165,7 @@ protected: 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?*/ @@ -188,7 +188,7 @@ protected: OwningPtr TM; OwningPtr TheJIT; IRBuilder<> Builder; - JITMemoryManager *MM; + RTDyldMemoryManager *MM; OwningPtr M; }; -- 2.34.1