reduce memory footprint of strings

This commit is contained in:
Quentin Carbonneaux 2026-05-12 23:38:44 +02:00
parent fbe3cea201
commit c0818978ac
6 changed files with 35 additions and 39 deletions

2
all.h
View File

@ -489,7 +489,7 @@ void vfree(void *);
void vgrow(void *, ulong); void vgrow(void *, ulong);
void addins(Ins **, uint *, Ins *); void addins(Ins **, uint *, Ins *);
void addbins(Ins **, uint *, Blk *); void addbins(Ins **, uint *, Blk *);
char *strf(char *, ...); char *strf(Pool, char *, ...);
uint32_t intern(char *); uint32_t intern(char *);
char *str(uint32_t); char *str(uint32_t);
int argcls(Ins *, int); int argcls(Ins *, int);

View File

@ -511,7 +511,7 @@ split(Fn *fn, Blk *b)
idup(bn, curi, &insb[NIns]-curi); idup(bn, curi, &insb[NIns]-curi);
curi = &insb[NIns]; curi = &insb[NIns];
bn->visit = ++b->visit; bn->visit = ++b->visit;
bn->name = strf("%s.%d", b->name, b->visit); bn->name = strf(PFn, "%s.%d", b->name, b->visit);
bn->loop = b->loop; bn->loop = b->loop;
bn->link = b->link; bn->link = b->link;
b->link = bn; b->link = bn;

View File

@ -548,7 +548,7 @@ split(Fn *fn, Blk *b)
idup(bn, curi, &insb[NIns]-curi); idup(bn, curi, &insb[NIns]-curi);
curi = &insb[NIns]; curi = &insb[NIns];
bn->visit = ++b->visit; bn->visit = ++b->visit;
bn->name = strf("%s.%d", b->name, b->visit); bn->name = strf(PFn, "%s.%d", b->name, b->visit);
bn->loop = b->loop; bn->loop = b->loop;
bn->link = b->link; bn->link = b->link;
b->link = bn; b->link = bn;

60
parse.c
View File

@ -235,7 +235,6 @@ getint()
static int static int
lex() lex()
{ {
char *tok;
int c, i, esc; int c, i, esc;
int t; int t;
@ -302,7 +301,6 @@ lex()
if (c == '"') { if (c == '"') {
t = Tstr; t = Tstr;
Quoted: Quoted:
tokval.str = vnew(2, 1, PFn);
tokval.str[0] = c; tokval.str[0] = c;
esc = 0; esc = 0;
for (i=1;; i++) { for (i=1;; i++) {
@ -321,22 +319,20 @@ lex()
Alpha: Alpha:
if (!isalpha(c) && c != '.' && c != '_') if (!isalpha(c) && c != '.' && c != '_')
err("invalid character %c (%d)", c, c); err("invalid character %c (%d)", c, c);
tok = vnew(2, 1, PFn);
i = 0; i = 0;
do { do {
vgrow(&tok, i+2); vgrow(&tokval.str, i+2);
tok[i++] = c; tokval.str[i++] = c;
c = fgetc(inf); c = fgetc(inf);
} while (isalpha(c) || c == '$' || c == '.' || c == '_' || isdigit(c)); } while (isalpha(c) || c == '$' || c == '.' || c == '_' || isdigit(c));
tok[i] = 0; tokval.str[i] = 0;
ungetc(c, inf); ungetc(c, inf);
tokval.str = tok;
if (t != Txxx) { if (t != Txxx) {
return t; return t;
} }
t = lexh[hash(tok)*K >> M]; t = lexh[hash(tokval.str)*K >> M];
if (t == Txxx || strcmp(kwmap[t], tok) != 0) { if (t == Txxx || strcmp(kwmap[t], tokval.str) != 0) {
err("unknown keyword %s", tok); err("unknown keyword %s", tokval.str);
return Txxx; return Txxx;
} }
return t; return t;
@ -397,7 +393,7 @@ expect(int t)
} }
static Ref static Ref
tmpref(char *v) tmpref()
{ {
int t, i; int t, i;
@ -412,16 +408,16 @@ tmpref(char *v)
tmph[i] = t; tmph[i] = t;
} }
} }
i = hash(v) & (tmphcap-1); i = hash(tokval.str) & (tmphcap-1);
for (; tmph[i]; i=(i+1) & (tmphcap-1)) { for (; tmph[i]; i=(i+1) & (tmphcap-1)) {
t = tmph[i]; t = tmph[i];
if (strcmp(curf->tmp[t].name, v) == 0) if (strcmp(curf->tmp[t].name, tokval.str) == 0)
return TMP(t); return TMP(t);
} }
t = curf->ntmp; t = curf->ntmp;
tmph[i] = t; tmph[i] = t;
newtmp(0, Kx, curf); newtmp(0, Kx, curf);
curf->tmp[t].name = v; curf->tmp[t].name = strf(PFn, "%s", tokval.str);
return TMP(t); return TMP(t);
} }
@ -434,7 +430,7 @@ parseref()
memset(&c, 0, sizeof c); memset(&c, 0, sizeof c);
switch ((tok = next())) { switch ((tok = next())) {
case Ttmp: case Ttmp:
return tmpref(tokval.str); return tmpref();
case Tint: case Tint:
c.type = CBits; c.type = CBits;
c.bits.i = tokval.num; c.bits.i = tokval.num;
@ -583,18 +579,18 @@ parserefl(int arg)
} }
static Blk * static Blk *
findblk(char *name) findblk()
{ {
Blk *b; Blk *b;
uint32_t h; uint32_t h;
h = hash(name) & BMask; h = hash(tokval.str) & BMask;
for (b=blkh[h]; b; b=b->dlink) for (b=blkh[h]; b; b=b->dlink)
if (strcmp(b->name, name) == 0) if (strcmp(b->name, tokval.str) == 0)
return b; return b;
b = newblk(); b = newblk();
b->id = nblk++; b->id = nblk++;
b->name = name; b->name = strf(PFn, "%s", tokval.str);
b->dlink = blkh[h]; b->dlink = blkh[h];
blkh[h] = b; blkh[h] = b;
return b; return b;
@ -624,7 +620,7 @@ parseline(PState ps)
err("label or } expected"); err("label or } expected");
switch (t) { switch (t) {
case Ttmp: case Ttmp:
r = tmpref(tokval.str); r = tmpref();
expect(Teq); expect(Teq);
k = parsecls(&ty); k = parsecls(&ty);
op = next(); op = next();
@ -644,7 +640,7 @@ parseline(PState ps)
case Trbrace: case Trbrace:
return PEnd; return PEnd;
case Tlbl: case Tlbl:
b = findblk(tokval.str); b = findblk();
if (curb && curb->jmp.type == Jxxx) { if (curb && curb->jmp.type == Jxxx) {
closeblk(); closeblk();
curb->jmp.type = Jjmp; curb->jmp.type = Jjmp;
@ -680,11 +676,11 @@ parseline(PState ps)
expect(Tcomma); expect(Tcomma);
Jump: Jump:
expect(Tlbl); expect(Tlbl);
curb->s1 = findblk(tokval.str); curb->s1 = findblk();
if (curb->jmp.type != Jjmp) { if (curb->jmp.type != Jjmp) {
expect(Tcomma); expect(Tcomma);
expect(Tlbl); expect(Tlbl);
curb->s2 = findblk(tokval.str); curb->s2 = findblk();
} }
if (curb->s1 == curf->start || curb->s2 == curf->start) if (curb->s1 == curf->start || curb->s2 == curf->start)
err("invalid jump to the start block"); err("invalid jump to the start block");
@ -744,7 +740,7 @@ parseline(PState ps)
err("too many arguments"); err("too many arguments");
if (op == Tphi) { if (op == Tphi) {
expect(Tlbl); expect(Tlbl);
blk[i] = findblk(tokval.str); blk[i] = findblk();
} }
arg[i] = parseref(); arg[i] = parseref();
if (req(arg[i], R)) if (req(arg[i], R))
@ -940,7 +936,7 @@ parsefn(Lnk *lnk)
rcls = K0; rcls = K0;
if (next() != Tglo) if (next() != Tglo)
err("function name expected"); err("function name expected");
curf->name = tokval.str; curf->name = strf(PFn, "%s", tokval.str);
curf->vararg = parserefl(0); curf->vararg = parserefl(0);
if (nextnl() != Tlbrace) if (nextnl() != Tlbrace)
err("function body must start with {"); err("function body must start with {");
@ -1050,8 +1046,7 @@ parsetyp()
ty->size = 0; ty->size = 0;
if (nextnl() != Ttyp || nextnl() != Teq) if (nextnl() != Ttyp || nextnl() != Teq)
err("type name and then = expected"); err("type name and then = expected");
ty->name = emalloc(strlen(tokval.str)+1); ty->name = strf(PHeap, "%s", tokval.str);
strcpy(ty->name, tokval.str);
t = nextnl(); t = nextnl();
if (t == Talign) { if (t == Talign) {
if (nextnl() != Tint) if (nextnl() != Tint)
@ -1095,7 +1090,7 @@ parsedatref(Dat *d)
int t; int t;
d->isref = 1; d->isref = 1;
d->u.ref.name = tokval.str; d->u.ref.name = strf(PFn, "%s", tokval.str);
d->u.ref.off = 0; d->u.ref.off = 0;
t = peek(); t = peek();
if (t == Tplus) { if (t == Tplus) {
@ -1110,7 +1105,7 @@ static void
parsedatstr(Dat *d) parsedatstr(Dat *d)
{ {
d->isstr = 1; d->isstr = 1;
d->u.str = tokval.str; d->u.str = strf(PFn, "%s", tokval.str);
} }
static void static void
@ -1122,7 +1117,7 @@ parsedat(void cb(Dat *), Lnk *lnk)
if (nextnl() != Tglo || nextnl() != Teq) if (nextnl() != Tglo || nextnl() != Teq)
err("data name, then = expected"); err("data name, then = expected");
name = tokval.str; name = strf(PFn, "%s", tokval.str);
t = nextnl(); t = nextnl();
lnk->align = 8; lnk->align = 8;
if (t == Talign) { if (t == Talign) {
@ -1204,10 +1199,10 @@ parselnk(Lnk *lnk)
err("only one section allowed"); err("only one section allowed");
if (next() != Tstr) if (next() != Tstr)
err("section \"name\" expected"); err("section \"name\" expected");
lnk->sec = tokval.str; lnk->sec = strf(PFn, "%s", tokval.str);
if (peek() == Tstr) { if (peek() == Tstr) {
next(); next();
lnk->secf = tokval.str; lnk->secf = strf(PFn, "%s", tokval.str);
} }
break; break;
default: default:
@ -1232,6 +1227,7 @@ parse(FILE *f, char *path, void dbgfile(char *), void data(Dat *), void func(Fn
thead = Txxx; thead = Txxx;
ntyp = 0; ntyp = 0;
typ = vnew(0, sizeof typ[0], PHeap); typ = vnew(0, sizeof typ[0], PHeap);
tokval.str = vnew(128, 1, PHeap);
for (;;) { for (;;) {
lnk = (Lnk){0}; lnk = (Lnk){0};
switch (parselnk(&lnk)) { switch (parselnk(&lnk)) {

2
rega.c
View File

@ -673,7 +673,7 @@ rega(Fn *fn)
b1->link = blist; b1->link = blist;
blist = b1; blist = b1;
fn->nblk++; fn->nblk++;
b1->name = strf("%s_%s", b->name, s->name); b1->name = strf(PFn, "%s_%s", b->name, s->name);
stmov += &insb[NIns]-curi; stmov += &insb[NIns]-curi;
stblk += 1; stblk += 1;
idup(b1, curi, &insb[NIns]-curi); idup(b1, curi, &insb[NIns]-curi);

6
util.c
View File

@ -173,7 +173,7 @@ addbins(Ins **pvins, uint *pnins, Blk *b)
} }
char * char *
strf(char *s, ...) strf(Pool pool, char *s, ...)
{ {
va_list ap; va_list ap;
int n; int n;
@ -182,7 +182,7 @@ strf(char *s, ...)
va_start(ap, s); va_start(ap, s);
n = vsnprintf(NULL, 0, s, ap); n = vsnprintf(NULL, 0, s, ap);
va_end(ap); va_end(ap);
p = alloc(n + 1); p = (pool == PFn ? alloc : emalloc)(n + 1);
va_start(ap, s); va_start(ap, s);
vsnprintf(p, n + 1, s, ap); vsnprintf(p, n + 1, s, ap);
va_end(ap); va_end(ap);
@ -450,7 +450,7 @@ newtmp(char *prfx, int k, Fn *fn)
vgrow(&fn->tmp, fn->ntmp); vgrow(&fn->tmp, fn->ntmp);
memset(&fn->tmp[t], 0, sizeof(Tmp)); memset(&fn->tmp[t], 0, sizeof(Tmp));
if (prfx) if (prfx)
fn->tmp[t].name = strf("%s.%d", prfx, ++n); fn->tmp[t].name = strf(PFn, "%s.%d", prfx, ++n);
fn->tmp[t].cls = k; fn->tmp[t].cls = k;
fn->tmp[t].slot = -1; fn->tmp[t].slot = -1;
fn->tmp[t].nuse = +1; fn->tmp[t].nuse = +1;