about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYip Coekjan <69834864+Coekjan@users.noreply.github.com>2024-09-06 20:35:32 +0800
committerGitHub <noreply@github.com>2024-09-06 14:35:32 +0200
commit7dc59ac342d315dbb352becbeabc4e7057992de0 (patch)
treea1b24c29de316422205a0f6a86f6268e3bee91dd /src
parent16f156be3f9b2089af807f012a960034dddb00ac (diff)
downloadbox64-7dc59ac342d315dbb352becbeabc4e7057992de0.tar.gz
box64-7dc59ac342d315dbb352becbeabc4e7057992de0.zip
Eliminate duplicate hash calculations for `getSymbolInSymbolMaps` (#1801)
Diffstat (limited to 'src')
-rw-r--r--src/include/khash.h34
-rw-r--r--src/librarian/library.c15
2 files changed, 43 insertions, 6 deletions
diff --git a/src/include/khash.h b/src/include/khash.h
index 823757bf..80711c3d 100644
--- a/src/include/khash.h
+++ b/src/include/khash.h
@@ -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) {												\
@@ -463,6 +479,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]
   @param  h     Pointer to the hash table [khash_t(name)*]
diff --git a/src/librarian/library.c b/src/librarian/library.c
index e21e648c..34bb0b79 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -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)