[COFF] Free some memory used for chunks
authorReid Kleckner <rnk@google.com>
Tue, 2 Jun 2020 01:46:51 +0000 (18:46 -0700)
committerReid Kleckner <rnk@google.com>
Tue, 2 Jun 2020 01:51:47 +0000 (18:51 -0700)
First, do not reserve numSections in the Chunks array. In cases where
there are many non-prevailing sections, this will overallocate memory
which will not be used.

Second, free the memory for sparseChunks after initializeSymbols. After
that, it is never used.

This saves 50MB of 627MB for my use case without affecting performance.

lld/COFF/InputFiles.cpp
lld/COFF/InputFiles.h

index 3d4a27b..0adc2b9 100644 (file)
@@ -215,7 +215,6 @@ static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1);
 
 void ObjFile::initializeChunks() {
   uint32_t numSections = coffObj->getNumberOfSections();
-  chunks.reserve(numSections);
   sparseChunks.resize(numSections + 1);
   for (uint32_t i = 1; i < numSections + 1; ++i) {
     const coff_section *sec = getSection(i);
@@ -458,6 +457,9 @@ void ObjFile::initializeSymbols() {
     uint32_t idx = kv.second;
     checkAndSetWeakAlias(symtab, this, sym, symbols[idx]);
   }
+
+  // Free the memory used by sparseChunks now that symbol loading is finished.
+  decltype(sparseChunks)().swap(sparseChunks);
 }
 
 Symbol *ObjFile::createUndefined(COFFSymbolRef sym) {
index a8ddf29..50323f5 100644 (file)
@@ -285,19 +285,19 @@ private:
   std::vector<SectionChunk *> guardFidChunks;
   std::vector<SectionChunk *> guardLJmpChunks;
 
-  // This vector contains the same chunks as Chunks, but they are
-  // indexed such that you can get a SectionChunk by section index.
-  // Nonexistent section indices are filled with null pointers.
-  // (Because section number is 1-based, the first slot is always a
-  // null pointer.)
-  std::vector<SectionChunk *> sparseChunks;
-
   // This vector contains a list of all symbols defined or referenced by this
   // file. They are indexed such that you can get a Symbol by symbol
   // index. Nonexistent indices (which are occupied by auxiliary
   // symbols in the real symbol table) are filled with null pointers.
   std::vector<Symbol *> symbols;
 
+  // This vector contains the same chunks as Chunks, but they are
+  // indexed such that you can get a SectionChunk by section index.
+  // Nonexistent section indices are filled with null pointers.
+  // (Because section number is 1-based, the first slot is always a
+  // null pointer.) This vector is only valid during initialization.
+  std::vector<SectionChunk *> sparseChunks;
+
   DWARFCache *dwarf = nullptr;
 };