================ @@ -755,11 +755,240 @@ size_t ModuleList::GetIndexForModule(const Module *module) const { } namespace { +/// A wrapper around ModuleList for shared modules. Provides fast lookups for +/// file-based ModuleSpec queries. +class SharedModuleList { +public: + /// Finds all the modules matching the module_spec, and adds them to \p + /// matching_module_list. + void FindModules(const ModuleSpec &module_spec, + ModuleList &matching_module_list) const { + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + // Try map first for performance - if found, skip expensive full list + // search + if (FindModulesInMap(module_spec, matching_module_list)) + return; + m_list.FindModules(module_spec, matching_module_list); + // Assert that modules were found in the list but not the map, it's + // because the module_spec has no filename or the found module has a + // different filename. For example, when searching by UUID and finding a + // module with an alias. + assert((matching_module_list.IsEmpty() || + module_spec.GetFileSpec().GetFilename().IsEmpty() || + module_spec.GetFileSpec().GetFilename() != + matching_module_list.GetModuleAtIndex(0) + ->GetFileSpec() + .GetFilename()) && + "Search by name not found in SharedModuleList's map"); + } + + ModuleSP FindModule(const Module *module_ptr) { + if (!module_ptr) + return ModuleSP(); + + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + if (ModuleSP result = FindModuleInMap(module_ptr)) + return result; + return m_list.FindModule(module_ptr); + } + + // UUID searches bypass map since UUIDs aren't indexed by filename. + ModuleSP FindModule(const UUID &uuid) const { + return m_list.FindModule(uuid); + } + + void Append(const ModuleSP &module_sp, bool use_notifier) { + if (!module_sp) + return; + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + m_list.Append(module_sp, use_notifier); + AddToMap(module_sp); + } + + size_t RemoveOrphans(bool mandatory) { + std::unique_lock<std::recursive_mutex> lock(GetMutex(), std::defer_lock); + if (mandatory) { + lock.lock(); + } else { + if (!lock.try_lock()) + return 0; + } + size_t total_count = 0; + size_t run_count; + do { + // Remove indexed orphans first, then remove non-indexed orphans. This + // order is important because the shared count will be different if a + // module is indexed or not. + run_count = RemoveOrphansFromMapAndList(); + run_count += m_list.RemoveOrphans(mandatory); + total_count += run_count; + // Because removing orphans might make new orphans, remove from both + // containers until a fixed-point is reached. + } while (run_count != 0); + + return total_count; + } + + bool Remove(const ModuleSP &module_sp, bool use_notifier = true) { + if (!module_sp) + return false; + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + RemoveFromMap(module_sp.get()); + return m_list.Remove(module_sp, use_notifier); + } + + void ReplaceEquivalent(const ModuleSP &module_sp, + llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules) { + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + m_list.ReplaceEquivalent(module_sp, old_modules); + ReplaceEquivalentInMap(module_sp); + } + + bool RemoveIfOrphaned(const Module *module_ptr) { + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + RemoveFromMap(module_ptr, /*if_orphaned =*/true); + return m_list.RemoveIfOrphaned(module_ptr); + } + + std::recursive_mutex &GetMutex() const { return m_list.GetMutex(); } + +private: + ModuleSP FindModuleInMap(const Module *module_ptr) { + if (!module_ptr->GetFileSpec().GetFilename()) + return ModuleSP(); + ConstString name = module_ptr->GetFileSpec().GetFilename(); + auto it = m_name_to_modules.find(name); + if (it == m_name_to_modules.end()) + return ModuleSP(); + const llvm::SmallVectorImpl<ModuleSP> &vector = it->second; + for (auto &module_sp : vector) { ---------------- JDevlieghere wrote:
```suggestion for (ModuleSP &module_sp : vector) { ``` https://github.com/llvm/llvm-project/pull/152054 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits