summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/InputSection.cpp3
-rw-r--r--lld/ELF/InputSection.h9
-rw-r--r--lld/ELF/OutputSections.cpp6
-rw-r--r--lld/ELF/OutputSections.h2
4 files changed, 14 insertions, 6 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 1e9e96eb631..d709626722e 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -644,7 +644,8 @@ template <class ELFT> void MergeInputSection<ELFT>::finalizePieces() {
auto *OutSec = static_cast<MergeOutputSection<ELFT> *>(this->OutSec);
ArrayRef<uint8_t> D = this->getData(Piece);
StringRef S((const char *)D.data(), D.size());
- Piece.OutputOff = OutSec->getOffset(S);
+ CachedHashString V(S, Piece.Hash);
+ Piece.OutputOff = OutSec->getOffset(V);
}
OffsetMap[Piece.InputOff] = Piece.OutputOff;
}
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index b5ff603a87c..b3c7f689795 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -124,14 +124,19 @@ template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
// SectionPiece represents a piece of splittable section contents.
struct SectionPiece {
+ SectionPiece(size_t Off, ArrayRef<uint8_t> Data, uint32_t Hash, bool Live)
+ : InputOff(Off), Hash(Hash), Size(Data.size()),
+ Live(Live || !Config->GcSections) {}
SectionPiece(size_t Off, ArrayRef<uint8_t> Data, bool Live = false)
- : InputOff(Off), Size(Data.size()), Live(Live || !Config->GcSections) {}
+ : SectionPiece(Off, Data, hash_value(Data), Live) {}
size_t size() const { return Size; }
size_t InputOff;
size_t OutputOff = -1;
+ uint32_t Hash;
+
private:
// We use bitfields because SplitInputSection is accessed by
// std::upper_bound very often.
@@ -181,7 +186,7 @@ private:
struct EhSectionPiece : public SectionPiece {
EhSectionPiece(size_t Off, ArrayRef<uint8_t> Data, unsigned FirstRelocation)
- : SectionPiece(Off, Data), Data(Data.data()),
+ : SectionPiece(Off, Data, 0, false), Data(Data.data()),
FirstRelocation(FirstRelocation) {}
const uint8_t *Data;
ArrayRef<uint8_t> data() { return {Data, size()}; }
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 683c15c6060..c2d736d3b1f 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -1244,14 +1244,16 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
for (SectionPiece &Piece : Sec->Pieces) {
if (!Piece.Live)
continue;
- uintX_t OutputOffset = Builder.add(toStringRef(Sec->getData(Piece)));
+ StringRef Data = toStringRef(Sec->getData(Piece));
+ CachedHashString V(Data, Piece.Hash);
+ uintX_t OutputOffset = Builder.add(V);
if (!shouldTailMerge())
Piece.OutputOff = OutputOffset;
}
}
template <class ELFT>
-unsigned MergeOutputSection<ELFT>::getOffset(StringRef Val) {
+unsigned MergeOutputSection<ELFT>::getOffset(CachedHashString Val) {
return Builder.getOffset(Val);
}
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 5dd6c46c25b..a405934b0de 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -427,7 +427,7 @@ public:
uintX_t Alignment);
void addSection(InputSectionBase<ELFT> *S) override;
void writeTo(uint8_t *Buf) override;
- unsigned getOffset(StringRef Val);
+ unsigned getOffset(llvm::CachedHashString Val);
void finalize() override;
void finalizePieces() override;
bool shouldTailMerge() const;
OpenPOWER on IntegriCloud