diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 290a29d8af7d..9cbd245244e8 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -52,23 +52,15 @@ std::string toCOFFString(const Archive::Symbol &b) { namespace coff { -StringRef Symbol::getName() { - // COFF symbol names are read lazily for a performance reason. - // Non-external symbol names are never used by the linker except for logging - // or debugging. Their internal references are resolved not by name but by - // symbol index. And because they are not external, no one can refer them by - // name. Object files contain lots of non-external symbols, and creating - // StringRefs for them (which involves lots of strlen() on the string table) - // is a waste of time. - if (nameData == nullptr) { - auto *d = cast(this); - StringRef nameStr; - cast(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr); - nameData = nameStr.data(); - nameSize = nameStr.size(); - assert(nameSize == nameStr.size() && "name length truncated"); - } - return StringRef(nameData, nameSize); +void Symbol::computeName() { + assert(nameData == nullptr && + "should only compute the name once for DefinedCOFF symbols"); + auto *d = cast(this); + StringRef nameStr; + cast(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr); + nameData = nameStr.data(); + nameSize = nameStr.size(); + assert(nameSize == nameStr.size() && "name length truncated"); } InputFile *Symbol::getFile() { diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index a8e70320b995..1da4df366966 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -69,7 +69,18 @@ public: Kind kind() const { return static_cast(symbolKind); } // Returns the symbol name. - StringRef getName(); + StringRef getName() { + // COFF symbol names are read lazily for a performance reason. + // Non-external symbol names are never used by the linker except for logging + // or debugging. Their internal references are resolved not by name but by + // symbol index. And because they are not external, no one can refer them by + // name. Object files contain lots of non-external symbols, and creating + // StringRefs for them (which involves lots of strlen() on the string table) + // is a waste of time. + if (nameData == nullptr) + computeName(); + return StringRef(nameData, nameSize); + } void replaceKeepingName(Symbol *other, size_t size); @@ -84,6 +95,9 @@ public: return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind; } +private: + void computeName(); + protected: friend SymbolTable; explicit Symbol(Kind k, StringRef n = "")