Hash symbol names only once per global SymbolBody.

The DenseMap doesn't store hash results. This means that when it is
resized it has to recompute them.

This patch is a small hack that wraps the StringRef in a struct that
remembers the hash value. That way we can be sure it is only hashed
once.

llvm-svn: 266357
This commit is contained in:
Rafael Espindola 2016-04-14 19:17:16 +00:00
parent 000c5af3e6
commit c9157d35d9
2 changed files with 34 additions and 3 deletions

View File

@ -113,7 +113,7 @@ template <class ELFT> void elf::markLive(SymbolTable<ELFT> *Symtab) {
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
if (Config->Shared || Config->ExportDynamic) {
for (const std::pair<StringRef, Symbol *> &P : Symtab->getSymbols()) {
for (const std::pair<SymName, Symbol *> &P : Symtab->getSymbols()) {
SymbolBody *B = P.second->Body;
if (B->getVisibility() == STV_DEFAULT)
MarkSymbol(B);

View File

@ -20,6 +20,37 @@ class Lazy;
template <class ELFT> class OutputSectionBase;
struct Symbol;
struct SymName {
SymName(StringRef Name) : Name(Name) {
Hash = llvm::DenseMapInfo<StringRef>::getHashValue(Name);
}
SymName(StringRef Name, unsigned Hash) : Name(Name), Hash(Hash) {}
StringRef Name;
unsigned Hash;
};
}
}
namespace llvm {
template <> struct DenseMapInfo<lld::elf::SymName> {
static lld::elf::SymName getEmptyKey() {
StringRef N = DenseMapInfo<StringRef>::getEmptyKey();
return {N, 0};
}
static lld::elf::SymName getTombstoneKey() {
StringRef N = DenseMapInfo<StringRef>::getTombstoneKey();
return {N, 0};
}
static unsigned getHashValue(lld::elf::SymName Name) { return Name.Hash; }
static bool isEqual(lld::elf::SymName A, lld::elf::SymName B) {
return A.Name == B.Name;
}
};
}
namespace lld {
namespace elf {
// SymbolTable is a bucket of all known symbols, including defined,
// undefined, or lazy symbols (the last one is symbols in archive
// files whose archive members are not yet loaded).
@ -38,7 +69,7 @@ public:
void addFile(std::unique_ptr<InputFile> File);
void addCombinedLtoObject();
const llvm::MapVector<StringRef, Symbol *> &getSymbols() const {
const llvm::MapVector<SymName, Symbol *> &getSymbols() const {
return Symtab;
}
@ -79,7 +110,7 @@ private:
// a bit inefficient.
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
// once symbol resolution is finished.
llvm::MapVector<StringRef, Symbol *> Symtab;
llvm::MapVector<SymName, Symbol *> Symtab;
llvm::BumpPtrAllocator Alloc;
// Comdat groups define "link once" sections. If two comdat groups have the