Commit d227d680 authored by Russ Cox's avatar Russ Cox

cmd/gc: use 100x less memory for []byte("string")

[]byte("string") was simplifying to
[]byte{0: 0x73, 1: 0x74, 2: 0x72, 3: 0x69, 4: 0x6e, 5: 0x67},
but that latter form takes up much more memory in the compiler.
Preserve the string form and recognize it to turn global variables
initialized this way into linker-initialized data.

Reduces the compiler memory footprint for a large []byte initialized
this way from approximately 10 kB/B to under 100 B/B.

See also issue 6643.

R=golang-codereviews, r, iant, oleku.konko, dave, gobot, bradfitz
CC=golang-codereviews
https://golang.org/cl/15930045
parent 78c16c9b
......@@ -1263,6 +1263,7 @@ int duintptr(Sym *s, int off, uint64 v);
int dsname(Sym *s, int off, char *dat, int ndat);
void dumpobj(void);
Sym* stringsym(char*, int);
void slicebytes(Node*, char*, int);
LSym* linksym(Sym*);
/*
......
......@@ -253,3 +253,31 @@ stringsym(char *s, int len)
return sym;
}
void
slicebytes(Node *nam, char *s, int len)
{
int off, n, m;
static int gen;
Sym *sym;
snprint(namebuf, sizeof(namebuf), ".gobytes.%d", ++gen);
sym = pkglookup(namebuf, localpkg);
sym->def = newname(sym);
off = 0;
for(n=0; n<len; n+=m) {
m = 8;
if(m > len-n)
m = len-n;
off = dsname(sym, off, s+n, m);
}
ggloblsym(sym, off, 0, 0);
if(nam->op != ONAME)
fatal("slicebytes %N", nam);
off = nam->xoffset;
off = dsymptr(nam->sym, off, sym, 0);
off = duintxx(nam->sym, off, len, widthint);
duintxx(nam->sym, off, len, widthint);
}
......@@ -378,6 +378,7 @@ staticassign(Node *l, Node *r, NodeList **out)
InitPlan *p;
InitEntry *e;
int i;
Strlit *sval;
switch(r->op) {
default:
......@@ -426,6 +427,14 @@ staticassign(Node *l, Node *r, NodeList **out)
}
break;
case OSTRARRAYBYTE:
if(l->class == PEXTERN && r->left->op == OLITERAL) {
sval = r->left->val.u.sval;
slicebytes(l, sval->s, sval->len);
return 1;
}
break;
case OARRAYLIT:
initplan(r);
if(isslice(r->type)) {
......
......@@ -1406,6 +1406,9 @@ reswitch:
}
break;
case OSTRARRAYBYTE:
// do not use stringtoarraylit.
// generated code and compiler memory footprint is better without it.
break;
case OSTRARRAYRUNE:
if(n->left->op == OLITERAL)
stringtoarraylit(&n);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment