mirror of
https://github.com/golang/go
synced 2024-11-12 08:20:22 -07:00
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
This commit is contained in:
parent
78c16c9b16
commit
d227d680ec
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user