]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: separate "has pointers" from "needs zeroing" in stack frame
authorRuss Cox <rsc@golang.org>
Sat, 17 Aug 2013 01:45:59 +0000 (21:45 -0400)
committerRuss Cox <rsc@golang.org>
Sat, 17 Aug 2013 01:45:59 +0000 (21:45 -0400)
When the new call site-specific frame bitmaps are available,
we can cut the zeroing to just those values that need it due
to scope escaping.

R=cshapiro, cshapiro
CC=golang-dev
https://golang.org/cl/13045043

src/cmd/5g/ggen.c
src/cmd/6g/ggen.c
src/cmd/8g/ggen.c
src/cmd/gc/go.h
src/cmd/gc/pgen.c

index 52c2cd4395fb5be4784137c4a48dd5b23d573bfe..f018c88aa87b4b3dfc9b38dcc8ebe5a88a851222 100644 (file)
@@ -35,11 +35,11 @@ defframe(Prog *ptxt, Bvec *bv)
        p = ptxt;
        while(p->link->as == AFUNCDATA || p->link->as == APCDATA || p->link->as == ATYPE)
                p = p->link;
-       if(stkptrsize >= 8*widthptr) {
+       if(stkzerosize >= 8*widthptr) {
                p = appendp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
-               p = appendp(p, AADD, D_CONST, NREG, 4+frame-stkptrsize, D_REG, 1, 0);
+               p = appendp(p, AADD, D_CONST, NREG, 4+frame-stkzerosize, D_REG, 1, 0);
                p->reg = REGSP;
-               p = appendp(p, AADD, D_CONST, NREG, stkptrsize, D_REG, 2, 0);
+               p = appendp(p, AADD, D_CONST, NREG, stkzerosize, D_REG, 2, 0);
                p->reg = 1;
                p1 = p = appendp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);
                p->scond |= C_PBIT;
@@ -49,13 +49,13 @@ defframe(Prog *ptxt, Bvec *bv)
                patch(p, p1);
        } else {
                first = 1;
-               for(i=0, j=0; i<stkptrsize; i+=widthptr, j+=2) {
+               for(i=0, j=(stkptrsize-stkzerosize)/widthptr*2; i<stkzerosize; i+=widthptr, j+=2) {
                        if(bvget(bv, j) || bvget(bv, j+1)) {
                                if(first) {
                                        p = appendp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
                                        first = 0;
                                }
-                               p = appendp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame-stkptrsize+i);
+                               p = appendp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame-stkzerosize+i);
                        }
                }
        }
index ec1d1ddc4cd3a4914afb47f7f5d5e0e57b8e9224..6e2f0fd69ebab05e50c4be96e7667798d4966ac2 100644 (file)
@@ -30,16 +30,16 @@ defframe(Prog *ptxt, Bvec *bv)
        // so that garbage collector only sees initialized values
        // when it looks for pointers.
        p = ptxt;
-       if(stkptrsize >= 8*widthptr) {
+       if(stkzerosize >= 8*widthptr) {
                p = appendp(p, AMOVQ, D_CONST, 0, D_AX, 0);
-               p = appendp(p, AMOVQ, D_CONST, stkptrsize/widthptr, D_CX, 0);
-               p = appendp(p, ALEAQ, D_SP+D_INDIR, frame-stkptrsize, D_DI, 0);
+               p = appendp(p, AMOVQ, D_CONST, stkzerosize/widthptr, D_CX, 0);
+               p = appendp(p, ALEAQ, D_SP+D_INDIR, frame-stkzerosize, D_DI, 0);
                p = appendp(p, AREP, D_NONE, 0, D_NONE, 0);
                appendp(p, ASTOSQ, D_NONE, 0, D_NONE, 0);
        } else {
-               for(i=0, j=0; i<stkptrsize; i+=widthptr, j+=2)
+               for(i=0, j=(stkptrsize-stkzerosize)/widthptr*2; i<stkzerosize; i+=widthptr, j+=2)
                        if(bvget(bv, j) || bvget(bv, j+1))
-                               p = appendp(p, AMOVQ, D_CONST, 0, D_SP+D_INDIR, frame-stkptrsize+i);
+                               p = appendp(p, AMOVQ, D_CONST, 0, D_SP+D_INDIR, frame-stkzerosize+i);
        }
 }
 
index 6b8c67e5bc876fd6fe4c5f09fa5cf436fc4a13a7..1f9e6e0593e435f2fd7ded79250822778ec454d0 100644 (file)
@@ -32,16 +32,16 @@ defframe(Prog *ptxt, Bvec *bv)
        // so that garbage collector only sees initialized values
        // when it looks for pointers.
        p = ptxt;
-       if(stkptrsize >= 8*widthptr) {
+       if(stkzerosize >= 8*widthptr) {
                p = appendp(p, AMOVL, D_CONST, 0, D_AX, 0);
-               p = appendp(p, AMOVL, D_CONST, stkptrsize/widthptr, D_CX, 0);
-               p = appendp(p, ALEAL, D_SP+D_INDIR, frame-stkptrsize, D_DI, 0);
+               p = appendp(p, AMOVL, D_CONST, stkzerosize/widthptr, D_CX, 0);
+               p = appendp(p, ALEAL, D_SP+D_INDIR, frame-stkzerosize, D_DI, 0);
                p = appendp(p, AREP, D_NONE, 0, D_NONE, 0);
                appendp(p, ASTOSL, D_NONE, 0, D_NONE, 0);
        } else {
-               for(i=0, j=0; i<stkptrsize; i+=widthptr, j+=2)
+               for(i=0, j=(stkptrsize-stkzerosize)/widthptr*2; i<stkzerosize; i+=widthptr, j+=2)
                        if(bvget(bv, j) || bvget(bv, j+1))
-                               p = appendp(p, AMOVL, D_CONST, 0, D_SP+D_INDIR, frame-stkptrsize+i);
+                               p = appendp(p, AMOVL, D_CONST, 0, D_SP+D_INDIR, frame-stkzerosize+i);
        }
 }
 
index c021e895efa3d8bcfa6eb4e51263bf339edafac5..9232650c287efd3ef67c8dc2e557fe0f80a41aec 100644 (file)
@@ -270,6 +270,7 @@ struct      Node
        uchar   dupok;  // duplicate definitions ok (for func)
        schar   likely; // likeliness of if statement
        uchar   hasbreak;       // has break statement
+       uchar   needzero; // if it contains pointers, needs to be zeroed on function entry
        uint    esc;            // EscXXX
        int     funcdepth;
 
@@ -940,7 +941,8 @@ EXTERN      NodeList*       lastconst;
 EXTERN Node*   lasttype;
 EXTERN vlong   maxarg;
 EXTERN vlong   stksize;                // stack size for current frame
-EXTERN vlong   stkptrsize;             // prefix of stack containing pointers for current frame
+EXTERN vlong   stkptrsize;             // prefix of stack containing pointers
+EXTERN vlong   stkzerosize;            // prefix of stack that must be zeroed on entry
 EXTERN int32   blockgen;               // max block number
 EXTERN int32   block;                  // current block number
 EXTERN int     hasdefer;               // flag that curfn has defer statetment
index edeaa06a693c21be3411f0947f63284c4864f6c6..f39163406785d7d66b860202b212876539bb0ea2 100644 (file)
@@ -367,11 +367,11 @@ dumpgclocals(Node* fn, Sym *sym)
 
 // Sort the list of stack variables. Autos after anything else,
 // within autos, unused after used, within used, things with
-// pointers first, and then decreasing size.
+// pointers first, zeroed things first, and then decreasing size.
 // Because autos are laid out in decreasing addresses
-// on the stack, pointers first and decreasing size
-// really means, in memory, pointers near the top of the 
-// stack and increasing in size.
+// on the stack, pointers first, zeroed things first and decreasing size
+// really means, in memory, things with pointers needing zeroing at
+// the top of the stack and increasing in size.
 // Non-autos sort on offset.
 static int
 cmpstackvar(Node *a, Node *b)
@@ -394,6 +394,12 @@ cmpstackvar(Node *a, Node *b)
        bp = haspointers(b->type);
        if(ap != bp)
                return bp - ap;
+
+       ap = a->needzero;
+       bp = b->needzero;
+       if(ap != bp)
+               return bp - ap;
+
        if(a->type->width < b->type->width)
                return +1;
        if(a->type->width > b->type->width)
@@ -409,11 +415,12 @@ allocauto(Prog* ptxt)
        Node* n;
        vlong w;
 
-       if(curfn->dcl == nil) {
-               stksize = 0;
-               stkptrsize = 0;
+       stksize = 0;
+       stkptrsize = 0;
+       stkzerosize = 0;
+
+       if(curfn->dcl == nil)
                return;
-       }
 
        // Mark the PAUTO's unused.
        for(ll=curfn->dcl; ll != nil; ll=ll->next)
@@ -421,6 +428,11 @@ allocauto(Prog* ptxt)
                        ll->n->used = 0;
 
        markautoused(ptxt);
+       
+       // TODO: Remove when liveness analysis sets needzero instead.
+       for(ll=curfn->dcl; ll != nil; ll=ll->next)
+               if (ll->n->class == PAUTO)
+                       ll->n->needzero = 1; // ll->n->addrtaken;
 
        listsort(&curfn->dcl, cmpstackvar);
 
@@ -430,8 +442,6 @@ allocauto(Prog* ptxt)
        if (n->class == PAUTO && n->op == ONAME && !n->used) {
                // No locals used at all
                curfn->dcl = nil;
-               stksize = 0;
-               stkptrsize = 0;
                fixautoused(ptxt);
                return;
        }
@@ -446,8 +456,6 @@ allocauto(Prog* ptxt)
        }
 
        // Reassign stack offsets of the locals that are still there.
-       stksize = 0;
-       stkptrsize = 0;
        for(ll = curfn->dcl; ll != nil; ll=ll->next) {
                n = ll->n;
                if (n->class != PAUTO || n->op != ONAME)
@@ -459,8 +467,11 @@ allocauto(Prog* ptxt)
                        fatal("bad width");
                stksize += w;
                stksize = rnd(stksize, n->type->align);
-               if(haspointers(n->type))
+               if(haspointers(n->type)) {
                        stkptrsize = stksize;
+                       if(n->needzero)
+                               stkzerosize = stksize;
+               }
                if(thechar == '5')
                        stksize = rnd(stksize, widthptr);
                if(stksize >= (1ULL<<31)) {
@@ -471,6 +482,7 @@ allocauto(Prog* ptxt)
        }
        stksize = rnd(stksize, widthptr);
        stkptrsize = rnd(stkptrsize, widthptr);
+       stkzerosize = rnd(stkzerosize, widthptr);
 
        fixautoused(ptxt);