From c6c0f2ef35175075e91169113cfe856f29b3eb9a Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 15 Dec 2025 21:46:24 +0100 Subject: move intern() to mem.c Being in lex.c was vestigial, since it was being used all over the frontend and backend. --- c/builtin.c | 1 - c/lex.c | 45 --------------------------------------------- c/lex.h | 1 - common.h | 3 +++ ir/ir.c | 1 - mem.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 52 insertions(+), 49 deletions(-) diff --git a/c/builtin.c b/c/builtin.c index a923bf1..aabd750 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -113,7 +113,6 @@ void putbuiltins(struct env *env) { for (int i = 0; i < countof(tab); ++i) { - const char *intern(const char *); envadddecl(env, &(struct decl) { .name = intern(tab[i].name), .isbuiltin = 1, diff --git a/c/lex.c b/c/lex.c index 2f33fc7..6c55e7f 100644 --- a/c/lex.c +++ b/c/lex.c @@ -1,51 +1,6 @@ #include "lex.h" #include -const char * -intern(const char *s) -{ - static uint N, n; - static struct ht { - const char *s; - size_t h; - } *ht; - static struct { char m[sizeof(struct arena) + (2<<10)]; struct arena *_a; } amem; - static struct arena *arena; - - if (!N) { - ht = xcalloc((sizeof *ht) * (N = 1<<10)); - arena = (void *)amem.m, arena->cap = sizeof amem.m - sizeof(struct arena); - } - - for (size_t h = hashs(0, s), i = h;;) { - i &= N - 1; - if (!ht[i].s) { /* insert */ - if (n < N/4*3 /*load factor 75%*/) { - ++n; - ht[i].h = h; - return ht[i].s = alloccopy(&arena, s, strlen(s)+1, 1); - } - /* resize */ - size_t nnew = N * 2; - struct ht *new = xcalloc(sizeof *new * nnew); - for (uint i = 0; i < N; ++i) { /* rehash */ - if (!ht[i].s) continue; - uint j = ht[i].h; - while (new[j &= nnew-1].s) ++j; - new[j] = ht[i]; - } - free(ht); - ht = new; - N = nnew; - i = h; - continue; - } else if (h == ht[i].h && !strcmp(s, ht[i].s)) { - return ht[i].s; - } - ++i; - } -} - static void identkeyword(struct token *tk, const char *s, int len) { diff --git a/c/lex.h b/c/lex.h index 89c9a7d..2782f67 100644 --- a/c/lex.h +++ b/c/lex.h @@ -111,7 +111,6 @@ enum initlexer { LXERR, }; -const char *intern(const char *); int lex(struct lexer *, struct token *); int lexpeek(struct lexer *, struct token *); enum typetag parsenumlit(uvlong *, double *, const struct token *, bool ispp); diff --git a/common.h b/common.h index 0d1ec4c..061c379 100644 --- a/common.h +++ b/common.h @@ -178,6 +178,9 @@ void free(void *); #define xcalloc(n) xcalloc(n, __func__) #define xrealloc(p,n) xrealloc(p, n, __func__) +/* string interning */ +const char *intern(const char *); + /* growable buffer that stores its capacity in the allocated memory */ #define xbnew_(n) (void *)(1 + (size_t *)xcalloc(sizeof(size_t) + (n))) #define xbcap_(p) ((size_t *)(p))[-1] diff --git a/ir/ir.c b/ir/ir.c index 13b309d..d932121 100644 --- a/ir/ir.c +++ b/ir/ir.c @@ -152,7 +152,6 @@ mkdatref(const char *name, union type ctype, uint siz, uint align, const void *b assert(n <= siz && siz && align); if (!name) { - extern const char *intern(const char *); char buf[32]; struct wbuf wbuf = MEMBUF(buf, sizeof buf); diff --git a/mem.c b/mem.c index 1c0f121..6866216 100644 --- a/mem.c +++ b/mem.c @@ -36,8 +36,53 @@ void * return p; } -/* vec: when .dyn, buf is dynamic allocated, otherwise an user provided buf */ +/** string interning **/ +const char * +intern(const char *s) +{ + static uint N, n; + static struct ht { + const char *s; + size_t h; + } *ht; + static struct { char m[sizeof(struct arena) + (2<<10)]; struct arena *_a; } amem; + static struct arena *arena; + + if (!N) { + ht = xcalloc((sizeof *ht) * (N = 1<<10)); + arena = (void *)amem.m, arena->cap = sizeof amem.m - sizeof(struct arena); + } + + for (size_t h = hashs(0, s), i = h;;) { + i &= N - 1; + if (!ht[i].s) { /* insert */ + if (n < N/4*3 /*load factor 75%*/) { + ++n; + ht[i].h = h; + return ht[i].s = alloccopy(&arena, s, strlen(s)+1, 1); + } + /* resize */ + size_t nnew = N * 2; + struct ht *new = xcalloc(sizeof *new * nnew); + for (uint i = 0; i < N; ++i) { /* rehash */ + if (!ht[i].s) continue; + uint j = ht[i].h; + while (new[j &= nnew-1].s) ++j; + new[j] = ht[i]; + } + free(ht); + ht = new; + N = nnew; + i = h; + continue; + } else if (h == ht[i].h && !strcmp(s, ht[i].s)) { + return ht[i].s; + } + ++i; + } +} +/** vec **/ void vinit_(struct vecbase *v, void *inlbuf, uint cap, uint siz) { @@ -96,6 +141,7 @@ vresize_(struct vecbase *v, uint siz, uint N) v->n = N; } +/** arena **/ struct arena * newarena(uint chunksiz) { @@ -155,6 +201,7 @@ freearena(struct arena **par) } } +/** integer hashmap **/ void imap_init_(struct imapbase *m, void **v, uint vsiz, uint N) { @@ -238,6 +285,7 @@ imap_set_(struct imapbase *m, void **v, uint vsiz, short k) } } +/** pointer hashmap **/ void pmap_init_(struct pmapbase *m, void **v, uint vsiz, uint N) { -- cgit v1.2.3