Index: lldb/include/lldb/Utility/ConstString.h =================================================================== --- lldb/include/lldb/Utility/ConstString.h +++ lldb/include/lldb/Utility/ConstString.h @@ -386,6 +386,15 @@ /// might not be NULL terminated if the string takes the entire buffer. void SetTrimmedCStringWithLength(const char *cstr, size_t fixed_cstr_len); + /// Returns a hash value of the string. + uint32_t GetHash() const; + + /// Set with hash value of the string + /// + /// Creates as if by calling SetString, but \a hash must contain the hash + /// of the string from a previous call to GetHash. + void SetStringWithHash(const llvm::StringRef &s, uint32_t hash); + /// Get the memory cost of this object. /// /// Return the size in bytes that this object takes in memory. This returns Index: lldb/source/Core/Mangled.cpp =================================================================== --- lldb/source/Core/Mangled.cpp +++ lldb/source/Core/Mangled.cpp @@ -430,18 +430,30 @@ case Empty: return true; - case DemangledOnly: - m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr))); + case DemangledOnly: { + uint32_t str_offset = data.GetU32(offset_ptr); + uint32_t hash = data.GetU32(offset_ptr); + m_demangled.SetStringWithHash(strtab.Get(str_offset), hash); return true; + } - case MangledOnly: - m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr))); + case MangledOnly: { + uint32_t str_offset = data.GetU32(offset_ptr); + uint32_t hash = data.GetU32(offset_ptr); + m_mangled.SetStringWithHash(strtab.Get(str_offset), hash); return true; + } - case MangledAndDemangled: - m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr))); - m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr))); + case MangledAndDemangled: { + uint32_t str_offset = data.GetU32(offset_ptr); + uint32_t hash = data.GetU32(offset_ptr); + m_mangled.SetStringWithHash(strtab.Get(str_offset), hash); + str_offset = data.GetU32(offset_ptr); + hash = data.GetU32(offset_ptr); + m_demangled.SetStringWithHash(strtab.Get(str_offset), hash); return true; + } + } return false; } @@ -492,13 +504,17 @@ break; case DemangledOnly: file.AppendU32(strtab.Add(m_demangled)); + file.AppendU32(m_demangled.GetHash()); break; case MangledOnly: file.AppendU32(strtab.Add(m_mangled)); + file.AppendU32(m_mangled.GetHash()); break; case MangledAndDemangled: file.AppendU32(strtab.Add(m_mangled)); + file.AppendU32(m_mangled.GetHash()); file.AppendU32(strtab.Add(m_demangled)); + file.AppendU32(m_demangled.GetHash()); break; } } Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -505,7 +505,8 @@ kDataIDEnd = 255u, }; -constexpr uint32_t CURRENT_CACHE_VERSION = 1; +constexpr uint32_t CURRENT_CACHE_VERSION = 2; +constexpr llvm::StringLiteral kCheckHashString("a test string for hash check"); bool ManualDWARFIndex::IndexSet::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr) { @@ -520,6 +521,11 @@ const uint32_t version = data.GetU32(offset_ptr); if (version != CURRENT_CACHE_VERSION) return false; + // Check that implementation of ConstString::GetHash() has not changed. + uint32_t checkHash = data.GetU32(offset_ptr); + ConstString checkString(kCheckHashString); + if (checkHash != checkString.GetHash()) + return false; bool done = false; while (!done) { @@ -582,6 +588,8 @@ index_encoder.AppendData(kIdentifierManualDWARFIndex); // Encode the data version. index_encoder.AppendU32(CURRENT_CACHE_VERSION); + // Encode check hash value. + index_encoder.AppendU32(ConstString(kCheckHashString).GetHash()); if (!function_basenames.IsEmpty()) { index_encoder.AppendU8(kDataIDFunctionBasenames); Index: lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -102,12 +102,15 @@ const uint32_t count = data.GetU32(offset_ptr); for (uint32_t i = 0; i < count; ++i) { llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr))); + uint32_t hash = data.GetU32(offset_ptr); // No empty strings allowed in the name to DIE maps. if (str.empty()) return false; - if (llvm::Optional die_ref = DIERef::Decode(data, offset_ptr)) - m_map.Append(ConstString(str), die_ref.getValue()); - else + if (llvm::Optional die_ref = DIERef::Decode(data, offset_ptr)) { + ConstString cstr; + cstr.SetStringWithHash(str, hash); + m_map.Append(cstr, die_ref.getValue()); + } else return false; } return true; @@ -120,6 +123,7 @@ // Make sure there are no empty strings. assert((bool)entry.cstring); encoder.AppendU32(strtab.Add(entry.cstring)); + encoder.AppendU32(entry.cstring.GetHash()); entry.value.Encode(encoder); } } Index: lldb/source/Symbol/Symtab.cpp =================================================================== --- lldb/source/Symbol/Symtab.cpp +++ lldb/source/Symbol/Symtab.cpp @@ -1207,17 +1207,21 @@ for (uint32_t i=0; i