aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-13 11:40:59 +1300
committerAndrew Chambers <[email protected]>2021-10-13 11:40:59 +1300
commite6326541162130dd4c2121db14c298cd5ad2009c (patch)
tree36693b45d78df0b2551511bdd08f7ab847c035a0
parent4fc6bfe524c3f708111e4659627d474d73f3352d (diff)
Simple string interning.
-rw-r--r--asm.peg6
-rw-r--r--minias.h2
-rw-r--r--util.c16
3 files changed, 21 insertions, 3 deletions
diff --git a/asm.peg b/asm.peg
index 0a80d3a..f181cfe 100644
--- a/asm.peg
+++ b/asm.peg
@@ -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
diff --git a/minias.h b/minias.h
index cbaae9b..8855756 100644
--- a/minias.h
+++ b/minias.h
@@ -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;
diff --git a/util.c b/util.c
index 9ed1c50..5cede75 100644
--- a/util.c
+++ b/util.c
@@ -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;