mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-25 21:18:19 +00:00
Fix a couple issues with the JIT and multiple modules:
1. The "JITState" object creates a PassManager with the ModuleProvider that the jit is created with. If the ModuleProvider is removed and deleted, the PassManager is invalid. 2. The Global maps in the JIT were not invalidated with a ModuleProvider was removed. This could lead to a case where the Module would be freed, and a new Module with Globals at the same addresses could return invalid results. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51384 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -91,15 +91,17 @@ ExecutionEngine *ExecutionEngine::createJIT(ModuleProvider *MP,
|
||||
|
||||
JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
|
||||
JITMemoryManager *JMM)
|
||||
: ExecutionEngine(MP), TM(tm), TJI(tji), jitstate(MP) {
|
||||
: ExecutionEngine(MP), TM(tm), TJI(tji) {
|
||||
setTargetData(TM.getTargetData());
|
||||
|
||||
jitstate = new JITState(MP);
|
||||
|
||||
// Initialize MCE
|
||||
MCE = createEmitter(*this, JMM);
|
||||
|
||||
// Add target data
|
||||
MutexGuard locked(lock);
|
||||
FunctionPassManager &PM = jitstate.getPM(locked);
|
||||
FunctionPassManager &PM = jitstate->getPM(locked);
|
||||
PM.add(new TargetData(*TM.getTargetData()));
|
||||
|
||||
// Turn the machine code intermediate representation into bytes in memory that
|
||||
@@ -114,10 +116,54 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
|
||||
}
|
||||
|
||||
JIT::~JIT() {
|
||||
delete jitstate;
|
||||
delete MCE;
|
||||
delete &TM;
|
||||
}
|
||||
|
||||
/// addModuleProvider - Add a new ModuleProvider to the JIT. If we previously
|
||||
/// removed the last ModuleProvider, we need re-initialize jitstate with a valid
|
||||
/// ModuleProvider.
|
||||
void JIT::addModuleProvider(ModuleProvider *MP) {
|
||||
MutexGuard locked(lock);
|
||||
|
||||
if (Modules.empty()) {
|
||||
assert(!jitstate && "jitstate should be NULL if Modules vector is empty!");
|
||||
|
||||
jitstate = new JITState(MP);
|
||||
|
||||
FunctionPassManager &PM = jitstate->getPM(locked);
|
||||
PM.add(new TargetData(*TM.getTargetData()));
|
||||
|
||||
// Turn the machine code intermediate representation into bytes in memory
|
||||
// that may be executed.
|
||||
if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
|
||||
cerr << "Target does not support machine code emission!\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
// Initialize passes.
|
||||
PM.doInitialization();
|
||||
}
|
||||
|
||||
ExecutionEngine::addModuleProvider(MP);
|
||||
}
|
||||
|
||||
/// removeModuleProvider - If we are removing the last ModuleProvider,
|
||||
/// invalidate the jitstate since the PassManager it contains references a
|
||||
/// released ModuleProvider.
|
||||
Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) {
|
||||
Module *result = ExecutionEngine::removeModuleProvider(MP, E);
|
||||
|
||||
MutexGuard locked(lock);
|
||||
if (Modules.empty()) {
|
||||
delete jitstate;
|
||||
jitstate = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// run - Start execution with the specified function and arguments.
|
||||
///
|
||||
GenericValue JIT::runFunction(Function *F,
|
||||
@@ -289,15 +335,15 @@ void JIT::runJITOnFunction(Function *F) {
|
||||
|
||||
// JIT the function
|
||||
isAlreadyCodeGenerating = true;
|
||||
jitstate.getPM(locked).run(*F);
|
||||
jitstate->getPM(locked).run(*F);
|
||||
isAlreadyCodeGenerating = false;
|
||||
|
||||
// If the function referred to a global variable that had not yet been
|
||||
// emitted, it allocates memory for the global, but doesn't emit it yet. Emit
|
||||
// all of these globals now.
|
||||
while (!jitstate.getPendingGlobals(locked).empty()) {
|
||||
const GlobalVariable *GV = jitstate.getPendingGlobals(locked).back();
|
||||
jitstate.getPendingGlobals(locked).pop_back();
|
||||
while (!jitstate->getPendingGlobals(locked).empty()) {
|
||||
const GlobalVariable *GV = jitstate->getPendingGlobals(locked).back();
|
||||
jitstate->getPendingGlobals(locked).pop_back();
|
||||
EmitGlobalVariable(GV);
|
||||
}
|
||||
}
|
||||
@@ -387,7 +433,7 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
|
||||
unsigned MisAligned = ((intptr_t)Ptr & (A-1));
|
||||
Ptr = (char*)Ptr + (MisAligned ? (A-MisAligned) : 0);
|
||||
}
|
||||
jitstate.getPendingGlobals(locked).push_back(GV);
|
||||
jitstate->getPendingGlobals(locked).push_back(GV);
|
||||
}
|
||||
addGlobalMapping(GV, Ptr);
|
||||
return Ptr;
|
||||
|
||||
Reference in New Issue
Block a user