diff options
author | Rui Ueyama <ruiu@google.com> | 2017-09-25 02:29:51 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2017-09-25 02:29:51 +0000 |
commit | 253af14cc25332a395e231dd131e2bb2002d4d6d (patch) | |
tree | eb9a8bdf47ec7c015aeefe65b123b52edbc26366 /ELF | |
parent | 4a8e0b7cc47add188be306ffecabb94d1f0be267 (diff) |
Do not use StringTableBuilder to build symbol table for .gdb_index.
Previously, we had two levels of hash table lookup. The first hash
lookup uses CachedHashStringRefs as keys and returns offsets in string
table. Then, we did the second hash table lookup to obtain GdbSymbol
pointers. But we can directly map strings to GDbSymbols.
One test file is updated in this patch because we no longer have a '\0'
byte at the start of the string pool, which was automatically inserted
by StringTableBuilder.
This patch speeds up Clang debug build (with -gdb-index) link time by
0.3 seconds.
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@314092 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'ELF')
-rw-r--r-- | ELF/SyntheticSections.cpp | 31 | ||||
-rw-r--r-- | ELF/SyntheticSections.h | 9 |
2 files changed, 23 insertions, 17 deletions
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index 8d4e09e8b..b006c0bcb 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1787,19 +1787,22 @@ void GdbIndexSection::fixCuIndex() { std::vector<std::set<uint32_t>> GdbIndexSection::createCuVectors() { std::vector<std::set<uint32_t>> Ret; uint32_t Idx = 0; + uint32_t Off = 0; for (GdbIndexChunk &Chunk : Chunks) { for (GdbIndexChunk::NameTypeEntry &Ent : Chunk.NamesAndTypes) { - size_t Offset = StringPool.add(Ent.Name); - GdbSymbol *&Sym = SymbolMap[Offset]; + GdbSymbol *&Sym = Symbols[Ent.Name]; if (!Sym) { - Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Offset, Ret.size()}); + Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Off, Ret.size()}); + Off += Ent.Name.size() + 1; Ret.resize(Ret.size() + 1); } Ret[Sym->CuVectorIndex].insert((Ent.Type << 24) | Idx); } Idx += Chunk.CompilationUnits.size(); } + + StringPoolSize = Off; return Ret; } @@ -1835,12 +1838,14 @@ static size_t getAddressAreaSize(ArrayRef<GdbIndexChunk> Arr) { } std::vector<GdbSymbol *> GdbIndexSection::createGdbSymtab() { - uint32_t Size = - std::max<uint32_t>(1024, NextPowerOf2(SymbolMap.size() * 4 / 3)); + uint32_t Size = NextPowerOf2(Symbols.size() * 4 / 3); + if (Size < 1024) + Size = 1024; + uint32_t Mask = Size - 1; std::vector<GdbSymbol *> Ret(Size); - for (auto &KV : SymbolMap) { + for (auto &KV : Symbols) { GdbSymbol *Sym = KV.second; uint32_t I = Sym->NameHash & Mask; uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1; @@ -1853,8 +1858,7 @@ std::vector<GdbSymbol *> GdbIndexSection::createGdbSymtab() { } GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&C) - : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), - StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(C)) { + : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), Chunks(std::move(C)) { fixCuIndex(); CuVectors = createCuVectors(); GdbSymtab = createGdbSymtab(); @@ -1871,11 +1875,10 @@ GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&C) Off += (CuVec.size() + 1) * 4; } StringPoolOffset = ConstantPoolOffset + Off; - StringPool.finalizeInOrder(); } size_t GdbIndexSection::getSize() const { - return StringPoolOffset + StringPool.getSize(); + return StringPoolOffset + StringPoolSize; } void GdbIndexSection::writeTo(uint8_t *Buf) { @@ -1929,7 +1932,13 @@ void GdbIndexSection::writeTo(uint8_t *Buf) { } // Write the string pool. - StringPool.write(Buf); + for (auto &KV : Symbols) { + CachedHashStringRef S = KV.first; + GdbSymbol *Sym = KV.second; + size_t Off = Sym->NameOffset; + memcpy(Buf + Off, S.val().data(), S.size()); + Buf[Off + S.size() + 1] = '\0'; + } } bool GdbIndexSection::empty() const { return !Out::DebugInfo; } diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h index 200ae95a8..019949918 100644 --- a/ELF/SyntheticSections.h +++ b/ELF/SyntheticSections.h @@ -542,15 +542,11 @@ private: // A symbol table for this .gdb_index section. std::vector<GdbSymbol *> GdbSymtab; - // Symbol table entries are uniquified by their offsets, so - // we need a map from offsets to symbols. - llvm::DenseMap<size_t, GdbSymbol *> SymbolMap; - // CU vector is a part of constant pool area of section. std::vector<std::set<uint32_t>> CuVectors; - // String pool is also a part of constant pool, it follows CU vectors. - llvm::StringTableBuilder StringPool; + // Symbol table contents. + llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols; // Each chunk contains information gathered from a debug sections of single // object and used to build different areas of gdb index. @@ -561,6 +557,7 @@ private: uint32_t SymtabOffset; uint32_t ConstantPoolOffset; uint32_t StringPoolOffset; + uint32_t StringPoolSize; std::vector<size_t> CuVectorOffsets; }; |