Skip to content

Commit

Permalink
Use xxhash instead of gdb_hash for the internal hashmap for .gdb_index
Browse files Browse the repository at this point in the history
Our ConcurrentMap uses linear probing to find unused hash table entry.
It gives up if 128 consective slots are occupied, and the whole process
dies with the "ConcurrentMap is full" error message. So our hash
function's quality must be high.

For .gdb_index, we used to use gdb_index() to compute keys for the
ConcurrentMap. It turned out that the function's quality is poor,
generating very similar output for short strings.

This commit changes the hash function to xxhash.

Fixes https://issues.chromium.org/issues/40276991#comment5
  • Loading branch information
rui314 committed Mar 6, 2024
1 parent c45dd19 commit c60d1d0
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions elf/gdb-index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ struct NameType {
}

std::string_view name;
u32 hash;
u64 hash;
u8 type;
};

struct MapValue {
u32 hash = 0;
u32 gdb_hash = 0;
Atomic<u32> count;
u32 name_offset = 0;
u32 type_offset = 0;
Expand Down Expand Up @@ -539,7 +539,7 @@ static i64 read_pubnames_cu(Context<E> &ctx, const PubnamesHdr &hdr,
u8 type = *p++;
std::string_view name = (char *)p;
p += name.size() + 1;
cu->nametypes.push_back({name, gdb_hash(name), type});
cu->nametypes.push_back({name, hash_string(name), type});
}

return size;
Expand Down Expand Up @@ -683,7 +683,8 @@ void write_gdb_index(Context<E> &ctx) {
for (NameType &nt : cu.nametypes) {
MapValue *ent;
bool inserted;
std::tie(ent, inserted) = map.insert(nt.name, nt.hash, MapValue{nt.hash});
std::tie(ent, inserted) = map.insert(nt.name, nt.hash,
MapValue{gdb_hash(nt.name)});
ent->count++;
cu.entries.push_back(ent);
}
Expand Down Expand Up @@ -750,7 +751,7 @@ void write_gdb_index(Context<E> &ctx) {
ul32 *ht = (ul32 *)(buf + hdr.symtab_offset);

for (Entry *ent : entries) {
u32 hash = ent->value.hash;
u32 hash = ent->value.gdb_hash;
u32 step = ((hash * 17) & mask) | 1;
u32 j = hash & mask;

Expand Down

0 comments on commit c60d1d0

Please sign in to comment.