Discard uncompressed buffer after creating .gdb_index contents.
authorRui Ueyama <ruiu@google.com>
Fri, 14 Sep 2018 22:57:39 +0000 (22:57 +0000)
committerRui Ueyama <ruiu@google.com>
Fri, 14 Sep 2018 22:57:39 +0000 (22:57 +0000)
Once we create .gdb_index contents, .zdebug_gnu_pub{names,types}
are useless, so there's no need to keep their uncompressed data
in memory.

I observed that for a test case in which lld creates a 3GB .gdb_index
section, the maximum resident set size reduced from 43GB to 29GB after
this patch.

Differential Revision: https://reviews.llvm.org/D52126

llvm-svn: 342297

lld/ELF/InputSection.h
lld/ELF/SyntheticSections.cpp

index c68b7d1..06644c7 100644 (file)
@@ -205,7 +205,6 @@ public:
     return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
   }
 
-private:
   // A pointer that owns decompressed data if a section is compressed by zlib.
   // Since the feature is not used often, this is usually a nullptr.
   std::unique_ptr<char[]> DecompressBuf;
index b547956..96eb384 100644 (file)
@@ -2495,13 +2495,6 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) {
 template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
   std::vector<InputSection *> Sections = getDebugInfoSections();
 
-  // .debug_gnu_pub{names,types} are useless in executables.
-  // They are present in input object files solely for creating
-  // a .gdb_index. So we can remove them from the output.
-  for (InputSectionBase *S : InputSections)
-    if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
-      S->Live = false;
-
   std::vector<GdbChunk> Chunks(Sections.size());
   std::vector<std::vector<NameTypeEntry>> NameTypes(Sections.size());
 
@@ -2515,6 +2508,16 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
     NameTypes[I] = readPubNamesAndTypes(Dwarf, I);
   });
 
+  // .debug_gnu_pub{names,types} are useless in executables.
+  // They are present in input object files solely for creating
+  // a .gdb_index. So we can remove them from the output.
+  for (InputSectionBase *S : InputSections) {
+    if (S->Name != ".debug_gnu_pubnames" && S->Name != ".debug_gnu_pubtypes")
+      continue;
+    S->Live = false;
+    S->DecompressBuf.reset();
+  }
+
   auto *Ret = make<GdbIndexSection>();
   Ret->Chunks = std::move(Chunks);
   Ret->Symbols = createSymbols(NameTypes);