mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-28 06:24:57 +00:00
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:
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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!");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user