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.cpp70
1 files changed, 61 insertions, 9 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 008c5907d8..6940d85d75 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -289,11 +289,28 @@ Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) {
Module *result = ExecutionEngine::removeModuleProvider(MP, E);
MutexGuard locked(lock);
- if (Modules.empty()) {
+
+ if (jitstate->getMP() == MP) {
delete jitstate;
jitstate = 0;
}
+ if (!jitstate && !Modules.empty()) {
+ jitstate = new JITState(Modules[0]);
+
+ 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();
+ }
return result;
}
@@ -304,10 +321,28 @@ void JIT::deleteModuleProvider(ModuleProvider *MP, std::string *E) {
ExecutionEngine::deleteModuleProvider(MP, E);
MutexGuard locked(lock);
- if (Modules.empty()) {
+
+ if (jitstate->getMP() == MP) {
delete jitstate;
jitstate = 0;
}
+
+ if (!jitstate && !Modules.empty()) {
+ jitstate = new JITState(Modules[0]);
+
+ 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();
+ }
}
/// run - Start execution with the specified function and arguments.
@@ -488,14 +523,26 @@ void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {
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();
- EmitGlobalVariable(GV);
+ // If the function referred to another function that had not yet been
+ // read from bitcode, but we are jitting non-lazily, emit it now.
+ while (!jitstate->getPendingFunctions(locked).empty()) {
+ Function *PF = jitstate->getPendingFunctions(locked).back();
+ jitstate->getPendingFunctions(locked).pop_back();
+
+ // JIT the function
+ isAlreadyCodeGenerating = true;
+ jitstate->getPM(locked).run(*PF);
+ isAlreadyCodeGenerating = false;
+
+ // Now that the function has been jitted, ask the JITEmitter to rewrite
+ // the stub with real address of the function.
+ updateFunctionStub(PF);
}
+
+ // If the JIT is configured to emit info so that dlsym can be used to
+ // rewrite stubs to external globals, do so now.
+ if (areDlsymStubsEnabled() && isLazyCompilationDisabled())
+ updateDlsymStubTable();
}
/// getPointerToFunction - This method is used to get the address of the
@@ -644,3 +691,8 @@ char* JIT::getMemoryForGV(const GlobalVariable* GV) {
return new char[GVSize];
}
}
+
+void JIT::addPendingFunction(Function *F) {
+ MutexGuard locked(lock);
+ jitstate->getPendingFunctions(locked).push_back(F);
+}