elf: Optimize symbol binding by pre-computing divisions

The division for the hash table lookup shows up in profiles.  We can
use a standard compiler optimization technique to speed up the hash
table lookup.  The speedup is most pronounced when a symbol lookup
succeeds early in the scope array, otherwise the bitmap check
dominates the profiles.

Change-Id: I898b7c711979447d4756b3f7b567c49a8d33187b
This commit is contained in:
Florian Weimer 2019-11-04 18:08:50 +01:00
parent 0e5a24f5a9
commit 0fa7402cbb
2 changed files with 20 additions and 2 deletions

View File

@ -28,6 +28,7 @@
#include <libc-lock.h>
#include <tls.h>
#include <atomic.h>
#include <divopt.h>
#include <assert.h>
@ -394,8 +395,18 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
if (__glibc_unlikely ((bitmask_word >> hashbit1)
& (bitmask_word >> hashbit2) & 1))
{
Elf32_Word bucket = map->l_gnu_buckets[new_hash
% map->l_nbuckets];
Elf32_Word bucket;
if (map->l_nbuckets > 1)
{
uint32_t quotient
= divopt_32 (new_hash, map->l_nbuckets_multiplier,
map->l_nbuckets_multiplier_shift);
uint32_t remainder = new_hash - map->l_nbuckets * quotient;
bucket = map->l_gnu_buckets[remainder];
}
else
bucket = map->l_gnu_buckets[0];
if (bucket != 0)
{
const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
@ -931,6 +942,11 @@ _dl_setup_hash (struct link_map *map)
/* Initialize MIPS xhash translation table. */
ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
if (map->l_nbuckets >= 2)
map->l_nbuckets_multiplier_shift
= precompute_divopt_32 (map->l_nbuckets,
&map->l_nbuckets_multiplier);
return;
}

View File

@ -153,6 +153,8 @@ struct link_map
/* Symbol hash table. */
Elf_Symndx l_nbuckets;
uint32_t l_nbuckets_multiplier;
int l_nbuckets_multiplier_shift;
Elf32_Word l_gnu_bitmask_idxbits;
Elf32_Word l_gnu_shift;
const ElfW(Addr) *l_gnu_bitmask;