Assume that mergeable input sections are smaller than 4 GiB.
By assuming that mergeable input sections are smaller than 4 GiB,
lld's memory usage when linking clang with debug info drops from
2.788 GiB to 2.019 GiB (measured by valgrind, and that does not include
memory space for mmap'ed files). I think that's a reasonable assumption
given such a large RAM savings, so this patch.
According to valgrind, gold needs 3.54 GiB of RAM to do the same thing.
NB: This patch does not introduce a limitation on the size of
output sections. You can still create sections larger than 4 GiB.
llvm-svn: 316280
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 51b2259..fc03749 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -214,15 +214,17 @@
// have to be as compact as possible, which is why we don't store the size (can
// be found by looking at the next one) and put the hash in a side table.
struct SectionPiece {
- SectionPiece(size_t Off, bool Live)
- : InputOff(Off), Live(Live || !Config->GcSections), OutputOff(-1) {}
+ SectionPiece(size_t Off, uint32_t Hash, bool Live)
+ : InputOff(Off), Hash(Hash), OutputOff(-1),
+ Live(Live || !Config->GcSections) {}
- size_t InputOff : 8 * sizeof(ssize_t) - 1;
- size_t Live : 1;
- ssize_t OutputOff;
+ uint32_t InputOff;
+ uint32_t Hash;
+ uint64_t OutputOff : 63;
+ uint64_t Live : 1;
};
-static_assert(sizeof(SectionPiece) == 2 * sizeof(size_t),
- "SectionPiece is too big");
+
+static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
// This corresponds to a SHF_MERGE section of an input file.
class MergeInputSection : public InputSectionBase {
@@ -252,14 +254,9 @@
LLVM_ATTRIBUTE_ALWAYS_INLINE
llvm::CachedHashStringRef getData(size_t I) const {
size_t Begin = Pieces[I].InputOff;
- size_t End;
- if (Pieces.size() - 1 == I)
- End = this->Data.size();
- else
- End = Pieces[I + 1].InputOff;
-
- StringRef S = {(const char *)(this->Data.data() + Begin), End - Begin};
- return {S, Hashes[I]};
+ size_t End =
+ (Pieces.size() - 1 == I) ? Data.size() : Pieces[I + 1].InputOff;
+ return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};
}
// Returns the SectionPiece at a given input section offset.
@@ -272,9 +269,7 @@
void splitStrings(ArrayRef<uint8_t> A, size_t Size);
void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
- std::vector<uint32_t> Hashes;
-
- mutable llvm::DenseMap<uint64_t, uint64_t> OffsetMap;
+ mutable llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
mutable llvm::once_flag InitOffsetMap;
llvm::DenseSet<uint64_t> LiveOffsets;