From d43c001a74f719a6089d0e5b616af3bcf9c29b48 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 22 Oct 2015 18:32:06 +0000 Subject: [PATCH] Avoid storing a second copy of each string in StringTableBuilder. This was only use in the extremely uncommon case of @@@ symbols on ELF. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251039 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/StringTableBuilder.h | 16 ++++----------- lib/MC/ELFObjectWriter.cpp | 11 ++++++++--- lib/MC/StringTableBuilder.cpp | 29 +++++++++++++++++++--------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h index f38247702eb..414c3adc5ea 100644 --- a/include/llvm/MC/StringTableBuilder.h +++ b/include/llvm/MC/StringTableBuilder.h @@ -11,7 +11,7 @@ #define LLVM_MC_STRINGTABLEBUILDER_H #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/DenseMap.h" #include namespace llvm { @@ -19,15 +19,12 @@ namespace llvm { /// \brief Utility for building string tables with deduplicated suffixes. class StringTableBuilder { SmallString<256> StringTable; - StringMap StringIndexMap; + DenseMap StringIndexMap; public: /// \brief Add a string to the builder. Returns a StringRef to the internal /// copy of s. Can only be used before the table is finalized. - StringRef add(StringRef s) { - assert(!isFinalized()); - return StringIndexMap.insert(std::make_pair(s, 0)).first->first(); - } + void add(StringRef s); enum Kind { ELF, @@ -48,12 +45,7 @@ public: /// \brief Get the offest of a string in the string table. Can only be used /// after the table is finalized. - size_t getOffset(StringRef s) const { - assert(isFinalized()); - auto I = StringIndexMap.find(s); - assert(I != StringIndexMap.end() && "String is not in table!"); - return I->second; - } + size_t getOffset(StringRef s) const; void clear(); diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index f1acc1d75fb..5fdfcf9ef2d 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/StringSaver.h" #include using namespace llvm; @@ -106,6 +107,8 @@ class ELFObjectWriter : public MCObjectWriter { /// @name Symbol Table Data /// @{ + BumpPtrAllocator Alloc; + StringSaver VersionSymSaver{Alloc}; StringTableBuilder StrTabBuilder; /// @} @@ -847,13 +850,15 @@ void ELFObjectWriter::computeSymbolTable( Buf += Name.substr(0, Pos); unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; Buf += Name.substr(Pos + Skip); - Name = Buf; + Name = VersionSymSaver.save(Buf.c_str()); } } // Sections have their own string table - if (Symbol.getType() != ELF::STT_SECTION) - MSD.Name = StrTabBuilder.add(Name); + if (Symbol.getType() != ELF::STT_SECTION) { + MSD.Name = Name; + StrTabBuilder.add(Name); + } if (Local) LocalSymbolData.push_back(MSD); diff --git a/lib/MC/StringTableBuilder.cpp b/lib/MC/StringTableBuilder.cpp index 0f15d3035ea..cc4fbf66385 100644 --- a/lib/MC/StringTableBuilder.cpp +++ b/lib/MC/StringTableBuilder.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/StringTableBuilder.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Endian.h" @@ -17,10 +16,10 @@ using namespace llvm; -static int compareBySuffix(StringMapEntry *const *AP, - StringMapEntry *const *BP) { - StringRef a = (*AP)->first(); - StringRef b = (*BP)->first(); +static int compareBySuffix(std::pair *const *AP, + std::pair *const *BP) { + StringRef a = (*AP)->first; + StringRef b = (*BP)->first; size_t sizeA = a.size(); size_t sizeB = b.size(); size_t len = std::min(sizeA, sizeB); @@ -34,9 +33,9 @@ static int compareBySuffix(StringMapEntry *const *AP, } void StringTableBuilder::finalize(Kind kind) { - std::vector *> Strings; + std::vector *> Strings; Strings.reserve(StringIndexMap.size()); - for (StringMapEntry &P : StringIndexMap) + for (std::pair &P : StringIndexMap) Strings.push_back(&P); array_pod_sort(Strings.begin(), Strings.end(), compareBySuffix); @@ -54,8 +53,8 @@ void StringTableBuilder::finalize(Kind kind) { } StringRef Previous; - for (StringMapEntry *P : Strings) { - StringRef s = P->first(); + for (std::pair *P : Strings) { + StringRef s = P->first; if (kind == WinCOFF) assert(s.size() > COFF::NameSize && "Short string in COFF string table!"); @@ -92,3 +91,15 @@ void StringTableBuilder::clear() { StringTable.clear(); StringIndexMap.clear(); } + +size_t StringTableBuilder::getOffset(StringRef s) const { + assert(isFinalized()); + auto I = StringIndexMap.find(s); + assert(I != StringIndexMap.end() && "String is not in table!"); + return I->second; +} + +void StringTableBuilder::add(StringRef s) { + assert(!isFinalized()); + StringIndexMap.insert(std::make_pair(s, 0)); +} -- 2.34.1