]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: use 100x less memory for []byte("string")
authorRuss Cox <rsc@golang.org>
Tue, 7 Jan 2014 01:43:44 +0000 (20:43 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 7 Jan 2014 01:43:44 +0000 (20:43 -0500)
[]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

src/cmd/gc/go.h
src/cmd/gc/obj.c
src/cmd/gc/sinit.c
src/cmd/gc/typecheck.c

index 2e03898cdae086cd54df14763fbb0d75cf845c4e..a00f5c8ab09e116abe979bf4e6b0ac2fbf4a9844 100644 (file)
@@ -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*);
 
 /*
index c17be5c39812296735664a9633b370a25ee5b7fa..c6ba367647c7173b17d68b6c779c325b19c8f2c6 100644 (file)
@@ -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);
+}
index 446b1110ac1c25062d1bf61a445fab46b55fca67..59c5097e040221c0120e262404fdaf8c41bfa557 100644 (file)
@@ -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)) {
index 6f8b6adbbf97eea27608da04f0ec1119dbf7b651..4d0a636bb907e496f1de16cf639613d8497cf9f5 100644 (file)
@@ -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);