SectionMemoryManager shouldn't be a JITMemoryManager. Previously, the
authorFilip Pizlo <fpizlo@apple.com>
Tue, 14 May 2013 19:29:00 +0000 (19:29 +0000)
committerFilip Pizlo <fpizlo@apple.com>
Tue, 14 May 2013 19:29:00 +0000 (19:29 +0000)
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

include/llvm/ExecutionEngine/ExecutionEngine.h
include/llvm/ExecutionEngine/SectionMemoryManager.h
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/MCJIT/MCJIT.cpp
lib/ExecutionEngine/MCJIT/MCJIT.h
tools/lli/lli.cpp
unittests/ExecutionEngine/MCJIT/MCJITTestBase.h

index bbaebc6f906b335b2118c07b45224aa7bcd300cc..83a672de2b698c9f28c5e108ed17c497bde242a2 100644 (file)
@@ -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;
   }
index 07e6832324f8fe0945603d6e01eab1b4633fe161..305a96619a0d2513cad2f34e769d44cbb08d04ae 100644 (file)
@@ -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!");
-  }
 };
 
 }
index e43ba4f1dd02c54752f36c3f7f1ea101adb649bd..019163630733b85c5c21d7527cd5756b6db7015f 100644 (file)
@@ -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) {
index 38aa5474a3b06fc3a8bc3331d0711bb20cd1e64d..ced567205aa850a51677ba2a9e2df505415b3d63 100644 (file)
@@ -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());
 }
index 8c4bf6e1dbc7d0d42480f5c226cbf669058390dc..7f247e2dee5b4759a079b0d071f55776b5e87412 100644 (file)
@@ -98,7 +98,7 @@ public:
 
   static ExecutionEngine *createJIT(Module *M,
                                     std::string *ErrorStr,
-                                    JITMemoryManager *JMM,
+                                    RTDyldMemoryManager *MemMgr,
                                     bool GVsWithCode,
                                     TargetMachine *TM);
 
index 1866403cf804ba50ae38cdda7d94495b010f8df3..ac7db20aed8cf4139d8dadf3f529027e219bc12f 100644 (file)
@@ -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<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.
@@ -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<SectionMemoryManager*>(JMM)->invalidateInstructionCache();
+    if (RTDyldMM)
+      static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache();
 
     // Run main.
     Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);
index b0e98a88defc14a5f9598108981efe7b818c2027..e99aa9916049c6f2d302a6a269546a39a0877fdc 100644 (file)
@@ -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<TargetMachine> TM;
   OwningPtr<ExecutionEngine> TheJIT;
   IRBuilder<> Builder;
-  JITMemoryManager *MM;
+  RTDyldMemoryManager *MM;
 
   OwningPtr<Module> M;
 };