forked from OSchip/llvm-project
[COFF] Pack Name in Symbol as is done in ELF
Summary: This assumes all symbols are <4GB long, so we can store them as a 32-bit integer. This reorders the fields so the length appears first, packing with the other bitfield data in the base Symbol object. This saved 70MB / 3.60% of heap allocations when linking browser_tests.exe with no PDB. It's not much as a percentage, but worth doing. I didn't do performance measurements, I don't think it will be measurable in time. Reviewers: ruiu, inglorion, amccarth, aganea Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60297 llvm-svn: 358794
This commit is contained in:
parent
a27252794e
commit
a30920c31f
|
@ -20,6 +20,9 @@ using namespace llvm::object;
|
||||||
|
|
||||||
using namespace lld::coff;
|
using namespace lld::coff;
|
||||||
|
|
||||||
|
static_assert(sizeof(SymbolUnion) <= 48,
|
||||||
|
"symbols should be optimized for memory usage");
|
||||||
|
|
||||||
// Returns a symbol name for an error message.
|
// Returns a symbol name for an error message.
|
||||||
std::string lld::toString(coff::Symbol &B) {
|
std::string lld::toString(coff::Symbol &B) {
|
||||||
if (Config->Demangle)
|
if (Config->Demangle)
|
||||||
|
@ -39,11 +42,15 @@ StringRef Symbol::getName() {
|
||||||
// name. Object files contain lots of non-external symbols, and creating
|
// name. Object files contain lots of non-external symbols, and creating
|
||||||
// StringRefs for them (which involves lots of strlen() on the string table)
|
// StringRefs for them (which involves lots of strlen() on the string table)
|
||||||
// is a waste of time.
|
// is a waste of time.
|
||||||
if (Name.empty()) {
|
if (NameData == nullptr) {
|
||||||
auto *D = cast<DefinedCOFF>(this);
|
auto *D = cast<DefinedCOFF>(this);
|
||||||
cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name);
|
StringRef NameStr;
|
||||||
|
cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, NameStr);
|
||||||
|
NameData = NameStr.data();
|
||||||
|
NameSize = NameStr.size();
|
||||||
|
assert(NameSize == NameStr.size() && "name length truncated");
|
||||||
}
|
}
|
||||||
return Name;
|
return StringRef(NameData, NameSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputFile *Symbol::getFile() {
|
InputFile *Symbol::getFile() {
|
||||||
|
@ -67,9 +74,10 @@ bool Symbol::isLive() const {
|
||||||
|
|
||||||
// MinGW specific.
|
// MinGW specific.
|
||||||
void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
|
void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
|
||||||
StringRef OrigName = Name;
|
StringRef OrigName = getName();
|
||||||
memcpy(this, Other, Size);
|
memcpy(this, Other, Size);
|
||||||
Name = OrigName;
|
NameData = OrigName.data();
|
||||||
|
NameSize = OrigName.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
|
COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
|
||||||
|
|
|
@ -79,7 +79,8 @@ protected:
|
||||||
explicit Symbol(Kind K, StringRef N = "")
|
explicit Symbol(Kind K, StringRef N = "")
|
||||||
: SymbolKind(K), IsExternal(true), IsCOMDAT(false),
|
: SymbolKind(K), IsExternal(true), IsCOMDAT(false),
|
||||||
WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
|
WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
|
||||||
IsRuntimePseudoReloc(false), Name(N) {}
|
IsRuntimePseudoReloc(false), NameSize(N.size()),
|
||||||
|
NameData(N.empty() ? nullptr : N.data()) {}
|
||||||
|
|
||||||
const unsigned SymbolKind : 8;
|
const unsigned SymbolKind : 8;
|
||||||
unsigned IsExternal : 1;
|
unsigned IsExternal : 1;
|
||||||
|
@ -106,7 +107,10 @@ public:
|
||||||
unsigned IsRuntimePseudoReloc : 1;
|
unsigned IsRuntimePseudoReloc : 1;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StringRef Name;
|
// Symbol name length. Assume symbol lengths fit in a 32-bit integer.
|
||||||
|
uint32_t NameSize;
|
||||||
|
|
||||||
|
const char *NameData;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The base class for any defined symbols, including absolute symbols,
|
// The base class for any defined symbols, including absolute symbols,
|
||||||
|
@ -129,7 +133,7 @@ public:
|
||||||
// Symbols defined via a COFF object file or bitcode file. For COFF files, this
|
// Symbols defined via a COFF object file or bitcode file. For COFF files, this
|
||||||
// stores a coff_symbol_generic*, and names of internal symbols are lazily
|
// stores a coff_symbol_generic*, and names of internal symbols are lazily
|
||||||
// loaded through that. For bitcode files, Sym is nullptr and the name is stored
|
// loaded through that. For bitcode files, Sym is nullptr and the name is stored
|
||||||
// as a StringRef.
|
// as a decomposed StringRef.
|
||||||
class DefinedCOFF : public Defined {
|
class DefinedCOFF : public Defined {
|
||||||
friend Symbol;
|
friend Symbol;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue