aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-13 12:20:52 +1300
committerAndrew Chambers <[email protected]>2021-10-13 12:20:52 +1300
commit7f51b475428aa2c0b505e1946870cb82a1155409 (patch)
treed5a551c49994ed8db6d018abe0e3e3ab7a92035e
parent17505af0c36e993f48cb072b5c2ecf41bc540ec4 (diff)
parente6326541162130dd4c2121db14c298cd5ad2009c (diff)
Merge branch 'master' of github.com:andrewchambers/minias
-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 100eaa2..8d8108c 100644
--- a/minias.h
+++ b/minias.h
@@ -349,6 +349,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;