]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: add zeroing to enable precise stack accounting
authorRuss Cox <rsc@golang.org>
Fri, 24 Jan 2014 04:11:04 +0000 (23:11 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 24 Jan 2014 04:11:04 +0000 (23:11 -0500)
There is more zeroing than I would like right now -
temporaries used for the new map and channel runtime
calls need to be eliminated - but it will do for now.

This CL only has an effect if you are building with

        GOEXPERIMENT=precisestack ./all.bash

(or make.bash). It costs about 5% in the overall time
spent in all.bash. That number will come down before
we make it on by default, but this should be enough for
Keith to try using the precise maps for copying stacks.

amd64 only (and it's not really great generated code).

TBR=khr, iant
CC=golang-codereviews
https://golang.org/cl/56430043

src/cmd/6g/ggen.c
src/cmd/gc/plive.c
src/pkg/runtime/mgc0.c

index fa965470e4fe3b574aac704557207a7fe2427ade..2bdb12bdd08be825c4e343cfb0d922f240d09a9a 100644 (file)
@@ -9,10 +9,13 @@
 #include "gg.h"
 #include "opt.h"
 
+static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
+
 void
 defframe(Prog *ptxt)
 {
        uint32 frame;
+       Prog *p;
 
        // fill in argument size
        ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
@@ -21,6 +24,35 @@ defframe(Prog *ptxt)
        ptxt->to.offset <<= 32;
        frame = rnd(stksize+maxarg, widthptr);
        ptxt->to.offset |= frame;
+       
+       // insert code to contain ambiguously live variables
+       // so that garbage collector only sees initialized values
+       // when it looks for pointers.
+       p = ptxt;
+       if(stkzerosize > 0) {
+               p = appendpp(p, AMOVQ, D_CONST, 0, D_AX, 0);    
+               p = appendpp(p, AMOVQ, D_CONST, stkzerosize/widthptr, D_CX, 0); 
+               p = appendpp(p, ALEAQ, D_SP+D_INDIR, frame-stkzerosize, D_DI, 0);       
+               p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0);    
+               appendpp(p, ASTOSQ, D_NONE, 0, D_NONE, 0);      
+       }
+}
+
+static Prog*   
+appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)  
+{
+       Prog *q;
+       q = mal(sizeof(*q));    
+       clearp(q);      
+       q->as = as;     
+       q->lineno = p->lineno;  
+       q->from.type = ftype;   
+       q->from.offset = foffset;       
+       q->to.type = ttype;     
+       q->to.offset = toffset; 
+       q->link = p->link;      
+       p->link = q;    
+       return q;       
 }
 
 // Sweep the prog list to mark any used nodes.
@@ -990,14 +1022,13 @@ clearfat(Node *nl)
        if(debug['g'])
                dump("\nclearfat", nl);
 
+       gfatvardef(nl);
 
        w = nl->type->width;
        // Avoid taking the address for simple enough types.
        if(componentgen(N, nl))
                return;
 
-       gfatvardef(nl);
-
        c = w % 8;      // bytes
        q = w / 8;      // quads
 
index 27eac707e16743c8f22834ce3a3c885d0e9d0942..5c03eaad6ee3bc73bed58774e1dfcaddca9a6226 100644 (file)
@@ -1498,25 +1498,29 @@ livenessepilogue(Liveness *lv)
                        bvor(all, all, avarinit);
 
                        if(issafepoint(p)) {
-                               if(debuglive >= 3) {
-                                       // Diagnose ambiguously live variables (any &^ all).
-                                       // livein and liveout are dead here and used as temporaries.
+                               // Annotate ambiguously live variables so that they can
+                               // be zeroed at function entry.
+                               // livein and liveout are dead here and used as temporaries.
+                               // For now, only enabled when using GOEXPERIMENT=precisestack
+                               // during make.bash / all.bash.
+                               if(precisestack_enabled) {
                                        bvresetall(livein);
                                        bvandnot(liveout, any, all);
-                                       if(bvcmp(livein, liveout) != 0) {
+                                       if(!bvisempty(liveout)) {
                                                for(pos = 0; pos < liveout->n; pos++) {
-                                                       if(bvget(liveout, pos)) {
-                                                               n = *(Node**)arrayget(lv->vars, pos);
-                                                               if(!n->diag && strncmp(n->sym->name, "autotmp_", 8) != 0) {
-                                                                       n->diag = 1;
+                                                       bvset(all, pos); // silence future warnings in this block
+                                                       if(!bvget(liveout, pos))
+                                                               continue;
+                                                       n = *(Node**)arrayget(lv->vars, pos);
+                                                       if(!n->needzero) {
+                                                               n->needzero = 1;
+                                                               if(debuglive >= 3)
                                                                        warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
-                                                               }
                                                        }
-                                                       bvset(all, pos); // silence future warnings in this block
                                                }
                                        }
                                }
-
+       
                                // Allocate a bit vector for each class and facet of
                                // value we are tracking.
        
index 2c82fb3ac437e143002bf32e34138ceab77b0ff8..aa93bfbeda4673668aea7c11df9fa441ee4cc635 100644 (file)
@@ -1505,7 +1505,7 @@ scanframe(Stkframe *frame, void *wbufp)
        stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
        if(stackmap != nil) {
                bv = stackmapdata(stackmap, pcdata);
-               scanbitvector(frame->argp, bv, false, wbufp);
+               scanbitvector(frame->argp, bv, true, wbufp);
        } else
                enqueue1(wbufp, (Obj){frame->argp, frame->arglen, 0});
 }