diff options
| author | Andrew Chambers <[email protected]> | 2021-10-13 11:40:59 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-13 11:40:59 +1300 |
| commit | e6326541162130dd4c2121db14c298cd5ad2009c (patch) | |
| tree | 36693b45d78df0b2551511bdd08f7ab847c035a0 | |
| parent | 4fc6bfe524c3f708111e4659627d474d73f3352d (diff) | |
Simple string interning.
| -rw-r--r-- | asm.peg | 6 | ||||
| -rw-r--r-- | minias.h | 2 | ||||
| -rw-r--r-- | util.c | 16 |
3 files changed, 21 insertions, 3 deletions
@@ -53,8 +53,8 @@ section-directive = {$$.section = (DirSection){.kind=ASM_DIR_SECTION, .name=n.charptr, .flags="", .type=SHT_PROGBITS}; } ) -section-name = <[.a-zA-Z0-9\-]+> { $$.charptr = xstrdup(yytext); } -section-flags = '"' <[awx]*> '"' { $$.charptr = xstrdup(yytext); } +section-name = <[.a-zA-Z0-9\-]+> { $$.charptr = internstring(yytext); } +section-flags = '"' <[awx]*> '"' { $$.charptr = internstring(yytext); } section-type = "@nobits" { $$.i64 = SHT_NOBITS; } | "@progbits" { $$.i64 = SHT_PROGBITS; } @@ -589,7 +589,7 @@ value = ident = <[._a-zA-Z][._a-zA-Z0-9]*> - { $$.charptr = xstrdup(yytext); } + { $$.charptr = internstring(yytext); } number = '-' ws? n:unsigned-number @@ -348,6 +348,8 @@ char *xmemdup(const char *, size_t); char *xstrdup(const char *s); void *zalloc(size_t n); +const char *internstring(const char *s); + struct hashtable { size_t len, cap; struct hashtablekey *keys; @@ -76,6 +76,22 @@ char *xmemdup(const char *s, size_t n) { char *xstrdup(const char *s) { return xmemdup(s, strlen(s) + 1); } +const char *internstring(const char *s) { + size_t idx, len; + const char *interned; + static const char *cache[4096] = {0}; + + len = strlen(s); + idx = murmurhash64a(s, len) % sizeof(cache)/sizeof(cache[0]); + interned = cache[idx]; + if (interned && strcmp(s, cache[idx]) == 0) { + return interned; + } + interned = xstrdup(s); + cache[idx] = interned; + return interned; +} + void htabkey(struct hashtablekey *k, const char *s, size_t n) { k->str = s; k->len = n; |
