Commit 90cb2606 by Ben Clayton

Reactor: Fix all memory leaks with rr::DebugInfo.

DebugInfo::NotifyObjectEmitted and NotifyFreeingObject have become statics as the free-object callback happens after the DebugInfo instance is destroyed. This isn't an issue as the JITEventListener is a singleton in LLVM. Bug: b/133399620 Change-Id: I93fa73d0e416ba3c09c6550cc0d3abd56354e862 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31837Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 3971b19b
...@@ -643,18 +643,12 @@ namespace rr ...@@ -643,18 +643,12 @@ namespace rr
ObjLayer::NotifyLoadedFtor(), ObjLayer::NotifyLoadedFtor(),
[](llvm::orc::VModuleKey, const llvm::object::ObjectFile &Obj, const llvm::RuntimeDyld::LoadedObjectInfo &L) { [](llvm::orc::VModuleKey, const llvm::object::ObjectFile &Obj, const llvm::RuntimeDyld::LoadedObjectInfo &L) {
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
if (debugInfo != nullptr) DebugInfo::NotifyObjectEmitted(Obj, L);
{
debugInfo->NotifyObjectEmitted(Obj, L);
}
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
}, },
[](llvm::orc::VModuleKey, const llvm::object::ObjectFile &Obj) { [](llvm::orc::VModuleKey, const llvm::object::ObjectFile &Obj) {
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
if (debugInfo != nullptr) DebugInfo::NotifyFreeingObject(Obj);
{
debugInfo->NotifyFreeingObject(Obj);
}
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
} }
), ),
...@@ -963,6 +957,10 @@ namespace rr ...@@ -963,6 +957,10 @@ namespace rr
Nucleus::~Nucleus() Nucleus::~Nucleus()
{ {
#ifdef ENABLE_RR_DEBUG_INFO
debugInfo.reset(nullptr);
#endif // ENABLE_RR_DEBUG_INFO
::reactorJIT->endSession(); ::reactorJIT->endSession();
::codegenMutex.unlock(); ::codegenMutex.unlock();
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <cctype> #include <cctype>
#include <fstream> #include <fstream>
#include <mutex>
#include <regex> #include <regex>
#include <sstream> #include <sstream>
#include <string> #include <string>
...@@ -45,6 +46,12 @@ namespace ...@@ -45,6 +46,12 @@ namespace
{ {
return llvm::StringRef(path).rsplit('/'); return llvm::StringRef(path).rsplit('/');
} }
// Note: createGDBRegistrationListener() returns a pointer to a singleton.
// Nothing is actually created.
auto jitEventListener = llvm::JITEventListener::createGDBRegistrationListener(); // guarded by jitEventListenerMutex
std::mutex jitEventListenerMutex;
} // anonymous namespaces } // anonymous namespaces
namespace rr namespace rr
...@@ -61,14 +68,13 @@ namespace rr ...@@ -61,14 +68,13 @@ namespace rr
auto location = getCallerLocation(); auto location = getCallerLocation();
auto fileAndDir = splitPath(location.function.file.c_str()); auto fileAndDir = splitPath(location.function.file.c_str());
diBuilder = new llvm::DIBuilder(*module); diBuilder.reset(new llvm::DIBuilder(*module));
diCU = diBuilder->createCompileUnit( diCU = diBuilder->createCompileUnit(
llvm::dwarf::DW_LANG_C, llvm::dwarf::DW_LANG_C,
diBuilder->createFile(fileAndDir.first, fileAndDir.second), diBuilder->createFile(fileAndDir.first, fileAndDir.second),
"Reactor", "Reactor",
0, "", 0); 0, "", 0);
jitEventListener = llvm::JITEventListener::createGDBRegistrationListener();
registerBasicTypes(); registerBasicTypes();
SmallVector<Metadata *, 8> EltTys; SmallVector<Metadata *, 8> EltTys;
...@@ -94,11 +100,13 @@ namespace rr ...@@ -94,11 +100,13 @@ namespace rr
builder->SetCurrentDebugLocation(diRootLocation); builder->SetCurrentDebugLocation(diRootLocation);
} }
DebugInfo::~DebugInfo() = default;
void DebugInfo::Finalize() void DebugInfo::Finalize()
{ {
while (diScope.size() > 0) while (diScope.size() > 0)
{ {
emitPending(diScope.back(), builder, diBuilder); emitPending(diScope.back(), builder);
diScope.pop_back(); diScope.pop_back();
} }
diBuilder->finalize(); diBuilder->finalize();
...@@ -127,7 +135,7 @@ namespace rr ...@@ -127,7 +135,7 @@ namespace rr
void DebugInfo::Flush() void DebugInfo::Flush()
{ {
emitPending(diScope.back(), builder, diBuilder); emitPending(diScope.back(), builder);
} }
void DebugInfo::syncScope(Backtrace const& backtrace) void DebugInfo::syncScope(Backtrace const& backtrace)
...@@ -141,7 +149,7 @@ namespace rr ...@@ -141,7 +149,7 @@ namespace rr
int(diScope.size() - 1), scope.di, int(diScope.size() - 1), scope.di,
scope.location.function.file.c_str(), scope.location.function.file.c_str(),
int(scope.location.line)); int(scope.location.line));
emitPending(scope, builder, diBuilder); emitPending(scope, builder);
diScope.pop_back(); diScope.pop_back();
} }
}; };
...@@ -172,7 +180,7 @@ namespace rr ...@@ -172,7 +180,7 @@ namespace rr
auto di = diBuilder->createLexicalBlock(scope.di, file, newLocation.line, 0); auto di = diBuilder->createLexicalBlock(scope.di, file, newLocation.line, 0);
LOG(" STACK(%d): Jumped backwards %d -> %d. di: %p -> %p", int(i), LOG(" STACK(%d): Jumped backwards %d -> %d. di: %p -> %p", int(i),
oldLocation.line, newLocation.line, scope.di, di); oldLocation.line, newLocation.line, scope.di, di);
emitPending(scope, builder, diBuilder); emitPending(scope, builder);
scope = {newLocation, di}; scope = {newLocation, di};
shrink(i+1); shrink(i+1);
break; break;
...@@ -263,7 +271,7 @@ namespace rr ...@@ -263,7 +271,7 @@ namespace rr
auto &scope = diScope[i]; auto &scope = diScope[i];
if (scope.pending.location != location) if (scope.pending.location != location)
{ {
emitPending(scope, builder, diBuilder); emitPending(scope, builder);
} }
auto value = V(variable); auto value = V(variable);
...@@ -297,7 +305,7 @@ namespace rr ...@@ -297,7 +305,7 @@ namespace rr
} }
} }
void DebugInfo::emitPending(Scope &scope, IRBuilder *builder, llvm::DIBuilder *diBuilder) void DebugInfo::emitPending(Scope &scope, IRBuilder *builder)
{ {
auto const &pending = scope.pending; auto const &pending = scope.pending;
if (pending.value == nullptr) if (pending.value == nullptr)
...@@ -373,11 +381,13 @@ namespace rr ...@@ -373,11 +381,13 @@ namespace rr
void DebugInfo::NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L) void DebugInfo::NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L)
{ {
std::unique_lock<std::mutex> lock(jitEventListenerMutex);
jitEventListener->NotifyObjectEmitted(Obj, static_cast<const llvm::RuntimeDyld::LoadedObjectInfo&>(L)); jitEventListener->NotifyObjectEmitted(Obj, static_cast<const llvm::RuntimeDyld::LoadedObjectInfo&>(L));
} }
void DebugInfo::NotifyFreeingObject(const llvm::object::ObjectFile &Obj) void DebugInfo::NotifyFreeingObject(const llvm::object::ObjectFile &Obj)
{ {
std::unique_lock<std::mutex> lock(jitEventListenerMutex);
jitEventListener->NotifyFreeingObject(Obj); jitEventListener->NotifyFreeingObject(Obj);
} }
......
...@@ -71,6 +71,8 @@ namespace rr ...@@ -71,6 +71,8 @@ namespace rr
llvm::Module *module, llvm::Module *module,
llvm::Function *function); llvm::Function *function);
~DebugInfo();
// Finalize debug info generation. Must be called before the LLVM module // Finalize debug info generation. Must be called before the LLVM module
// is built. // is built.
void Finalize(); void Finalize();
...@@ -88,11 +90,11 @@ namespace rr ...@@ -88,11 +90,11 @@ namespace rr
// NotifyObjectEmitted informs any attached debuggers of the JIT'd // NotifyObjectEmitted informs any attached debuggers of the JIT'd
// object. // object.
void NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L); static void NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L);
// NotifyFreeingObject informs any attached debuggers that the JIT'd // NotifyFreeingObject informs any attached debuggers that the JIT'd
// object is now invalid. // object is now invalid.
void NotifyFreeingObject(const llvm::object::ObjectFile &Obj); static void NotifyFreeingObject(const llvm::object::ObjectFile &Obj);
private: private:
struct Token struct Token
...@@ -168,7 +170,7 @@ namespace rr ...@@ -168,7 +170,7 @@ namespace rr
void registerBasicTypes(); void registerBasicTypes();
void emitPending(Scope &scope, IRBuilder *builder, llvm::DIBuilder *diBuilder); void emitPending(Scope &scope, IRBuilder *builder);
// Returns the source location of the non-Reactor calling function. // Returns the source location of the non-Reactor calling function.
Location getCallerLocation() const; Location getCallerLocation() const;
...@@ -192,7 +194,7 @@ namespace rr ...@@ -192,7 +194,7 @@ namespace rr
llvm::Module *module; llvm::Module *module;
llvm::Function *function; llvm::Function *function;
llvm::DIBuilder *diBuilder; std::unique_ptr<llvm::DIBuilder> diBuilder;
llvm::DICompileUnit *diCU; llvm::DICompileUnit *diCU;
llvm::DISubprogram *diSubprogram; llvm::DISubprogram *diSubprogram;
llvm::DILocation *diRootLocation; llvm::DILocation *diRootLocation;
...@@ -200,7 +202,6 @@ namespace rr ...@@ -200,7 +202,6 @@ namespace rr
std::unordered_map<std::string, llvm::DIFile*> diFiles; std::unordered_map<std::string, llvm::DIFile*> diFiles;
std::unordered_map<llvm::Type*, llvm::DIType*> diTypes; std::unordered_map<llvm::Type*, llvm::DIType*> diTypes;
std::unordered_map<std::string, std::unique_ptr<LineTokens>> fileTokens; std::unordered_map<std::string, std::unique_ptr<LineTokens>> fileTokens;
llvm::JITEventListener *jitEventListener;
std::vector<void const*> pushed; std::vector<void const*> pushed;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment