diff options
-rw-r--r-- | include/llvm/ExecutionEngine/JITEventListener.h | 15 | ||||
-rw-r--r-- | lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp | 10 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.cpp | 35 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.h | 8 |
4 files changed, 68 insertions, 0 deletions
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index eea603fcee..e6586e778c 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -26,6 +26,7 @@ class Function; class MachineFunction; class OProfileWrapper; class IntelJITEventsWrapper; +class ObjectImage; /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -76,6 +77,20 @@ public: /// matching NotifyFreeingMachineCode call. virtual void NotifyFreeingMachineCode(void *) {} + /// NotifyObjectEmitted - Called after an object has been successfully + /// emitted to memory. NotifyFunctionEmitted will not be called for + /// individual functions in the object. + /// + /// ELF-specific information + /// The ObjectImage contains the generated object image + /// with section headers updated to reflect the address at which sections + /// were loaded and with relocations performed in-place on debug sections. + virtual void NotifyObjectEmitted(const ObjectImage &Obj) {} + + /// NotifyFreeingObject - Called just before the memory associated with + /// a previously emitted object is released. + virtual void NotifyFreeingObject(const ObjectImage &Obj) {} + #if LLVM_USE_INTEL_JITEVENTS // Construct an IntelJITEventListener static JITEventListener *createIntelJITEventListener(); diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index 23f8607322..4cb0270d57 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -54,6 +54,10 @@ public: const EmittedFunctionDetails &Details); virtual void NotifyFreeingMachineCode(void *OldPtr); + + virtual void NotifyObjectEmitted(const ObjectImage &Obj); + + virtual void NotifyFreeingObject(const ObjectImage &Obj); }; static LineNumberInfo LineStartToIntelJITFormat( @@ -164,6 +168,12 @@ void IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) { } } +void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { +} + +void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { +} + } // anonymous namespace. namespace llvm { diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 71d713468b..91d9441b46 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -11,6 +11,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" @@ -57,6 +58,8 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, } MCJIT::~MCJIT() { + if (LoadedObject) + NotifyFreeingObject(LoadedObject.get()); delete MemMgr; delete TM; } @@ -107,6 +110,8 @@ void MCJIT::emitObject(Module *m) { // FIXME: Make this optional, maybe even move it to a JIT event listener LoadedObject->registerWithDebugger(); + NotifyObjectEmitted(*LoadedObject); + // FIXME: Add support for per-module compilation state isCompiled = true; } @@ -290,3 +295,33 @@ void *MCJIT::getPointerToNamedFunction(const std::string &Name, } return 0; } + +void MCJIT::RegisterJITEventListener(JITEventListener *L) { + if (L == NULL) + return; + MutexGuard locked(lock); + EventListeners.push_back(L); +} +void MCJIT::UnregisterJITEventListener(JITEventListener *L) { + if (L == NULL) + return; + MutexGuard locked(lock); + SmallVector<JITEventListener*, 2>::reverse_iterator I= + std::find(EventListeners.rbegin(), EventListeners.rend(), L); + if (I != EventListeners.rend()) { + std::swap(*I, EventListeners.back()); + EventListeners.pop_back(); + } +} +void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { + MutexGuard locked(lock); + for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { + EventListeners[I]->NotifyObjectEmitted(Obj); + } +} +void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { + MutexGuard locked(lock); + for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { + EventListeners[I]->NotifyFreeingObject(Obj); + } +} diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 6cffcc5b82..571080d2bd 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -11,6 +11,7 @@ #define LLVM_LIB_EXECUTIONENGINE_MCJIT_H #include "llvm/PassManager.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" @@ -30,6 +31,7 @@ class MCJIT : public ExecutionEngine { MCContext *Ctx; RTDyldMemoryManager *MemMgr; RuntimeDyld Dyld; + SmallVector<JITEventListener*, 2> EventListeners; // FIXME: Add support for multiple modules bool isCompiled; @@ -75,6 +77,9 @@ public: Dyld.mapSectionAddress(LocalAddress, TargetAddress); } + virtual void RegisterJITEventListener(JITEventListener *L); + virtual void UnregisterJITEventListener(JITEventListener *L); + /// @} /// @name (Private) Registration Interfaces /// @{ @@ -98,6 +103,9 @@ protected: /// is passed as a parameter here to prepare for multiple module support in /// the future. void emitObject(Module *M); + + void NotifyObjectEmitted(const ObjectImage& Obj); + void NotifyFreeingObject(const ObjectImage& Obj); }; } // End llvm namespace |