[lld] 03909c4 - [ELF] Remove StringRefZ

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 19 20:09:51 PST 2022


Author: Fangrui Song
Date: 2022-01-19T20:09:41-08:00
New Revision: 03909c4400b585c1991e59359b4155d72a4f19ca

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

LOG: [ELF] Remove StringRefZ

StringRefZ does not improve performance. Non-local symbols always have eagerly
computed nameSize. Most local symbols's lengths will be updated in either:

* shouldKeepInSymtab
* SymbolTableBaseSection::addSymbol

Its benefit is offsetted by strlen in every call site (sums up to 5KiB code in a
release x86-64 build), so using StringRefZ may be slower.

In a -s link (uncommon) there is minor speedup, like ~0.3% for clang and chrome.

Reviewed By: alexander-shaposhnikov

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 64e64ff63b506..ca16a64e50836 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1067,7 +1067,7 @@ template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
       sourceFile = CHECK(eSym.getName(stringTable), this);
     if (LLVM_UNLIKELY(stringTable.size() <= eSym.st_name))
       fatal(toString(this) + ": invalid symbol name offset");
-    StringRefZ name = stringTable.data() + eSym.st_name;
+    StringRef name(stringTable.data() + eSym.st_name);
 
     symbols[i] = reinterpret_cast<Symbol *>(locals + i);
     if (eSym.st_shndx == SHN_UNDEF || sec == &InputSection::discarded)

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 2198bc29d19fe..cd5d4b280e793 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -42,20 +42,6 @@ class SharedSymbol;
 class Symbol;
 class Undefined;
 
-// This is a StringRef-like container that doesn't run strlen().
-//
-// ELF string tables contain a lot of null-terminated strings. Most of them
-// are not necessary for the linker because they are names of local symbols,
-// and the linker doesn't use local symbol names for name resolution. So, we
-// use this class to represents strings read from string tables.
-struct StringRefZ {
-  StringRefZ(const char *s) : data(s), size(-1) {}
-  StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
-
-  const char *data;
-  const uint32_t size;
-};
-
 // Some index properties of a symbol are stored separately in this auxiliary
 // struct to decrease sizeof(SymbolUnion) in the majority of cases.
 struct SymbolAux {
@@ -87,7 +73,8 @@ class Symbol {
 
 protected:
   const char *nameData;
-  mutable uint32_t nameSize;
+  // 32-bit size saves space.
+  uint32_t nameSize;
 
 public:
   // A symAux index used to access GOT/PLT entry indexes. This is allocated in
@@ -179,11 +166,7 @@ class Symbol {
   // all input files have been added.
   bool isUndefWeak() const { return isWeak() && isUndefined(); }
 
-  StringRef getName() const {
-    if (nameSize == (uint32_t)-1)
-      nameSize = strlen(nameData);
-    return {nameData, nameSize};
-  }
+  StringRef getName() const { return {nameData, nameSize}; }
 
   void setName(StringRef s) {
     nameData = s.data();
@@ -196,10 +179,7 @@ class Symbol {
   //
   // For @@, the name has been truncated by insert(). For @, the name has been
   // truncated by Symbol::parseSymbolVersion().
-  const char *getVersionSuffix() const {
-    (void)getName();
-    return nameData + nameSize;
-  }
+  const char *getVersionSuffix() const { return nameData + nameSize; }
 
   uint32_t getGotIdx() const {
     return auxIdx == uint32_t(-1) ? uint32_t(-1) : symAux[auxIdx].gotIdx;
@@ -266,10 +246,11 @@ class Symbol {
   inline size_t getSymbolSize() const;
 
 protected:
-  Symbol(Kind k, InputFile *file, StringRefZ name, uint8_t binding,
+  Symbol(Kind k, InputFile *file, StringRef name, uint8_t binding,
          uint8_t stOther, uint8_t type)
-      : file(file), nameData(name.data), nameSize(name.size), binding(binding),
-        type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
+      : file(file), nameData(name.data()), nameSize(name.size()),
+        binding(binding), type(type), stOther(stOther), symbolKind(k),
+        visibility(stOther & 3),
         isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
         exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
         canInline(false), referenced(false), traced(false),
@@ -348,7 +329,7 @@ class Symbol {
 // Represents a symbol that is defined in the current output file.
 class Defined : public Symbol {
 public:
-  Defined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+  Defined(InputFile *file, StringRef name, uint8_t binding, uint8_t stOther,
           uint8_t type, uint64_t value, uint64_t size, SectionBase *section)
       : Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
         size(size), section(section) {}
@@ -383,7 +364,7 @@ class Defined : public Symbol {
 // section. (Therefore, the later passes don't see any CommonSymbols.)
 class CommonSymbol : public Symbol {
 public:
-  CommonSymbol(InputFile *file, StringRefZ name, uint8_t binding,
+  CommonSymbol(InputFile *file, StringRef name, uint8_t binding,
                uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
       : Symbol(CommonKind, file, name, binding, stOther, type),
         alignment(alignment), size(size) {}
@@ -396,7 +377,7 @@ class CommonSymbol : public Symbol {
 
 class Undefined : public Symbol {
 public:
-  Undefined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
+  Undefined(InputFile *file, StringRef name, uint8_t binding, uint8_t stOther,
             uint8_t type, uint32_t discardedSecIdx = 0)
       : Symbol(UndefinedKind, file, name, binding, stOther, type),
         discardedSecIdx(discardedSecIdx) {}


        


More information about the llvm-commits mailing list