aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/JIT/JIT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/JIT/JIT.cpp')
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp60
1 files changed, 53 insertions, 7 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 4b888ef018..48286e915e 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/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;