summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2008-05-21 16:34:48 +0000
committerNate Begeman <natebegeman@mac.com>2008-05-21 16:34:48 +0000
commit8f83fc4d9b8161717f939f27cf824dc094d26e6c (patch)
tree39b0e75303098439e9119eefa9eaba7028614145 /llvm/lib/ExecutionEngine
parentf025a8bc1c78b7a56c9fb2589305ec6dc8f4e331 (diff)
downloadbcm5719-llvm-8f83fc4d9b8161717f939f27cf824dc094d26e6c.tar.gz
bcm5719-llvm-8f83fc4d9b8161717f939f27cf824dc094d26e6c.zip
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. llvm-svn: 51384
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r--llvm/lib/ExecutionEngine/ExecutionEngine.cpp17
-rw-r--r--llvm/lib/ExecutionEngine/JIT/JIT.cpp60
-rw-r--r--llvm/lib/ExecutionEngine/JIT/JIT.h6
3 files changed, 75 insertions, 8 deletions
diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
index 535f4ac90f7..8b94ad02840 100644
--- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -59,6 +59,7 @@ Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
ModuleProvider *MP = *I;
if (MP == P) {
Modules.erase(I);
+ clearGlobalMappingsFromModule(MP->getModule());
return MP->releaseModule(ErrInfo);
}
}
@@ -106,6 +107,22 @@ void ExecutionEngine::clearAllGlobalMappings() {
state.getGlobalAddressReverseMap(locked).clear();
}
+/// clearGlobalMappingsFromModule - Clear all global mappings that came from a
+/// particular module, because it has been removed from the JIT.
+void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
+ MutexGuard locked(lock);
+
+ for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
+ state.getGlobalAddressMap(locked).erase(FI);
+ state.getGlobalAddressReverseMap(locked).erase(FI);
+ }
+ for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
+ GI != GE; ++GI) {
+ state.getGlobalAddressMap(locked).erase(GI);
+ state.getGlobalAddressReverseMap(locked).erase(GI);
+ }
+}
+
/// updateGlobalMapping - Replace an existing mapping for GV with a new
/// address. This updates both maps as required. If "Addr" is null, the
/// entry for the global is removed from the mappings.
diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp
index 4b888ef018c..48286e915ee 100644
--- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp
@@ -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;
diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.h b/llvm/lib/ExecutionEngine/JIT/JIT.h
index 69e301bf6d0..7366f944365 100644
--- a/llvm/lib/ExecutionEngine/JIT/JIT.h
+++ b/llvm/lib/ExecutionEngine/JIT/JIT.h
@@ -54,7 +54,7 @@ class JIT : public ExecutionEngine {
TargetJITInfo &TJI; // The JITInfo for the target we are compiling to
MachineCodeEmitter *MCE; // MCE object
- JITState jitstate;
+ JITState *jitstate;
JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM);
@@ -76,6 +76,10 @@ public:
return createJIT(MP, Err, 0);
}
+ virtual void addModuleProvider(ModuleProvider *MP);
+ virtual Module *removeModuleProvider(ModuleProvider *MP,
+ std::string *ErrInfo = 0);
+
/// run - Start execution with the specified function and arguments.
///
virtual GenericValue runFunction(Function *F,
OpenPOWER on IntegriCloud