Avoid storing a second copy of each string in StringTableBuilder.

This was only use in the extremely uncommon case of @@@ symbols on ELF.

llvm-svn: 251039
This commit is contained in:
Rafael Espindola 2015-10-22 18:32:06 +00:00
parent d276de6db1
commit fc063e8fec
3 changed files with 32 additions and 24 deletions

View File

@ -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 <cassert>
namespace llvm {
@ -19,15 +19,12 @@ namespace llvm {
/// \brief Utility for building string tables with deduplicated suffixes.
class StringTableBuilder {
SmallString<256> StringTable;
StringMap<size_t> StringIndexMap;
DenseMap<StringRef, size_t> 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();

View File

@ -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 <vector>
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);

View File

@ -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<size_t> *const *AP,
StringMapEntry<size_t> *const *BP) {
StringRef a = (*AP)->first();
StringRef b = (*BP)->first();
static int compareBySuffix(std::pair<StringRef, size_t> *const *AP,
std::pair<StringRef, size_t> *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<size_t> *const *AP,
}
void StringTableBuilder::finalize(Kind kind) {
std::vector<StringMapEntry<size_t> *> Strings;
std::vector<std::pair<StringRef, size_t> *> Strings;
Strings.reserve(StringIndexMap.size());
for (StringMapEntry<size_t> &P : StringIndexMap)
for (std::pair<StringRef, size_t> &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<size_t> *P : Strings) {
StringRef s = P->first();
for (std::pair<StringRef, size_t> *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));
}