[lld] ab00f78 - [ELF] InputFile: change symbols to unique_ptr<Symbol *[]>

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 21 01:02:10 PST 2022


Author: Fangrui Song
Date: 2022-11-21T09:02:04Z
New Revision: ab00f78dcc5c7eb4da852d03e20e8a291f06e085

URL: https://github.com/llvm/llvm-project/commit/ab00f78dcc5c7eb4da852d03e20e8a291f06e085
DIFF: https://github.com/llvm/llvm-project/commit/ab00f78dcc5c7eb4da852d03e20e8a291f06e085.diff

LOG: [ELF] InputFile: change symbols to unique_ptr<Symbol *[]>

We may try a custom allocator in the future.

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index f751d43ccbde..0b932dfab409 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1036,7 +1036,10 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
 template <class ELFT>
 void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {
   ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
-  symbols.resize(eSyms.size());
+  if (numSymbols == 0) {
+    numSymbols = eSyms.size();
+    symbols = std::make_unique<Symbol *[]>(numSymbols);
+  }
 
   // Some entries have been filled by LazyObjFile.
   for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
@@ -1675,7 +1678,10 @@ void BitcodeFile::parse() {
             .second);
   }
 
-  symbols.resize(obj->symbols().size());
+  if (numSymbols == 0) {
+    numSymbols = obj->symbols().size();
+    symbols = std::make_unique<Symbol *[]>(numSymbols);
+  }
   // Process defined symbols first. See the comment in
   // ObjFile<ELFT>::initializeSymbols.
   for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
@@ -1690,7 +1696,8 @@ void BitcodeFile::parse() {
 }
 
 void BitcodeFile::parseLazy() {
-  symbols.resize(obj->symbols().size());
+  numSymbols = obj->symbols().size();
+  symbols = std::make_unique<Symbol *[]>(numSymbols);
   for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
     if (!irSym.isUndefined()) {
       auto *sym = symtab.insert(saver().save(irSym.getName()));
@@ -1766,7 +1773,8 @@ ELFFileBase *elf::createObjFile(MemoryBufferRef mb, StringRef archiveName,
 
 template <class ELFT> void ObjFile<ELFT>::parseLazy() {
   const ArrayRef<typename ELFT::Sym> eSyms = this->getELFSyms<ELFT>();
-  symbols.resize(eSyms.size());
+  numSymbols = eSyms.size();
+  symbols = std::make_unique<Symbol *[]>(numSymbols);
   for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
     if (eSyms[i].st_shndx != SHN_UNDEF)
       symbols[i] = symtab.insert(CHECK(eSyms[i].getName(stringTable), this));
@@ -1776,7 +1784,7 @@ template <class ELFT> void ObjFile<ELFT>::parseLazy() {
   // resolve() may trigger this->extract() if an existing symbol is an undefined
   // symbol. If that happens, this function has served its purpose, and we can
   // exit from the loop early.
-  for (Symbol *sym : makeArrayRef(symbols).slice(firstGlobal))
+  for (Symbol *sym : getGlobalSymbols())
     if (sym) {
       sym->resolve(LazyObject{*this});
       if (!lazy)

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index e318d9bf5de9..c2b0f9d91579 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -51,7 +51,8 @@ void parseFile(InputFile *file);
 // The root class of input files.
 class InputFile {
 protected:
-  SmallVector<Symbol *, 0> symbols;
+  std::unique_ptr<Symbol *[]> symbols;
+  uint32_t numSymbols = 0;
   SmallVector<InputSectionBase *, 0> sections;
 
 public:
@@ -85,7 +86,7 @@ class InputFile {
   ArrayRef<Symbol *> getSymbols() const {
     assert(fileKind == BinaryKind || fileKind == ObjKind ||
            fileKind == BitcodeKind);
-    return symbols;
+    return {symbols.get(), numSymbols};
   }
 
   // Get filename to use for linker script processing.
@@ -171,16 +172,17 @@ class ELFFileBase : public InputFile {
   StringRef getStringTable() const { return stringTable; }
 
   ArrayRef<Symbol *> getLocalSymbols() {
-    if (symbols.empty())
+    if (numSymbols == 0)
       return {};
-    return llvm::makeArrayRef(symbols).slice(1, firstGlobal - 1);
+    return llvm::makeArrayRef(symbols.get() + 1, firstGlobal - 1);
   }
   ArrayRef<Symbol *> getGlobalSymbols() {
-    return llvm::makeArrayRef(symbols).slice(firstGlobal);
+    return llvm::makeArrayRef(symbols.get() + firstGlobal,
+                              numSymbols - firstGlobal);
   }
   MutableArrayRef<Symbol *> getMutableGlobalSymbols() {
-    return llvm::makeMutableArrayRef(symbols.data(), symbols.size())
-        .slice(firstGlobal);
+    return llvm::makeMutableArrayRef(symbols.get() + firstGlobal,
+                                     numSymbols - firstGlobal);
   }
 
   template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {
@@ -234,7 +236,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
                                  const Elf_Shdr &sec);
 
   Symbol &getSymbol(uint32_t symbolIndex) const {
-    if (symbolIndex >= this->symbols.size())
+    if (symbolIndex >= numSymbols)
       fatal(toString(this) + ": invalid symbol index");
     return *this->symbols[symbolIndex];
   }


        


More information about the llvm-commits mailing list