diff --git a/lldb/include/lldb/Core/ConstString.h b/lldb/include/lldb/Core/ConstString.h index 9d95b96945be..8409c1348c82 100644 --- a/lldb/include/lldb/Core/ConstString.h +++ b/lldb/include/lldb/Core/ConstString.h @@ -290,7 +290,11 @@ public: /// @li \b false if the contained string is not empty. //------------------------------------------------------------------ bool - IsEmpty () const; + IsEmpty () const + { + return m_string == NULL || m_string[0] == '\0'; + } + //------------------------------------------------------------------ /// Set the C string value. diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 7cf4108628bc..12db609d48d3 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -2295,6 +2295,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, diff --git a/lldb/source/Core/ConstString.cpp b/lldb/source/Core/ConstString.cpp index 1caf843a3d3c..bb4745e466ac 100644 --- a/lldb/source/Core/ConstString.cpp +++ b/lldb/source/Core/ConstString.cpp @@ -390,15 +390,6 @@ ConstString::DumpDebug(Stream *s) const s->Printf("%*p: ConstString, string = %s%s%s, length = %zu", (int)sizeof(void*) * 2, this, parens, cstr, parens, cstr_len); } -//---------------------------------------------------------------------- -// Returns true if the contained string is empty. -//---------------------------------------------------------------------- -bool -ConstString::IsEmpty() const -{ - return m_string == NULL || m_string[0] == '\0'; -} - //---------------------------------------------------------------------- // Set the string value in the object by uniquing the "cstr" string // value in our global string pool. diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp index 5b48c5a2c0c2..c3657952c167 100644 --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -9,6 +9,8 @@ #include +#include "llvm/ADT/DenseMap.h" + #include "lldb/Core/ConstString.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Stream.h" @@ -142,18 +144,47 @@ Mangled::GetDemangledName () const const char * mangled = m_mangled.AsCString(); if (mangled[0]) { - char *demangled_name = abi::__cxa_demangle (mangled, NULL, NULL, NULL); + // Since demangling can be a costly, and since all names that go + // into a ConstString (like our m_mangled and m_demangled members) + // end up being unique "const char *" values, we can use a DenseMap + // to speed up our lookup. We do this because often our symbol table + // and our debug information both have the mangled names which they + // would each need to demangle. Also, with GCC we end up with the one + // definition rule where a lot of STL code produces symbols that are + // in multiple compile units and the mangled names end up being in + // the same binary multiple times. The performance win isn't huge, + // but we showed a 20% improvement on darwin. + typedef llvm::DenseMap MangledToDemangledMap; + static MangledToDemangledMap g_mangled_to_demangled; - if (demangled_name) + // Check our mangled string pointer to demangled string pointer map first + MangledToDemangledMap::const_iterator pos = g_mangled_to_demangled.find (mangled); + if (pos != g_mangled_to_demangled.end()) { - m_demangled.SetCString (demangled_name); - free (demangled_name); + // We have already demangled this string, we can just use our saved result! + m_demangled.SetCString(pos->second); } else { - // Set the demangled string to the empty string to indicate we - // tried to parse it once and failed. - m_demangled.SetCString(""); + // We didn't already mangle this name, demangle it and if all goes well + // add it to our map. + char *demangled_name = abi::__cxa_demangle (mangled, NULL, NULL, NULL); + + if (demangled_name) + { + m_demangled.SetCString (demangled_name); + // Now that the name has been uniqued, add the uniqued C string + // pointer from m_mangled as the key to the uniqued C string + // pointer in m_demangled. + g_mangled_to_demangled.insert (std::make_pair (mangled, m_demangled.GetCString())); + free (demangled_name); + } + else + { + // Set the demangled string to the empty string to indicate we + // tried to parse it once and failed. + m_demangled.SetCString(""); + } } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index e5a55ca2bc76..8a21e1ec5551 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -9,6 +9,7 @@ #include "DWARFCompileUnit.h" +#include "lldb/Core/Mangled.h" #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" @@ -591,7 +592,7 @@ DWARFCompileUnit::Index DWARFDebugInfoEntry::Attributes attributes; const char *name = NULL; - const char *mangled = NULL; + Mangled mangled; bool is_variable = false; bool is_declaration = false; bool is_artificial = false; @@ -629,7 +630,7 @@ DWARFCompileUnit::Index case DW_AT_MIPS_linkage_name: if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - mangled = form_value.AsCString(debug_str); + mangled.GetMangledName().SetCString(form_value.AsCString(debug_str)); break; case DW_AT_low_pc: @@ -761,8 +762,10 @@ DWARFCompileUnit::Index else base_name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset()); } - if (mangled) - full_name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + if (mangled.GetMangledName()) + full_name_to_function_die.Append(mangled.GetMangledName().AsCString(), die.GetOffset()); + if (mangled.GetDemangledName()) + full_name_to_function_die.Append(mangled.GetDemangledName().AsCString(), die.GetOffset()); } break; @@ -771,8 +774,10 @@ DWARFCompileUnit::Index { if (name) base_name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset()); - if (mangled) - full_name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset()); + if (mangled.GetMangledName()) + full_name_to_function_die.Append(mangled.GetMangledName().AsCString(), die.GetOffset()); + if (mangled.GetDemangledName()) + full_name_to_function_die.Append(mangled.GetDemangledName().AsCString(), die.GetOffset()); } break;