summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Object/ArchiveWriter.cpp26
-rw-r--r--llvm/test/Object/archive-format.test5
2 files changed, 24 insertions, 7 deletions
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index 767205390e0..4de5871c7ec 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -250,6 +250,7 @@ static void addToStringTable(raw_ostream &Out, StringRef ArcName,
static void printMemberHeader(raw_ostream &Out, uint64_t Pos,
raw_ostream &StringTable,
+ StringMap<uint64_t> &MemberNames,
object::Archive::Kind Kind, bool Thin,
StringRef ArcName, const NewArchiveMember &M,
sys::TimePoint<std::chrono::seconds> ModTime,
@@ -262,8 +263,20 @@ static void printMemberHeader(raw_ostream &Out, uint64_t Pos,
return printGNUSmallMemberHeader(Out, M.MemberName, ModTime, M.UID, M.GID,
M.Perms, Size);
Out << '/';
- uint64_t NamePos = StringTable.tell();
- addToStringTable(StringTable, ArcName, M, Thin);
+ uint64_t NamePos;
+ if (Thin) {
+ NamePos = StringTable.tell();
+ addToStringTable(StringTable, ArcName, M, Thin);
+ } else {
+ StringMap<uint64_t>::const_iterator it = MemberNames.find(M.MemberName);
+ if (it == MemberNames.end()) {
+ NamePos = StringTable.tell();
+ addToStringTable(StringTable, ArcName, M, Thin);
+ MemberNames[M.MemberName] = NamePos;
+ } else {
+ NamePos = it->second;
+ }
+ }
printWithSpacePadding(Out, NamePos, 15);
printRestOfMemberHeader(Out, ModTime, M.UID, M.GID, M.Perms, Size);
}
@@ -433,6 +446,11 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
std::vector<MemberData> Ret;
bool HasObject = false;
+ // Deduplicate long member names in the string table and reuse earlier name
+ // offsets. This especially saves space for COFF Import libraries where all
+ // members have the same name.
+ StringMap<uint64_t> MemberNames;
+
// UniqueTimestamps is a special case to improve debugging on Darwin:
//
// The Darwin linker does not link debug info into the final
@@ -505,8 +523,8 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
ModTime = sys::toTimePoint(FilenameCount[M.MemberName]++);
else
ModTime = M.ModTime;
- printMemberHeader(Out, Pos, StringTable, Kind, Thin, ArcName, M, ModTime,
- Buf.getBufferSize() + MemberPadding);
+ printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, ArcName,
+ M, ModTime, Buf.getBufferSize() + MemberPadding);
Out.flush();
Expected<std::vector<unsigned>> Symbols =
diff --git a/llvm/test/Object/archive-format.test b/llvm/test/Object/archive-format.test
index b1ae411161b..b555bf88fac 100644
--- a/llvm/test/Object/archive-format.test
+++ b/llvm/test/Object/archive-format.test
@@ -15,8 +15,7 @@ RUN: llvm-ar --format=gnu rc %t.a 0123456789abcde 0123456789abcdef foo/012345678
RUN: cat %t.a | FileCheck -strict-whitespace %s
CHECK: !<arch>
-CHECK-NEXT: // 36 `
-CHECK-NEXT: 0123456789abcdef/
+CHECK-NEXT: // 18 `
CHECK-NEXT: 0123456789abcdef/
CHECK-NEXT: 0123456789abcde/0 0 0 644 4 `
CHECK-NEXT: bar.
@@ -24,7 +23,7 @@ CHECK-SAME: /0 0 0 0 644 4 `
CHECK-NEXT: zed.
CHECK-SAME: 0123456789abcde/0 0 0 644 4 `
CHECK-NEXT: bar2
-CHECK-SAME: /18 0 0 0 644 4 `
+CHECK-SAME: /0 0 0 0 644 4 `
CHECK-NEXT: zed2
RUN: rm -f %t.a
OpenPOWER on IntegriCloud