class MachineFunction;
class OProfileWrapper;
class IntelJITEventsWrapper;
+class ObjectImage;
/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
/// about a generated machine code function.
/// 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();
const EmittedFunctionDetails &Details);
virtual void NotifyFreeingMachineCode(void *OldPtr);
+
+ virtual void NotifyObjectEmitted(const ObjectImage &Obj);
+
+ virtual void NotifyFreeingObject(const ObjectImage &Obj);
};
static LineNumberInfo LineStartToIntelJITFormat(
}
}
+void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
+}
+
+void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
+}
+
} // anonymous namespace.
namespace llvm {
#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"
}
MCJIT::~MCJIT() {
+ if (LoadedObject)
+ NotifyFreeingObject(LoadedObject.get());
delete MemMgr;
delete TM;
}
// 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;
}
}
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);
+ }
+}
#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"
MCContext *Ctx;
RTDyldMemoryManager *MemMgr;
RuntimeDyld Dyld;
+ SmallVector<JITEventListener*, 2> EventListeners;
// FIXME: Add support for multiple modules
bool isCompiled;
Dyld.mapSectionAddress(LocalAddress, TargetAddress);
}
+ virtual void RegisterJITEventListener(JITEventListener *L);
+ virtual void UnregisterJITEventListener(JITEventListener *L);
+
/// @}
/// @name (Private) Registration Interfaces
/// @{
/// 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