From 8fe59b41fae0f9d6bbd50f98d577937deab060f9 Mon Sep 17 00:00:00 2001 From: icgmilk Date: Sun, 18 May 2025 18:11:39 +0800 Subject: [PATCH] Replace MACROS with hashmap Introduced 'MACROS_MAP' to replace the original 'MACROS' structure, and refactored related logic with hashmap utilities. To make this change improves memory flexibility and future extensibility, I set 'MAX_ALIASES' to 128. The original value (1024) is excessive, as uftrace analysis shows that the number of aliases rarely exceeds 64 in practice(measured via 'uftrace record ./out/shecc ./src/main.c'), and the total number of '#defines' in 'shecc' is typically below 70. In shecc's hashmap implementation, a rehash is triggered when the number of entries exceeds 75% of the capacity. With this load factor of 0.75, a capacity of 128 supports up to 96 entries before rehashing, which comfortably covers observed usage while providing sufficient headroom. In contrast, a capacity of 64 only allows 48 entries, increasing the likelihood of rehashing. uftrace confirms this: setting 'MAX_ALIASES' to 64 triggered one more 'hashmap_rehash' compared to 128. Therefore, I chose 128 over 64 to avoid unnecessary rehashing while still keeping memory usage significantly lower than the original default. --- src/defs.h | 2 +- src/globals.c | 37 +++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/defs.h b/src/defs.h index ccbfcb5e..4da10747 100644 --- a/src/defs.h +++ b/src/defs.h @@ -32,7 +32,7 @@ #define MAX_STRTAB 65536 #define MAX_HEADER 1024 #define MAX_SECTION 1024 -#define MAX_ALIASES 1024 +#define MAX_ALIASES 128 #define MAX_CONSTANTS 1024 #define MAX_CASES 128 #define MAX_NESTING 128 diff --git a/src/globals.c b/src/globals.c index 7e200bfa..37b0c66e 100644 --- a/src/globals.c +++ b/src/globals.c @@ -28,13 +28,12 @@ int macro_return_idx; /* Global objects */ -macro_t *MACROS; -int macros_idx = 0; - /* FUNC_MAP is used to integrate function storing and boost lookup * performance, currently it uses FNV-1a hash function to hash function * name. */ + +hashmap_t *MACROS_MAP; hashmap_t *FUNC_MAP; hashmap_t *ALIASES_MAP; hashmap_t *CONSTANTS_MAP; @@ -557,28 +556,34 @@ bool remove_alias(char *alias) macro_t *add_macro(char *name) { - macro_t *ma = &MACROS[macros_idx++]; - strcpy(ma->name, name); + macro_t *ma = hashmap_get(MACROS_MAP, name); + if (!ma) { + ma = malloc(sizeof(macro_t)); + if (!ma) { + printf("Failed to allocate macro_t\n"); + return NULL; + } + strcpy(ma->name, name); + hashmap_put(MACROS_MAP, name, ma); + } ma->disabled = false; return ma; } macro_t *find_macro(char *name) { - for (int i = 0; i < macros_idx; i++) { - if (!MACROS[i].disabled && !strcmp(name, MACROS[i].name)) - return &MACROS[i]; - } + macro_t *ma = hashmap_get(MACROS_MAP, name); + if (ma && !ma->disabled) + return ma; return NULL; } bool remove_macro(char *name) { - for (int i = 0; i < macros_idx; i++) { - if (!MACROS[i].disabled && !strcmp(name, MACROS[i].name)) { - MACROS[i].disabled = true; - return true; - } + macro_t *ma = hashmap_get(MACROS_MAP, name); + if (ma) { + ma->disabled = true; + return true; } return false; } @@ -974,7 +979,7 @@ void global_init(void) { elf_code_start = ELF_START + elf_header_len; - MACROS = malloc(MAX_ALIASES * sizeof(macro_t)); + MACROS_MAP = hashmap_create(MAX_ALIASES); TYPES = malloc(MAX_TYPES * sizeof(type_t)); BLOCK_ARENA = arena_init(DEFAULT_ARENA_SIZE); INSN_ARENA = arena_init(DEFAULT_ARENA_SIZE); @@ -996,7 +1001,7 @@ void global_init(void) void global_release(void) { - free(MACROS); + hashmap_free(MACROS_MAP); free(TYPES); arena_free(BLOCK_ARENA); arena_free(INSN_ARENA);