Skip to content

Commit abcbd45

Browse files
bamorui314
authored andcommitted
perf: cache symbol names to avoid per-call strlen
Several parse-time sites converted `symbol_strtab.data() + st_name` implicitly to string_view, running strlen on each call. Precompute a string_view vector parallel to elf_syms and read from it.
1 parent f1b4be8 commit abcbd45

4 files changed

Lines changed: 21 additions & 5 deletions

File tree

src/input-files.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ InputFile<E>::InputFile(Context<E> &ctx, MappedFile *mf)
9393
shstrtab = this->get_string(ctx, shstrtab_idx);
9494
}
9595

96+
template <typename E>
97+
void InputFile<E>::populate_symbol_names() {
98+
symbol_names.reserve(elf_syms.size());
99+
for (const ElfSym<E> &esym : elf_syms) {
100+
const char *p = symbol_strtab.data() + esym.st_name;
101+
symbol_names.emplace_back(p, strlen(p));
102+
}
103+
}
104+
96105
template <typename E>
97106
ElfShdr<E> *InputFile<E>::find_section(i64 type) {
98107
for (ElfShdr<E> &sec : elf_sections)
@@ -329,7 +338,7 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
329338
signature = this->shstrtab.data() +
330339
this->elf_sections[get_shndx(esym)].sh_name;
331340
} else {
332-
signature = this->symbol_strtab.data() + esym.st_name;
341+
signature = this->symbol_names[shdr.sh_info];
333342
}
334343

335344
// Ignore a broken comdat group GCC emits for .debug_macros.
@@ -646,7 +655,7 @@ void ObjectFile<E>::initialize_symbols(Context<E> &ctx) {
646655
if (esym.st_type == STT_SECTION)
647656
name = this->shstrtab.data() + this->elf_sections[get_shndx(esym)].sh_name;
648657
else
649-
name = this->symbol_strtab.data() + esym.st_name;
658+
name = this->symbol_names[i];
650659

651660
Symbol<E> &sym = this->local_syms[i];
652661
sym.set_name(name);
@@ -674,7 +683,7 @@ void ObjectFile<E>::initialize_symbols(Context<E> &ctx) {
674683
has_common_symbol = true;
675684

676685
// Get a symbol name
677-
std::string_view key = this->symbol_strtab.data() + esym.st_name;
686+
std::string_view key = this->symbol_names[i];
678687
std::string_view name = key;
679688

680689
// Parse symbol version after atsign
@@ -889,6 +898,7 @@ void ObjectFile<E>::parse(Context<E> &ctx) {
889898
this->first_global = symtab_sec->sh_info;
890899
this->elf_syms = this->template get_data<ElfSym<E>>(ctx, *symtab_sec);
891900
this->symbol_strtab = this->get_string(ctx, symtab_sec->sh_link);
901+
this->populate_symbol_names();
892902

893903
if (ElfShdr<E> *shdr = this->find_section(SHT_SYMTAB_SHNDX))
894904
symtab_shndx_sec = this->template get_data<U32<E>>(ctx, *shdr);

src/lto-unix.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ ObjectFile<E> *read_lto_object(Context<E> &ctx, MappedFile *mf) {
675675

676676
obj->symbol_strtab = save_string(ctx, strtab);
677677
obj->elf_syms = obj->lto_elf_syms;
678+
obj->populate_symbol_names();
678679
obj->initialize_symbols(ctx);
679680
plugin_symbols.clear();
680681
return obj;

src/mold.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,11 @@ class InputFile {
17121712
std::string_view shstrtab;
17131713
std::string_view symbol_strtab;
17141714

1715+
// Parallel to elf_syms; cached to avoid per-call strlen.
1716+
std::vector<std::string_view> symbol_names;
1717+
1718+
void populate_symbol_names();
1719+
17151720
bool as_needed = false;
17161721
bool has_init_array = false;
17171722
bool has_ctors = false;

src/passes.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,8 +2178,8 @@ void parse_symbol_version(Context<E> &ctx) {
21782178
if (sym->file != file)
21792179
continue;
21802180

2181-
const char *name = file->symbol_strtab.data() + file->elf_syms[i].st_name;
2182-
std::string_view ver = strchr(name, '@') + 1;
2181+
std::string_view name = file->symbol_names[i];
2182+
std::string_view ver = name.substr(name.find('@') + 1);
21832183

21842184
bool is_default = false;
21852185
if (ver.starts_with('@')) {

0 commit comments

Comments
 (0)