]> Cypherpunks repositories - gostls13.git/commitdiff
6g: generate string data as individual symbols,
authorRuss Cox <rsc@golang.org>
Wed, 6 May 2009 20:47:40 +0000 (13:47 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 6 May 2009 20:47:40 +0000 (13:47 -0700)
so that 6l can discard strings used by dead code.
also, for short strings, generate DUPOK global
symbols so that references to, say, "%s: %s" in
multiple files result in only a single symbol.

R=ken
OCL=28361
CL=28361

src/cmd/6g/gg.h
src/cmd/6g/gsubr.c
src/cmd/6g/obj.c
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/obj.c

index ed2e703dba007b1e277b98a5aa6aca1cff34aa8d..0cebfba469ee3e0db47904bde8f354991f9c6312 100644 (file)
@@ -122,6 +122,7 @@ int isfat(Type*);
 void   sudoclean(void);
 int    sudoaddable(int, Node*, Addr*);
 void   afunclit(Addr*);
+void   datagostring(Strlit*, Addr*);
 
 /*
  * list.c
index 25a16a20e124c62495060ebeeed90a689e0515c6..b29cab304135ef1c12292d8c49d9745030d6ebc5 100644 (file)
@@ -152,8 +152,6 @@ ggloblsym(Sym *s, int32 width, int dupok)
 
        p = gins(AGLOBL, N, N);
        p->from.type = D_EXTERN;
-       if(s == symstringl || s == symstringc)
-               p->from.type = D_STATIC;
        p->from.index = D_NONE;
        p->from.sym = s;
        p->to.type = D_CONST;
@@ -1146,11 +1144,7 @@ naddr(Node *n, Addr *a)
                        a->offset = mpgetfix(n->val.u.xval);
                        break;
                case CTSTR:
-                       a->etype = simtype[n->etype];
-                       a->sym = symstringl;
-                       a->type = D_STATIC;
-                       a->offset = symstringl->offset;
-                       stringpool(n);
+                       datagostring(n->val.u.sval, a);
                        break;
                case CTBOOL:
                        a->sym = S;
index ac249b6b6d06d8b7ad34737c5ca93a32f7fd5739..bdbf5c7671238761727c03af36e2d556d2f57795 100644 (file)
@@ -261,23 +261,75 @@ dumpfuncs(void)
        }
 }
 
+/* deferred DATA output */
+static Prog *strdat;
+static Prog *estrdat;
+static int gflag;
+static Prog *savepc;
+
+static void
+data(void)
+{
+       gflag = debug['g'];
+       debug['g'] = 0;
+       
+       if(estrdat == nil) {
+               strdat = mal(sizeof(*pc));
+               clearp(strdat);
+               estrdat = strdat;
+       }
+       if(savepc)
+               fatal("data phase error");
+       savepc = pc;
+       pc = estrdat;
+}
+
+static void
+text(void)
+{
+       if(!savepc)
+               fatal("text phase error");
+       debug['g'] = gflag;
+       estrdat = pc;
+       pc = savepc;
+       savepc = nil;
+}
+
+void
+dumpdata(void)
+{
+       Prog *p;
+
+       if(estrdat == nil)
+               return;
+       *pc = *strdat;
+       if(gflag)
+               for(p=pc; p!=estrdat; p=p->link)
+                       print("%P\n", p);
+       pc = estrdat;
+}
+
 /*
- * dump the characters of the string
- * pool into the array symstringc
+ * make a refer to the data s, s+len
+ * emitting DATA if needed.
  */
 void
-datastring(char *s, int len)
+datastring(char *s, int len, Addr *a)
 {
        int w;
        Prog *p;
        Addr ac, ao;
-
+       static int gen;
+       struct {
+               Strlit lit;
+               char buf[100];
+       } tmp;
+       
        // string
        memset(&ao, 0, sizeof(ao));
        ao.type = D_STATIC;
        ao.index = D_NONE;
        ao.etype = TINT32;
-       ao.sym = symstringc;
        ao.offset = 0;          // fill in
 
        // constant
@@ -286,13 +338,37 @@ datastring(char *s, int len)
        ac.index = D_NONE;
        ac.offset = 0;          // fill in
 
+       // huge strings are made static to avoid long names.
+       if(len > 100) {
+               snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
+               ao.sym = lookup(namebuf);
+               ao.type = D_STATIC;
+       } else {
+               if(len > 0 && s[len-1] == '\0')
+                       len--;
+               tmp.lit.len = len;
+               memmove(tmp.lit.s, s, len);
+               tmp.lit.s[len] = '\0';
+               len++;
+               snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
+               ao.sym = pkglookup(namebuf, "string");
+               ao.type = D_EXTERN;
+       }
+       *a = ao;
+
+       // only generate data the first time.
+       if(ao.sym->uniq)
+               return;
+       ao.sym->uniq = 1;
+
+       data();
        for(w=0; w<len; w+=8) {
                p = pc;
                gins(ADATA, N, N);
 
-               // .stringo<>+oo, [NSNAME], $"xxx"
+               // DATA s+w, [NSNAME], $"xxx"
                p->from = ao;
-               p->from.offset = stringc;
+               p->from.offset = w;
 
                p->from.scale = NSNAME;
                if(w+8 > len)
@@ -302,25 +378,25 @@ datastring(char *s, int len)
                p->to.type = D_SCONST;
                p->to.offset = len;
                memmove(p->to.sval, s+w, p->from.scale);
-               stringc += p->from.scale;
        }
+       p = pc;
+       ggloblsym(ao.sym, len, ao.type == D_EXTERN);
+       if(ao.type == D_STATIC)
+               p->from.type = D_STATIC;
+       text();
 }
 
 /*
- * dump the strings into thye pool
- * symstingl that consists of a pointer
- * to the characters and a count
+ * make a refer to the string sval,
+ * emitting DATA if needed.
  */
 void
-dumpstrings(void)
+datagostring(Strlit *sval, Addr *a)
 {
-       Pool *l;
        Prog *p;
        Addr ac, ao, ap;
-       int32 wi, wp, ws;
-
-       if(poolist == nil)
-               return;
+       int32 wi, wp;
+       static int gen;
 
        memset(&ac, 0, sizeof(ac));
        memset(&ao, 0, sizeof(ao));
@@ -332,49 +408,61 @@ dumpstrings(void)
        ac.offset = 0;                  // fill in
 
        // string len+ptr
-       ao.type = D_STATIC;
+       ao.type = D_STATIC;             // fill in
        ao.index = D_NONE;
        ao.etype = TINT32;
-       ao.sym = symstringl;
-       ao.offset = 0;                  // fill in
+       ao.sym = nil;                   // fill in
 
        // $string len+ptr
+       datastring(sval->s, sval->len, &ap);
+       ap.index = ap.type;
        ap.type = D_ADDR;
-       ap.index = D_STATIC;
        ap.etype = TINT32;
-       ap.sym = symstringc;
-       ap.offset = 0;                  // fill in
 
        wi = types[TUINT32]->width;
        wp = types[tptr]->width;
-       ws = types[TSTRING]->width;
-
-       // lay out (count+string)
-       for(l=poolist; l!=nil; l=l->link) {
+       
+       if(ap.index == D_STATIC) {
+               // huge strings are made static to avoid long names
+               snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
+               ao.sym = lookup(namebuf);
+               ao.type = D_STATIC;
+       } else {
+               // small strings get named by their contents,
+               // so that multiple modules using the same string
+               // can share it.
+               snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
+               ao.sym = pkglookup(namebuf, "go.string");
+               ao.type = D_EXTERN;
+       }
 
-               // .stringl<>+ol, wp, $.stringc<>+oc
-               p = pc;
-               gins(ADATA, N, N);
-               p->from = ao;
-               p->from.offset = stringl;
-               p->from.scale = wp;
-               p->to = ap;
-               p->to.offset = stringc;
-               stringl += wp;
+       *a = ao;
+       if(ao.sym->uniq)
+               return;
+       ao.sym->uniq = 1;
 
-               // .stringl<>+ol, wi, $len
-               p = pc;
-               gins(ADATA, N, N);
-               p->from = ao;
-               p->from.offset = stringl;
-               p->from.scale = wi;
-               p->to = ac;
-               p->to.offset = l->sval->len;
-               stringl += wi;
+       data();
+       // DATA gostring, wp, $cstring
+       p = pc;
+       gins(ADATA, N, N);
+       p->from = ao;
+       p->from.scale = wp;
+       p->to = ap;
 
-               stringl = rnd(stringl, ws);
-               datastring(l->sval->s, l->sval->len);
-       }
+       // DATA gostring+wp, wi, $len
+       p = pc;
+       gins(ADATA, N, N);
+       p->from = ao;
+       p->from.offset = wp;
+       p->from.scale = wi;
+       p->to = ac;
+       p->to.offset = sval->len;
+       
+       p = pc;
+       ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
+       if(ao.type == D_STATIC)
+               p->from.type = D_STATIC;
+       text();
 }
 
 int
@@ -390,14 +478,12 @@ dstringptr(Sym *s, int off, char *str)
        p->from.offset = off;
        p->from.scale = widthptr;
 
+       datastring(str, strlen(str)+1, &p->to);
+       p->to.index = p->to.type;
        p->to.type = D_ADDR;
-       p->to.index = D_STATIC;
        p->to.etype = TINT32;
-       p->to.sym = symstringc;
-       p->to.offset = stringc;
        off += widthptr;
 
-       datastring(str, strlen(str)+1);
        return off;
 }
 
index cdf2e2f1f963ecfc0639da7a7519542fcfd24612..5b0da4cad2188351eaf6b3ee8eb1fefd09c2d5e7 100644 (file)
@@ -463,20 +463,6 @@ struct Sig
        Sig*    link;
 };
 
-typedef        struct  Pool Pool;
-struct Pool
-{
-       Strlit* sval;
-       Pool*   link;
-};
-
-EXTERN Pool*   poolist;
-EXTERN Pool*   poolast;
-EXTERN Sym*    symstringl;     // string literals
-EXTERN Sym*    symstringc;     // string characters
-EXTERN int32   stringl;        // size of string literals
-EXTERN int32   stringc;        // size of string characters
-
 typedef        struct  Io      Io;
 struct Io
 {
@@ -785,7 +771,6 @@ int brrev(int);
 void   setmaxarg(Type*);
 Sig*   lsort(Sig*, int(*)(Sig*, Sig*));
 int    dotoffset(Node*, int*, Node**);
-void   stringpool(Node*);
 void   tempname(Node*, Type*);
 
 int    Econv(Fmt*);
@@ -1029,7 +1014,6 @@ Plist*    newplist(void);
  *     obj.c
  */
 void   Bputdot(Biobuf *b);
-void   dumpfuncs(void);
 void   dumpglobls(void);
 void   dumpobj(void);
 void   ieeedtod(uint64 *ieee, double native);
@@ -1060,17 +1044,15 @@ int     isfat(Type*);
 void   clearfat(Node *n);
 void   cgen(Node*, Node*);
 void   gused(Node*);
-void   dumpstrings(void);
 void   dumpsignatures(void);
 void   dumpfuncs(void);
+void   dumpdata(void);
 void   ggloblnod(Node *nam, int32 width);
 void   ggloblsym(Sym *s, int32 width, int dupok);
 void   zfile(Biobuf *b, char *p, int n);
 void   zhist(Biobuf *b, int line, vlong offset);
 void   zname(Biobuf *b, Sym *s, int t);
-void   dumpstrings(void);
 void   nopout(Prog*);
-void   datastring(char *s, int len);
 int    dstringptr(Sym *s, int off, char *str);
 int    dsymptr(Sym *s, int off, Sym *x);
 int    duint16(Sym *s, int off, uint32 v);
index 6457bf12a2373c7cc216f662c9f3a700e86b890c..b84d91ba74db9ab0304b3030768d83c354d7c3e4 100644 (file)
@@ -66,9 +66,6 @@ main(int argc, char *argv[])
        lexinit();
        typeinit(LBASETYPE);
 
-       symstringl = lookup(".stringl");        // string literals (ptr to char and count)
-       symstringc = lookup(".stringc");        // string characters
-
        lineno = 1;
        block = 1;
        blockgen = 1;
index 037cd4d4822ee7f8d0e79abd5a809a160a794bb0..6c67b6dfa840142c882306e89acd01f78ae9dbda 100644 (file)
@@ -28,8 +28,8 @@ dumpobj(void)
        newplist();
 
        dumpglobls();
-       dumpstrings();
        dumpsignatures();
+       dumpdata();
        dumpfuncs();
 
        Bterm(bout);
@@ -483,42 +483,6 @@ dumpsignatures(void)
 //print("s=%S\n", s);
                dumpsigt(progt, ifacet, rcvrt, methodt, s);
        }
-
-       if(stringl > 0) {
-               stringl = rnd(stringl, maxround);
-               ggloblsym(symstringl, stringl, 0);
-               if(stringc == 0)
-                       stringc = 1;
-       }
-       if(stringc > 0) {
-               stringc = rnd(stringc, maxround);
-               ggloblsym(symstringc, stringc, 0);
-       }
-}
-
-void
-stringpool(Node *n)
-{
-       Pool *p;
-
-       if(n->op != OLITERAL || n->val.ctype != CTSTR) {
-               if(n->val.ctype == CTNIL)
-                       return;
-               fatal("stringpool: not string %N", n);
-       }
-
-       p = mal(sizeof(*p));
-
-       p->sval = n->val.u.sval;
-       p->link = nil;
-
-       if(poolist == nil)
-               poolist = p;
-       else
-               poolast->link = p;
-       poolast = p;
-
-       symstringl->offset += types[TSTRING]->width;
 }
 
 Sig*