diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h --- a/lldb/include/lldb/Symbol/Symtab.h +++ b/lldb/include/lldb/Symbol/Symtab.h @@ -13,6 +13,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" +#include #include #include @@ -173,15 +174,20 @@ ObjectFile *m_objfile; collection m_symbols; FileRangeToIndexMap m_file_addr_to_index; - UniqueCStringMap m_name_to_index; - UniqueCStringMap m_basename_to_index; - UniqueCStringMap m_method_to_index; - UniqueCStringMap m_selector_to_index; + + /// Maps function names to symbol indices (grouped by FunctionNameTypes) + std::map> + m_name_to_symbol_indices; mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table bool m_file_addr_to_index_computed : 1, m_name_indexes_computed : 1; private: + UniqueCStringMap &GetFunctypeMap(lldb::FunctionNameType type) { + auto map = m_name_to_symbol_indices.find(type); + assert(map != m_name_to_symbol_indices.end()); + return map->second; + } bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const { switch (symbol_debug_type) { diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -29,8 +29,17 @@ Symtab::Symtab(ObjectFile *objfile) : m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this), - m_name_to_index(), m_mutex(), m_file_addr_to_index_computed(false), - m_name_indexes_computed(false) {} + m_name_to_symbol_indices(), m_mutex(), + m_file_addr_to_index_computed(false), m_name_indexes_computed(false) { + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeNone, UniqueCStringMap())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeBase, UniqueCStringMap())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeMethod, UniqueCStringMap())); + m_name_to_symbol_indices.emplace(std::make_pair( + lldb::eFunctionNameTypeSelector, UniqueCStringMap())); +} Symtab::~Symtab() {} @@ -51,7 +60,8 @@ // Clients should grab the mutex from this symbol table and lock it manually // when calling this function to avoid performance issues. uint32_t symbol_idx = m_symbols.size(); - m_name_to_index.Clear(); + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); + name_to_index.Clear(); m_file_addr_to_index.Clear(); m_symbols.push_back(symbol); m_file_addr_to_index_computed = false; @@ -65,7 +75,8 @@ } void Symtab::SectionFileAddressesChanged() { - m_name_to_index.Clear(); + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); + name_to_index.Clear(); m_file_addr_to_index_computed = false; } @@ -252,9 +263,14 @@ if (!m_name_indexes_computed) { m_name_indexes_computed = true; LLDB_SCOPED_TIMER(); + + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); + auto &basename_to_index = GetFunctypeMap(lldb::eFunctionNameTypeBase); + auto &method_to_index = GetFunctypeMap(lldb::eFunctionNameTypeMethod); + auto &selector_to_index = GetFunctypeMap(lldb::eFunctionNameTypeSelector); // Create the name index vector to be able to quickly search by name const size_t num_symbols = m_symbols.size(); - m_name_to_index.Reserve(num_symbols); + name_to_index.Reserve(num_symbols); // The "const char *" in "class_contexts" and backlog::value_type::second // must come from a ConstString::GetCString() @@ -279,14 +295,14 @@ // stored in the mangled field. Mangled &mangled = symbol->GetMangled(); if (ConstString name = mangled.GetMangledName()) { - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. ConstString stripped = ConstString( m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); - m_name_to_index.Append(stripped, value); + name_to_index.Append(stripped, value); } const SymbolType type = symbol->GetType(); @@ -299,25 +315,25 @@ // Symbol name strings that didn't match a Mangled::ManglingScheme, are // stored in the demangled field. if (ConstString name = mangled.GetDemangledName()) { - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. name = ConstString( m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); - m_name_to_index.Append(name, value); + name_to_index.Append(name, value); } // If the demangled name turns out to be an ObjC name, and is a category // name, add the version without categories to the index too. ObjCLanguage::MethodName objc_method(name.GetStringRef(), true); if (objc_method.IsValid(true)) { - m_selector_to_index.Append(objc_method.GetSelector(), value); + selector_to_index.Append(objc_method.GetSelector(), value); if (ConstString objc_method_no_category = objc_method.GetFullNameWithoutCategory(true)) - m_name_to_index.Append(objc_method_no_category, value); + name_to_index.Append(objc_method_no_category, value); } } } @@ -326,14 +342,14 @@ RegisterBacklogEntry(record.first, record.second, class_contexts); } - m_name_to_index.Sort(); - m_name_to_index.SizeToFit(); - m_selector_to_index.Sort(); - m_selector_to_index.SizeToFit(); - m_basename_to_index.Sort(); - m_basename_to_index.SizeToFit(); - m_method_to_index.Sort(); - m_method_to_index.SizeToFit(); + name_to_index.Sort(); + name_to_index.SizeToFit(); + selector_to_index.Sort(); + selector_to_index.SizeToFit(); + basename_to_index.Sort(); + basename_to_index.SizeToFit(); + method_to_index.Sort(); + method_to_index.SizeToFit(); } } @@ -356,10 +372,12 @@ // Register functions with no context. if (decl_context.empty()) { // This has to be a basename - m_basename_to_index.Append(entry); + auto &basename_to_index = GetFunctypeMap(lldb::eFunctionNameTypeBase); + basename_to_index.Append(entry); // If there is no context (no namespaces or class scopes that come before // the function name) then this also could be a fullname. - m_name_to_index.Append(entry); + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); + name_to_index.Append(entry); return; } @@ -368,10 +386,11 @@ const char *decl_context_ccstr = ConstString(decl_context).GetCString(); auto it = class_contexts.find(decl_context_ccstr); + auto &method_to_index = GetFunctypeMap(lldb::eFunctionNameTypeMethod); // Register constructors and destructors. They are methods and create // declaration contexts. if (rmc.IsCtorOrDtor()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); if (it == class_contexts.end()) class_contexts.insert(it, decl_context_ccstr); return; @@ -379,7 +398,7 @@ // Register regular methods with a known declaration context. if (it != class_contexts.end()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); return; } @@ -391,14 +410,16 @@ void Symtab::RegisterBacklogEntry( const NameToIndexMap::Entry &entry, const char *decl_context, const std::set &class_contexts) { + auto &method_to_index = GetFunctypeMap(lldb::eFunctionNameTypeMethod); auto it = class_contexts.find(decl_context); if (it != class_contexts.end()) { - m_method_to_index.Append(entry); + method_to_index.Append(entry); } else { // If we got here, we have something that had a context (was inside // a namespace or class) yet we don't know the entry - m_method_to_index.Append(entry); - m_basename_to_index.Append(entry); + method_to_index.Append(entry); + auto &basename_to_index = GetFunctypeMap(lldb::eFunctionNameTypeBase); + basename_to_index.Append(entry); } } @@ -595,7 +616,8 @@ if (!m_name_indexes_computed) InitNameIndexes(); - return m_name_to_index.GetValues(symbol_name, indexes); + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); + return name_to_index.GetValues(symbol_name, indexes); } return 0; } @@ -612,9 +634,10 @@ if (!m_name_indexes_computed) InitNameIndexes(); + auto &name_to_index = GetFunctypeMap(lldb::eFunctionNameTypeNone); std::vector all_name_indexes; const size_t name_match_count = - m_name_to_index.GetValues(symbol_name, all_name_indexes); + name_to_index.GetValues(symbol_name, all_name_indexes); for (size_t i = 0; i < name_match_count; ++i) { if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type, symbol_visibility)) @@ -1035,45 +1058,18 @@ } } - if (name_type_mask & eFunctionNameTypeBase) { - // From mangled names we can't tell what is a basename and what is a method - // name, so we just treat them the same - if (!m_name_indexes_computed) - InitNameIndexes(); - - if (!m_basename_to_index.IsEmpty()) { - const UniqueCStringMap::Entry *match; - for (match = m_basename_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_basename_to_index.FindNextValueForName(match)) { - symbol_indexes.push_back(match->value); - } - } - } - - if (name_type_mask & eFunctionNameTypeMethod) { - if (!m_name_indexes_computed) - InitNameIndexes(); - - if (!m_method_to_index.IsEmpty()) { - const UniqueCStringMap::Entry *match; - for (match = m_method_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_method_to_index.FindNextValueForName(match)) { - symbol_indexes.push_back(match->value); - } - } - } + if (!m_name_indexes_computed) + InitNameIndexes(); - if (name_type_mask & eFunctionNameTypeSelector) { - if (!m_name_indexes_computed) - InitNameIndexes(); + for (lldb::FunctionNameType type : + {lldb::eFunctionNameTypeBase, lldb::eFunctionNameTypeMethod, + lldb::eFunctionNameTypeSelector}) { + if (name_type_mask & type) { + auto map = GetFunctypeMap(type); - if (!m_selector_to_index.IsEmpty()) { const UniqueCStringMap::Entry *match; - for (match = m_selector_to_index.FindFirstValueForName(name); - match != nullptr; - match = m_selector_to_index.FindNextValueForName(match)) { + for (match = map.FindFirstValueForName(name); match != nullptr; + match = map.FindNextValueForName(match)) { symbol_indexes.push_back(match->value); } }