aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-15 21:46:24 +0100
committerlemon <lsof@mailbox.org>2025-12-15 21:46:24 +0100
commitc6c0f2ef35175075e91169113cfe856f29b3eb9a (patch)
tree65dc85d7b2845a4e1145ac9d6ffd26fbb2482e8e
parentbf0f2805b5aec7f4fa5fb4ff1a4da081a0112e4e (diff)
move intern() to mem.c
Being in lex.c was vestigial, since it was being used all over the frontend and backend.
-rw-r--r--c/builtin.c1
-rw-r--r--c/lex.c45
-rw-r--r--c/lex.h1
-rw-r--r--common.h3
-rw-r--r--ir/ir.c1
-rw-r--r--mem.c50
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 <string.h>
-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)
{