llvm.org GIT mirror llvm / 13a3cf1
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 Filip Pizlo 6 years ago
7 changed file(s) with 58 addition(s) and 75 deletion(s). Raw diff Collapse all Expand all
3333
3434 struct GenericValue;
3535 class Constant;
36 class DataLayout;
3637 class ExecutionEngine;
3738 class Function;
3839 class GlobalVariable;
4344 class Module;
4445 class MutexGuard;
4546 class ObjectCache;
46 class DataLayout;
47 class RTDyldMemoryManager;
4748 class Triple;
4849 class Type;
4950
141142 static ExecutionEngine *(*MCJITCtor)(
142143 Module *M,
143144 std::string *ErrorStr,
144 JITMemoryManager *JMM,
145 RTDyldMemoryManager *MCJMM,
145146 bool GVsWithCode,
146147 TargetMachine *TM);
147148 static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
495496 EngineKind::Kind WhichEngine;
496497 std::string *ErrorStr;
497498 CodeGenOpt::Level OptLevel;
499 RTDyldMemoryManager *MCJMM;
498500 JITMemoryManager *JMM;
499501 bool AllocateGVsWithCode;
500502 TargetOptions Options;
510512 WhichEngine = EngineKind::Either;
511513 ErrorStr = NULL;
512514 OptLevel = CodeGenOpt::Default;
515 MCJMM = NULL;
513516 JMM = NULL;
514517 Options = TargetOptions();
515518 AllocateGVsWithCode = false;
531534 WhichEngine = w;
532535 return *this;
533536 }
534
535 /// setJITMemoryManager - Sets the memory manager to use. This allows
536 /// clients to customize their memory allocation policies. If create() is
537 /// called and is successful, the created engine takes ownership of the
538 /// memory manager. This option defaults to NULL.
537
538 /// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows
539 /// clients to customize their memory allocation policies for the MCJIT. This
540 /// is only appropriate for the MCJIT; setting this and configuring the builder
541 /// to create anything other than MCJIT will cause a runtime error. If create()
542 /// is called and is successful, the created engine takes ownership of the
543 /// memory manager. This option defaults to NULL. Using this option nullifies
544 /// the setJITMemoryManager() option.
545 EngineBuilder &setMCJITMemoryManager(RTDyldMemoryManager *mcjmm) {
546 MCJMM = mcjmm;
547 JMM = NULL;
548 return *this;
549 }
550
551 /// setJITMemoryManager - Sets the JIT memory manager to use. This allows
552 /// clients to customize their memory allocation policies. This is only
553 /// appropriate for either JIT or MCJIT; setting this and configuring the
554 /// builder to create an interpreter will cause a runtime error. If create()
555 /// is called and is successful, the created engine takes ownership of the
556 /// memory manager. This option defaults to NULL. This option overrides
557 /// setMCJITMemoryManager() as well.
539558 EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
559 MCJMM = NULL;
540560 JMM = jmm;
541561 return *this;
542562 }
1515 #define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
1616
1717 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ExecutionEngine/JITMemoryManager.h"
18 #include "llvm/ExecutionEngine/RuntimeDyld.h"
1919 #include "llvm/Support/ErrorHandling.h"
2020 #include "llvm/Support/Memory.h"
2121
3434 /// in the JITed object. Permissions can be applied either by calling
3535 /// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions
3636 /// directly. Clients of MCJIT should call MCJIT::finalizeObject.
37 class SectionMemoryManager : public JITMemoryManager {
37 class SectionMemoryManager : public RTDyldMemoryManager {
3838 SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
3939 void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
4040
107107 MemoryGroup CodeMem;
108108 MemoryGroup RWDataMem;
109109 MemoryGroup RODataMem;
110
111 public:
112 ///
113 /// Functions below are not used by MCJIT or RuntimeDyld, but must be
114 /// implemented because they are declared as pure virtuals in the base class.
115 ///
116
117 virtual void setMemoryWritable() {
118 llvm_unreachable("Unexpected call!");
119 }
120 virtual void setMemoryExecutable() {
121 llvm_unreachable("Unexpected call!");
122 }
123 virtual void setPoisonMemory(bool poison) {
124 llvm_unreachable("Unexpected call!");
125 }
126 virtual void AllocateGOT() {
127 llvm_unreachable("Unexpected call!");
128 }
129 virtual uint8_t *getGOTBase() const {
130 llvm_unreachable("Unexpected call!");
131 return 0;
132 }
133 virtual uint8_t *startFunctionBody(const Function *F,
134 uintptr_t &ActualSize){
135 llvm_unreachable("Unexpected call!");
136 return 0;
137 }
138 virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
139 unsigned Alignment) {
140 llvm_unreachable("Unexpected call!");
141 return 0;
142 }
143 virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
144 uint8_t *FunctionEnd) {
145 llvm_unreachable("Unexpected call!");
146 }
147 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
148 llvm_unreachable("Unexpected call!");
149 return 0;
150 }
151 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
152 llvm_unreachable("Unexpected call!");
153 return 0;
154 }
155 virtual void deallocateFunctionBody(void *Body) {
156 llvm_unreachable("Unexpected call!");
157 }
158110 };
159111
160112 }
1313
1414 #define DEBUG_TYPE "jit"
1515 #include "llvm/ExecutionEngine/ExecutionEngine.h"
16 #include "llvm/ExecutionEngine/JITMemoryManager.h"
1617 #include "llvm/ADT/SmallString.h"
1718 #include "llvm/ADT/Statistic.h"
1819 #include "llvm/ExecutionEngine/GenericValue.h"
4647 ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
4748 Module *M,
4849 std::string *ErrorStr,
49 JITMemoryManager *JMM,
50 RTDyldMemoryManager *MCJMM,
5051 bool GVsWithCode,
5152 TargetMachine *TM) = 0;
5253 ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
454455 if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
455456 return 0;
456457
458 assert(!(JMM && MCJMM));
459
457460 // If the user specified a memory manager but didn't specify which engine to
458461 // create, we assume they only want the JIT, and we fail if they only want
459462 // the interpreter.
460 if (JMM) {
463 if (JMM || MCJMM) {
461464 if (WhichEngine & EngineKind::JIT)
462465 WhichEngine = EngineKind::JIT;
463466 else {
465468 *ErrorStr = "Cannot create an interpreter with a memory manager.";
466469 return 0;
467470 }
471 }
472
473 if (MCJMM && ! UseMCJIT) {
474 if (ErrorStr)
475 *ErrorStr =
476 "Cannot create a legacy JIT with a runtime dyld memory "
477 "manager.";
478 return 0;
468479 }
469480
470481 // Unless the interpreter was explicitly selected or the JIT is not linked,
479490
480491 if (UseMCJIT && ExecutionEngine::MCJITCtor) {
481492 ExecutionEngine *EE =
482 ExecutionEngine::MCJITCtor(M, ErrorStr, JMM,
493 ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
483494 AllocateGVsWithCode, TheTM.take());
484495 if (EE) return EE;
485496 } else if (ExecutionEngine::JITCtor) {
3838
3939 ExecutionEngine *MCJIT::createJIT(Module *M,
4040 std::string *ErrorStr,
41 JITMemoryManager *JMM,
41 RTDyldMemoryManager *MemMgr,
4242 bool GVsWithCode,
4343 TargetMachine *TM) {
4444 // Try to register the program as a source of symbols to resolve against.
4646 // FIXME: Don't do this here.
4747 sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
4848
49 return new MCJIT(M, TM, JMM ? JMM : new SectionMemoryManager(), GVsWithCode);
49 return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(),
50 GVsWithCode);
5051 }
5152
5253 MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
5354 bool AllocateGVsWithCode)
54 : ExecutionEngine(m), TM(tm), Ctx(0),
55 MemMgr(MM ? MM : new SectionMemoryManager()), Dyld(MemMgr),
56 IsLoaded(false), M(m), ObjCache(0) {
55 : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM),
56 IsLoaded(false), M(m), ObjCache(0) {
5757
5858 setDataLayout(TM->getDataLayout());
5959 }
9797
9898 static ExecutionEngine *createJIT(Module *M,
9999 std::string *ErrorStr,
100 JITMemoryManager *JMM,
100 RTDyldMemoryManager *MemMgr,
101101 bool GVsWithCode,
102102 TargetMachine *TM);
103103
336336 Mod->setTargetTriple(Triple::normalize(TargetTriple));
337337
338338 // Enable MCJIT if desired.
339 JITMemoryManager *JMM = 0;
339 RTDyldMemoryManager *RTDyldMM = 0;
340340 if (UseMCJIT && !ForceInterpreter) {
341341 builder.setUseMCJIT(true);
342342 if (RemoteMCJIT)
343 JMM = new RecordingMemoryManager();
343 RTDyldMM = new RecordingMemoryManager();
344344 else
345 JMM = new SectionMemoryManager();
346 builder.setJITMemoryManager(JMM);
345 RTDyldMM = new SectionMemoryManager();
346 builder.setMCJITMemoryManager(RTDyldMM);
347347 } else {
348348 if (RemoteMCJIT) {
349349 errs() << "error: Remote process execution requires -use-mcjit\n";
460460
461461 int Result;
462462 if (RemoteMCJIT) {
463 RecordingMemoryManager *MM = static_cast(JMM);
463 RecordingMemoryManager *MM = static_cast(RTDyldMM);
464464 // Everything is prepared now, so lay out our program for the target
465465 // address space, assign the section addresses to resolve any relocations,
466466 // and send it to the target.
494494 // invalidated will be known.
495495 (void)EE->getPointerToFunction(EntryFn);
496496 // Clear instruction cache before code will be executed.
497 if (JMM)
498 static_cast(JMM)->invalidateInstructionCache();
497 if (RTDyldMM)
498 static_cast(RTDyldMM)->invalidateInstructionCache();
499499
500500 // Run main.
501501 Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);
164164 std::string Error;
165165 TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
166166 .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
167 .setJITMemoryManager(MM)
167 .setMCJITMemoryManager(MM)
168168 .setErrorStr(&Error)
169169 .setOptLevel(CodeGenOpt::None)
170170 .setAllocateGVsWithCode(false) /*does this do anything?*/
187187 OwningPtr TM;
188188 OwningPtr TheJIT;
189189 IRBuilder<> Builder;
190 JITMemoryManager *MM;
190 RTDyldMemoryManager *MM;
191191
192192 OwningPtr M;
193193 };