Author: Stefan Gränitz Date: 2023-08-18T13:57:50+02:00 New Revision: af2eb838309d88f046d34bca6055f1de6078fa3b
URL: https://github.com/llvm/llvm-project/commit/af2eb838309d88f046d34bca6055f1de6078fa3b DIFF: https://github.com/llvm/llvm-project/commit/af2eb838309d88f046d34bca6055f1de6078fa3b.diff LOG: [lldb] Fix performance regression after adding GNUstep ObjC runtime We added support for the GNUstep ObjC runtime in 0b6264738f3d. In order to check if the target process uses GNUstep we run an expensive symbol lookup in `CreateInstance()`. This turned out to cause a heavy performance regression for non-GNUstep inferiors. This patch puts a cheaper check in front, so that the vast majority of requests should return early. This should fix the symptom for the moment. The conceptual question remains: Why does `LanguageRuntime::FindPlugin` invoke `create_callback` for each available runtime unconditionally in every `Process::ModulesDidLoad`? Reviewed By: jasonmolenda, jingham, bulbazord Differential Revision: https://reviews.llvm.org/D158205 Added: Modified: lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp index fb2656ef1385e7..39b3e816f4becf 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp @@ -37,6 +37,33 @@ void GNUstepObjCRuntime::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } +static bool CanModuleBeGNUstepObjCLibrary(const ModuleSP &module_sp, + const llvm::Triple &TT) { + if (!module_sp) + return false; + const FileSpec &module_file_spec = module_sp->GetFileSpec(); + if (!module_file_spec) + return false; + llvm::StringRef filename = module_file_spec.GetFilename().GetStringRef(); + if (TT.isOSBinFormatELF()) + return filename.starts_with("libobjc.so"); + if (TT.isOSWindows()) + return filename == "objc.dll"; + return false; +} + +static bool ScanForGNUstepObjCLibraryCandidate(const ModuleList &modules, + const llvm::Triple &TT) { + std::lock_guard<std::recursive_mutex> guard(modules.GetMutex()); + size_t num_modules = modules.GetSize(); + for (size_t i = 0; i < num_modules; i++) { + auto mod = modules.GetModuleAtIndex(i); + if (CanModuleBeGNUstepObjCLibrary(mod, TT)) + return true; + } + return false; +} + LanguageRuntime *GNUstepObjCRuntime::CreateInstance(Process *process, LanguageType language) { if (language != eLanguageTypeObjC) @@ -50,6 +77,9 @@ LanguageRuntime *GNUstepObjCRuntime::CreateInstance(Process *process, return nullptr; const ModuleList &images = target.GetImages(); + if (!ScanForGNUstepObjCLibraryCandidate(images, TT)) + return nullptr; + if (TT.isOSBinFormatELF()) { SymbolContextList eh_pers; RegularExpression regex("__gnustep_objc[x]*_personality_v[0-9]+"); @@ -176,18 +206,8 @@ void GNUstepObjCRuntime::UpdateISAToDescriptorMapIfNeeded() { } bool GNUstepObjCRuntime::IsModuleObjCLibrary(const ModuleSP &module_sp) { - if (!module_sp) - return false; - const FileSpec &module_file_spec = module_sp->GetFileSpec(); - if (!module_file_spec) - return false; - llvm::StringRef filename = module_file_spec.GetFilename().GetStringRef(); const llvm::Triple &TT = GetTargetRef().GetArchitecture().GetTriple(); - if (TT.isOSBinFormatELF()) - return filename.starts_with("libobjc.so"); - if (TT.isOSWindows()) - return filename == "objc.dll"; - return false; + return CanModuleBeGNUstepObjCLibrary(module_sp, TT); } bool GNUstepObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits