Eliminate duplicate hash calculations for getSymbolInSymbolMaps (#1801)

This commit is contained in:
Yip Coekjan 2024-09-06 20:35:32 +08:00 committed by GitHub
parent 16f156be3f
commit 7dc59ac342
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 6 deletions

View File

@ -217,6 +217,22 @@ static const double __ac_HASH_UPPER = 0.77;
h->size = h->n_occupied = 0; \
} \
} \
SCOPE khint_t kh_hash_##name(khkey_t key) { \
return __hash_func(key); \
} \
SCOPE khint_t kh_get_##name##_with_hash(const kh_##name##_t *h, khkey_t key, khint_t hash) { \
if (h->n_buckets) { \
khint_t k = hash, i, last, mask, step = 0; \
mask = h->n_buckets - 1; \
i = k & mask; \
last = i; \
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
i = (i + (++step)) & mask; \
if (i == last) return h->n_buckets; \
} \
return __ac_iseither(h->flags, i)? h->n_buckets : i; \
} else return 0; \
} \
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
{ \
if (h->n_buckets) { \
@ -462,6 +478,24 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
*/
#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
/*! @function
@abstract Hash a key.
@param name Name of the hash table [symbol]
@param key Key [type of keys]
@return Hash value [khint_t]
*/
#define kh_hash(name, key) kh_hash_##name(key)
/*! @function
@abstract Retrieve a key from the hash table with a given hash value.
@param name Name of the hash table [symbol]
@param h Pointer to the hash table [khash_t(name)*]
@param k Key [type of keys]
@param hash Hash value [khint_t]
@return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
*/
#define kh_get_with_hash(name, h, k, hash) kh_get_##name##_with_hash(h, k, hash)
/*! @function
@abstract Retrieve a key from the hash table.
@param name Name of the hash table [symbol]

View File

@ -836,9 +836,10 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint
}
static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak)
{
const khint_t hash = kh_hash(symbolmap, name);
void* symbol;
// check in mysymbolmap
khint_t k = kh_get(symbolmap, lib->w.mysymbolmap, name);
khint_t k = kh_get_with_hash(symbolmap, lib->w.mysymbolmap, name, hash);
if (k!=kh_end(lib->w.mysymbolmap)) {
symbol1_t *s = &kh_value(lib->w.mysymbolmap, k);
if(!s->resolved) {
@ -866,7 +867,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
return 1;
}
// check in stsymbolmap (return struct...)
k = kh_get(symbolmap, lib->w.stsymbolmap, name);
k = kh_get_with_hash(symbolmap, lib->w.stsymbolmap, name, hash);
if (k!=kh_end(lib->w.stsymbolmap)) {
symbol1_t *s = &kh_value(lib->w.stsymbolmap, k);
if(!s->resolved) {
@ -894,7 +895,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
return 1;
}
// check in symbolmap
k = kh_get(symbolmap, lib->w.symbolmap, name);
k = kh_get_with_hash(symbolmap, lib->w.symbolmap, name, hash);
if (k!=kh_end(lib->w.symbolmap)) {
symbol1_t *s = &kh_value(lib->w.symbolmap, k);
if(!s->resolved) {
@ -931,7 +932,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
}
if(!noweak) {
// check in wmysymbolmap
khint_t k = kh_get(symbolmap, lib->w.wmysymbolmap, name);
khint_t k = kh_get_with_hash(symbolmap, lib->w.wmysymbolmap, name, hash);
if (k!=kh_end(lib->w.wmysymbolmap)) {
symbol1_t *s = &kh_value(lib->w.wmysymbolmap, k);
if(!s->resolved) {
@ -958,7 +959,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
*weak = 1;
return 1;
}
k = kh_get(symbolmap, lib->w.wsymbolmap, name);
k = kh_get_with_hash(symbolmap, lib->w.wsymbolmap, name, hash);
if (k!=kh_end(lib->w.wsymbolmap)) {
symbol1_t *s = &kh_value(lib->w.wsymbolmap, k);
if(!s->resolved) {
@ -995,7 +996,9 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
}
}
// check in symbol2map
k = kh_get(symbol2map, lib->w.symbol2map, name);
//
// NOTE: symbol2map & symbolmap share the same hash function, so we can use the same hash
k = kh_get_with_hash(symbol2map, lib->w.symbol2map, name, hash);
if (k!=kh_end(lib->w.symbol2map)) {
symbol2_t *s = &kh_value(lib->w.symbol2map, k);
if(!noweak || !s->weak)