diff options
8 files changed, 75 insertions, 67 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/JITEventListener.h b/llvm/include/llvm/ExecutionEngine/JITEventListener.h index 589ca612f04..1b08379b8c3 100644 --- a/llvm/include/llvm/ExecutionEngine/JITEventListener.h +++ b/llvm/include/llvm/ExecutionEngine/JITEventListener.h @@ -42,23 +42,26 @@ class ObjectFile; /// The default implementation of each method does nothing. class JITEventListener { public: + using ObjectKey = uint64_t; + JITEventListener() = default; virtual ~JITEventListener() = default; - /// NotifyObjectEmitted - Called after an object has been successfully - /// emitted to memory. NotifyFunctionEmitted will not be called for + /// notifyObjectLoaded - Called after an object has had its sections allocated + /// and addresses assigned to all symbols. Note: Section memory will not have + /// been relocated yet. notifyFunctionLoaded 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 object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) {} + virtual void notifyObjectLoaded(ObjectKey K, const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) {} - /// NotifyFreeingObject - Called just before the memory associated with + /// notifyFreeingObject - Called just before the memory associated with /// a previously emitted object is released. - virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {} + virtual void notifyFreeingObject(ObjectKey K) {} // Get a pointe to the GDB debugger registration listener. static JITEventListener *createGDBRegistrationListener(); diff --git a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp index fd4f0746f7f..8204f5a9026 100644 --- a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp +++ b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp @@ -76,8 +76,8 @@ struct RegisteredObjectInfo { }; // Buffer for an in-memory object file in executable memory -typedef llvm::DenseMap< const char*, RegisteredObjectInfo> - RegisteredObjectBufferMap; +typedef llvm::DenseMap<JITEventListener::ObjectKey, RegisteredObjectInfo> + RegisteredObjectBufferMap; /// Global access point for the JIT debugging interface designed for use with a /// singleton toolbox. Handles thread-safe registration and deregistration of @@ -99,13 +99,13 @@ public: /// Creates an entry in the JIT registry for the buffer @p Object, /// which must contain an object file in executable memory with any /// debug information for the debugger. - void NotifyObjectEmitted(const ObjectFile &Object, - const RuntimeDyld::LoadedObjectInfo &L) override; + void notifyObjectLoaded(ObjectKey K, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) override; /// Removes the internal registration of @p Object, and /// frees associated resources. /// Returns true if @p Object was found in ObjectBufferMap. - void NotifyFreeingObject(const ObjectFile &Object) override; + void notifyFreeingObject(ObjectKey K) override; private: /// Deregister the debug info for the given object file from the debugger @@ -147,11 +147,11 @@ GDBJITRegistrationListener::~GDBJITRegistrationListener() { ObjectBufferMap.clear(); } -void GDBJITRegistrationListener::NotifyObjectEmitted( - const ObjectFile &Object, - const RuntimeDyld::LoadedObjectInfo &L) { +void GDBJITRegistrationListener::notifyObjectLoaded( + ObjectKey K, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { - OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object); + OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Obj); // Bail out if debug objects aren't supported. if (!DebugObj.getBinary()) @@ -160,11 +160,8 @@ void GDBJITRegistrationListener::NotifyObjectEmitted( const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart(); size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize(); - const char *Key = Object.getMemoryBufferRef().getBufferStart(); - - assert(Key && "Attempt to register a null object with a debugger."); llvm::MutexGuard locked(*JITDebugLock); - assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() && + assert(ObjectBufferMap.find(K) == ObjectBufferMap.end() && "Second attempt to perform debug registration."); jit_code_entry* JITCodeEntry = new jit_code_entry(); @@ -175,16 +172,15 @@ void GDBJITRegistrationListener::NotifyObjectEmitted( JITCodeEntry->symfile_addr = Buffer; JITCodeEntry->symfile_size = Size; - ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry, - std::move(DebugObj)); + ObjectBufferMap[K] = + RegisteredObjectInfo(Size, JITCodeEntry, std::move(DebugObj)); NotifyDebugger(JITCodeEntry); } } -void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) { - const char *Key = Object.getMemoryBufferRef().getBufferStart(); +void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) { llvm::MutexGuard locked(*JITDebugLock); - RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key); + RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(K); if (I != ObjectBufferMap.end()) { deregisterObjectInternal(I); diff --git a/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index 211f5216811..e9051c19850 100644 --- a/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -47,7 +47,7 @@ class IntelJITEventListener : public JITEventListener { typedef DenseMap<const void *, MethodAddressVector> ObjectMap; ObjectMap LoadedObjectMap; - std::map<const char*, OwningBinary<ObjectFile>> DebugObjects; + std::map<ObjectKey, OwningBinary<ObjectFile>> DebugObjects; public: IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) { @@ -57,10 +57,10 @@ public: ~IntelJITEventListener() { } - void NotifyObjectEmitted(const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) override; + void notifyObjectLoaded(ObjectKey Key, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) override; - void NotifyFreeingObject(const ObjectFile &Obj) override; + void notifyFreeingObject(ObjectKey Key) override; }; static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress, @@ -96,9 +96,9 @@ static iJIT_Method_Load FunctionDescToIntelJITFormat( return Result; } -void IntelJITEventListener::NotifyObjectEmitted( - const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) { +void IntelJITEventListener::notifyObjectLoaded( + ObjectKey Key, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj); const ObjectFile *DebugObj = DebugObjOwner.getBinary(); @@ -188,17 +188,17 @@ void IntelJITEventListener::NotifyObjectEmitted( // registered function addresses for each loaded object. We will // use the MethodIDs map to get the registered ID for each function. LoadedObjectMap[ObjData] = Functions; - DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner); + DebugObjects[Key] = std::move(DebugObjOwner); } -void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { +void IntelJITEventListener::notifyFreeingObject(ObjectKey Key) { // This object may not have been registered with the listener. If it wasn't, // bail out. - if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end()) + if (DebugObjects.find(Key) == DebugObjects.end()) return; // Get the address of the object image for use as a unique identifier - const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary(); + const ObjectFile &DebugObj = *DebugObjects[Key].getBinary(); const void* ObjData = DebugObj.getData().data(); // Get the object's function list from LoadedObjectMap @@ -223,7 +223,7 @@ void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { // Erase the object from LoadedObjectMap LoadedObjectMap.erase(OI); - DebugObjects.erase(Obj.getData().data()); + DebugObjects.erase(Key); } } // anonymous namespace. diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 8122ed28b7f..ffc6707e148 100644 --- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -95,7 +95,7 @@ MCJIT::~MCJIT() { for (auto &Obj : LoadedObjects) if (Obj) - NotifyFreeingObject(*Obj); + notifyFreeingObject(*Obj); Archives.clear(); } @@ -119,7 +119,7 @@ void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) { if (Dyld.hasError()) report_fatal_error(Dyld.getErrorString()); - NotifyObjectEmitted(*Obj, *L); + notifyObjectLoaded(*Obj, *L); LoadedObjects.push_back(std::move(Obj)); } @@ -226,7 +226,7 @@ void MCJIT::generateCodeForModule(Module *M) { if (Dyld.hasError()) report_fatal_error(Dyld.getErrorString()); - NotifyObjectEmitted(*LoadedObject.get(), *L); + notifyObjectLoaded(*LoadedObject.get(), *L); Buffers.push_back(std::move(ObjectToLoad)); LoadedObjects.push_back(std::move(*LoadedObject)); @@ -648,19 +648,23 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) { } } -void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj, - const RuntimeDyld::LoadedObjectInfo &L) { +void MCJIT::notifyObjectLoaded(const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { + uint64_t Key = + static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data())); MutexGuard locked(lock); MemMgr->notifyObjectLoaded(this, Obj); for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { - EventListeners[I]->NotifyObjectEmitted(Obj, L); + EventListeners[I]->notifyObjectLoaded(Key, Obj, L); } } -void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) { +void MCJIT::notifyFreeingObject(const object::ObjectFile &Obj) { + uint64_t Key = + static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data())); MutexGuard locked(lock); for (JITEventListener *L : EventListeners) - L->NotifyFreeingObject(Obj); + L->notifyFreeingObject(Key); } JITSymbol diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h index 943b14942a0..1119e138720 100644 --- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -331,9 +331,9 @@ protected: /// the future. std::unique_ptr<MemoryBuffer> emitObject(Module *M); - void NotifyObjectEmitted(const object::ObjectFile& Obj, - const RuntimeDyld::LoadedObjectInfo &L); - void NotifyFreeingObject(const object::ObjectFile& Obj); + void notifyObjectLoaded(const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L); + void notifyFreeingObject(const object::ObjectFile &Obj); JITSymbol findExistingSymbol(const std::string &Name); Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly); diff --git a/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index 6f0825fb38d..21af6b585c4 100644 --- a/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -40,7 +40,7 @@ class OProfileJITEventListener : public JITEventListener { std::unique_ptr<OProfileWrapper> Wrapper; void initialize(); - std::map<const char*, OwningBinary<ObjectFile>> DebugObjects; + std::map<ObjectKey, OwningBinary<ObjectFile>> DebugObjects; public: OProfileJITEventListener(std::unique_ptr<OProfileWrapper> LibraryWrapper) @@ -50,10 +50,10 @@ public: ~OProfileJITEventListener(); - void NotifyObjectEmitted(const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) override; + void notifyObjectLoaded(ObjectKey Key, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) override; - void NotifyFreeingObject(const ObjectFile &Obj) override; + void notifyFreeingObject(ObjectKey Key) override; }; void OProfileJITEventListener::initialize() { @@ -78,9 +78,9 @@ OProfileJITEventListener::~OProfileJITEventListener() { } } -void OProfileJITEventListener::NotifyObjectEmitted( - const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) { +void OProfileJITEventListener::notifyObjectLoaded( + ObjectKey Key, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { if (!Wrapper->isAgentAvailable()) { return; } @@ -137,18 +137,18 @@ void OProfileJITEventListener::NotifyObjectEmitted( } } - DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner); + DebugObjects[Key] = std::move(DebugObjOwner); } -void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { +void OProfileJITEventListener::notifyFreeingObject(ObjectKey Key) { if (Wrapper->isAgentAvailable()) { // If there was no agent registered when the original object was loaded then // we won't have created a debug object for it, so bail out. - if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end()) + if (DebugObjects.find(Key) == DebugObjects.end()) return; - const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary(); + const ObjectFile &DebugObj = *DebugObjects[Key].getBinary(); // Use symbol info to iterate functions in the object. for (symbol_iterator I = DebugObj.symbol_begin(), @@ -171,7 +171,7 @@ void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { } } - DebugObjects.erase(Obj.getData().data()); + DebugObjects.erase(Key); } } // anonymous namespace. diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index deddfcb10e1..817a4b89bfb 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -492,13 +492,17 @@ private: void notifyFinalized(orc::VModuleKey K, const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { + uint64_t Key = static_cast<uint64_t>( + reinterpret_cast<uintptr_t>(Obj.getData().data())); for (auto &Listener : EventListeners) - Listener->NotifyObjectEmitted(Obj, LoadedObjInfo); + Listener->notifyObjectLoaded(Key, Obj, LoadedObjInfo); } void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) { + uint64_t Key = static_cast<uint64_t>( + reinterpret_cast<uintptr_t>(Obj.getData().data())); for (auto &Listener : EventListeners) - Listener->NotifyFreeingObject(Obj); + Listener->notifyFreeingObject(Key); } orc::ExecutionSession ES; diff --git a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp index 7bf8120d23d..f195d028299 100644 --- a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp +++ b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp @@ -66,9 +66,9 @@ public: CloseMarker(); } - void NotifyObjectEmitted(const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) override; - void NotifyFreeingObject(const ObjectFile &Obj) override; + void notifyObjectLoaded(ObjectKey K, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) override; + void notifyFreeingObject(ObjectKey K) override; private: bool InitDebuggingDir(); @@ -227,8 +227,9 @@ PerfJITEventListener::PerfJITEventListener() : Pid(::getpid()) { SuccessfullyInitialized = true; } -void PerfJITEventListener::NotifyObjectEmitted( - const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) { +void PerfJITEventListener::notifyObjectLoaded( + ObjectKey K, const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { if (!SuccessfullyInitialized) return; @@ -280,7 +281,7 @@ void PerfJITEventListener::NotifyObjectEmitted( Dumpstream->flush(); } -void PerfJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { +void PerfJITEventListener::notifyFreeingObject(ObjectKey K) { // perf currently doesn't have an interface for unloading. But munmap()ing the // code section does, so that's ok. } |

