Skip to content

Commit d08ab66

Browse files
author
James Marsh
committed
perf(wamrc): Replace slow symbol lookup with hash map in AOT compilation/emission
The relocation symbol deduplication in aot_emit_aot_file.c used a linked list, requiring O(n) traversal per relocation to check for duplicates. Replace with a lazily-allocated hash map for O(1) lookups. The linked list is preserved for ordered iteration during emission.
1 parent 389d206 commit d08ab66

File tree

1 file changed

+82
-32
lines changed

1 file changed

+82
-32
lines changed

core/iwasm/compilation/aot_emit_aot_file.c

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef struct AOTSymbolList {
4545
AOTSymbolNode *head;
4646
AOTSymbolNode *end;
4747
uint32 len;
48+
void *hash_table;
4849
} AOTSymbolList;
4950

5051
/* AOT object data */
@@ -989,46 +990,81 @@ get_relocation_groups_size(AOTObjectData *obj_data,
989990
return size;
990991
}
991992

992-
/* return the index (in order of insertion) of the symbol,
993-
create if not exits, -1 if failed */
993+
#define SYMBOL_HASH_SIZE 4096
994+
#define SYMBOL_HASH_MASK (SYMBOL_HASH_SIZE - 1)
995+
996+
typedef struct AOTSymbolHashEntry {
997+
const char *symbol;
998+
uint32 index;
999+
struct AOTSymbolHashEntry *hash_next;
1000+
} AOTSymbolHashEntry;
1001+
9941002
static uint32
9951003
get_relocation_symbol_index(const char *symbol_name, bool *is_new,
9961004
AOTSymbolList *symbol_list)
9971005
{
998-
AOTSymbolNode *sym;
999-
uint32 index = 0;
1000-
1001-
sym = symbol_list->head;
1002-
while (sym) {
1003-
if (!strcmp(sym->symbol, symbol_name)) {
1004-
if (is_new)
1005-
*is_new = false;
1006-
return index;
1006+
uint32 index;
1007+
AOTSymbolHashEntry **ht;
1008+
if (!symbol_list->hash_table) {
1009+
symbol_list->hash_table = wasm_runtime_malloc(
1010+
sizeof(AOTSymbolHashEntry *) * SYMBOL_HASH_SIZE);
1011+
if (symbol_list->hash_table)
1012+
memset(symbol_list->hash_table, 0,
1013+
sizeof(AOTSymbolHashEntry *) * SYMBOL_HASH_SIZE);
1014+
}
1015+
ht = (AOTSymbolHashEntry **)symbol_list->hash_table;
1016+
if (ht) {
1017+
uint32 bucket = wasm_string_hash(symbol_name) & SYMBOL_HASH_MASK;
1018+
AOTSymbolHashEntry *entry = ht[bucket];
1019+
while (entry) {
1020+
if (!strcmp(entry->symbol, symbol_name)) {
1021+
if (is_new)
1022+
*is_new = false;
1023+
return entry->index;
1024+
}
1025+
entry = entry->hash_next;
10071026
}
1008-
1009-
sym = sym->next;
1010-
index++;
1011-
}
1012-
1013-
/* Not found in symbol_list, add it */
1014-
sym = wasm_runtime_malloc(sizeof(AOTSymbolNode));
1015-
if (!sym) {
1016-
return (uint32)-1;
1017-
}
1018-
1019-
memset(sym, 0, sizeof(AOTSymbolNode));
1020-
sym->symbol = (char *)symbol_name;
1021-
sym->str_len = (uint32)strlen(symbol_name);
1022-
1023-
if (!symbol_list->head) {
1024-
symbol_list->head = symbol_list->end = sym;
10251027
}
10261028
else {
1027-
symbol_list->end->next = sym;
1028-
symbol_list->end = sym;
1029+
AOTSymbolNode *sym = symbol_list->head;
1030+
uint32 idx = 0;
1031+
while (sym) {
1032+
if (!strcmp(sym->symbol, symbol_name)) {
1033+
if (is_new)
1034+
*is_new = false;
1035+
return idx;
1036+
}
1037+
sym = sym->next;
1038+
idx++;
1039+
}
1040+
}
1041+
index = symbol_list->len;
1042+
{
1043+
AOTSymbolNode *sym = wasm_runtime_malloc(sizeof(AOTSymbolNode));
1044+
if (!sym)
1045+
return (uint32)-1;
1046+
memset(sym, 0, sizeof(AOTSymbolNode));
1047+
sym->symbol = (char *)symbol_name;
1048+
sym->str_len = (uint32)strlen(symbol_name);
1049+
if (!symbol_list->head)
1050+
symbol_list->head = symbol_list->end = sym;
1051+
else {
1052+
symbol_list->end->next = sym;
1053+
symbol_list->end = sym;
1054+
}
1055+
symbol_list->len++;
1056+
}
1057+
if (ht) {
1058+
uint32 bucket = wasm_string_hash(symbol_name) & SYMBOL_HASH_MASK;
1059+
AOTSymbolHashEntry *entry =
1060+
wasm_runtime_malloc(sizeof(AOTSymbolHashEntry));
1061+
if (!entry)
1062+
return (uint32)-1;
1063+
entry->symbol = symbol_name;
1064+
entry->index = index;
1065+
entry->hash_next = ht[bucket];
1066+
ht[bucket] = entry;
10291067
}
1030-
symbol_list->len++;
1031-
10321068
if (is_new)
10331069
*is_new = true;
10341070
return index;
@@ -4324,6 +4360,20 @@ destroy_relocation_symbol_list(AOTSymbolList *symbol_list)
43244360
wasm_runtime_free(elem);
43254361
elem = next;
43264362
}
4363+
if (symbol_list->hash_table) {
4364+
AOTSymbolHashEntry **ht =
4365+
(AOTSymbolHashEntry **)symbol_list->hash_table;
4366+
uint32 i;
4367+
for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
4368+
AOTSymbolHashEntry *entry = ht[i];
4369+
while (entry) {
4370+
AOTSymbolHashEntry *next = entry->hash_next;
4371+
wasm_runtime_free(entry);
4372+
entry = next;
4373+
}
4374+
}
4375+
wasm_runtime_free(ht);
4376+
}
43274377
}
43284378

43294379
void

0 commit comments

Comments
 (0)