]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cc, cmd/gc, runtime: Uniquely encode iface and eface pointers in the pointer...
authorCarl Shapiro <cshapiro@google.com>
Fri, 9 Aug 2013 23:48:12 +0000 (16:48 -0700)
committerCarl Shapiro <cshapiro@google.com>
Fri, 9 Aug 2013 23:48:12 +0000 (16:48 -0700)
Prior to this change, pointer maps encoded the disposition of
a word using a single bit.  A zero signaled a non-pointer
value and a one signaled a pointer value.  Interface values,
which are a effectively a union type, were conservatively
labeled as a pointer.

This change widens the logical element size of the pointer map
to two bits per word.  As before, zero signals a non-pointer
value and one signals a pointer value.  Additionally, a two
signals an iface pointer and a three signals an eface pointer.

Following other changes to the runtime, values two and three
will allow a type information to drive interpretation of the
subsequent word so only those interface values containing a
pointer value will be scanned.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/12689046

src/cmd/cc/pgen.c
src/cmd/gc/pgen.c
src/pkg/runtime/mgc0.c

index 4c6859a73364b5c5584e2740639c2cc61bdfb0c2..66075572b6917ab63469fece719d525f4b2eaa86 100644 (file)
@@ -31,6 +31,8 @@
 #include "gc.h"
 #include "../../pkg/runtime/funcdata.h"
 
+enum { BitsPerPointer = 2 };
+
 static void dumpgcargs(Type *fn, Sym *sym);
 
 int
@@ -674,7 +676,7 @@ walktype1(Type *t, int32 offset, Bvec *bv)
                // pointer types
                if((offset + t->offset) % ewidth[TIND] != 0)
                        yyerror("unaligned pointer");
-               bvset(bv, (offset + t->offset) / ewidth[TIND]);
+               bvset(bv, ((offset + t->offset) / ewidth[TIND])*BitsPerPointer);
                break;
 
        case TSTRUCT:
@@ -701,6 +703,7 @@ dumpgcargs(Type *fn, Sym *sym)
        Bvec *bv;
        Type *t;
        int32 i;
+       int32 argbytes;
        int32 symoffset, argoffset;
 
        if(hasdotdotdot()) {
@@ -709,7 +712,8 @@ dumpgcargs(Type *fn, Sym *sym)
                gextern(sym, nodconst(0), 0, 4); // nptrs=0
                symoffset = 4;
        } else {
-               bv = bvalloc((argsize() + ewidth[TIND] - 1) / ewidth[TIND]);
+               argbytes = (argsize() + ewidth[TIND] - 1);
+               bv = bvalloc((argbytes  / ewidth[TIND]) * BitsPerPointer);
                argoffset = align(0, fn->link, Aarg0, nil);
                if(argoffset > 0) {
                        // The C calling convention returns structs by
index 64b03b341f9190c3ae950e66155806e2ea792483..6595abce42005d42a59e9c873d95ea9dd2e08dc3 100644 (file)
@@ -8,6 +8,8 @@
 #include       "opt.h"
 #include       "../../pkg/runtime/funcdata.h"
 
+enum { BitsPerPointer = 2 };
+
 static void allocauto(Prog* p);
 static void dumpgcargs(Node*, Sym*);
 static void dumpgclocals(Node*, Sym*);
@@ -227,7 +229,7 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
        case TMAP:
                if(*xoffset % widthptr != 0)
                        fatal("walktype1: invalid alignment, %T", t);
-               bvset(bv, *xoffset / widthptr);
+               bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
                *xoffset += t->width;
                break;
 
@@ -235,7 +237,7 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
                // struct { byte *str; intgo len; }
                if(*xoffset % widthptr != 0)
                        fatal("walktype1: invalid alignment, %T", t);
-               bvset(bv, *xoffset / widthptr);
+               bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
                *xoffset += t->width;
                break;
 
@@ -245,8 +247,10 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
                // struct { Type* type; union { void* ptr, uintptr val } data; }
                if(*xoffset % widthptr != 0)
                        fatal("walktype1: invalid alignment, %T", t);
-               bvset(bv, *xoffset / widthptr);
-               bvset(bv, (*xoffset + widthptr) / widthptr);
+               bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1);
+               if(isnilinter(t))
+                       bvset(bv, ((*xoffset / widthptr) * BitsPerPointer));
+               bvset(bv, ((*xoffset + widthptr) / widthptr) * BitsPerPointer);
                *xoffset += t->width;
                break;
 
@@ -259,7 +263,7 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
                        // struct { byte* array; uintgo len; uintgo cap; }
                        if(*xoffset % widthptr != 0)
                                fatal("walktype1: invalid TARRAY alignment, %T", t);
-                       bvset(bv, *xoffset / widthptr);
+                       bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
                        *xoffset += t->width;
                } else if(!haspointers(t->type))
                                *xoffset += t->width;
@@ -309,7 +313,7 @@ dumpgcargs(Node *fn, Sym *sym)
        thistype = getthisx(fn->type);
        inargtype = getinargx(fn->type);
        outargtype = getoutargx(fn->type);
-       bv = bvalloc(fn->type->argwid / widthptr);
+       bv = bvalloc((fn->type->argwid / widthptr) * BitsPerPointer);
        if(thistype != nil)
                walktype(thistype, bv);
        if(inargtype != nil)
@@ -336,7 +340,7 @@ dumpgclocals(Node* fn, Sym *sym)
        int32 i;
        int off;
 
-       bv = bvalloc(stkptrsize / widthptr);
+       bv = bvalloc((stkptrsize / widthptr) * BitsPerPointer);
        for(ll = fn->dcl; ll != nil; ll = ll->next) {
                node = ll->n;
                if(node->class == PAUTO && node->op == ONAME) {
index 3c7df994751645b9a6721ca59a7d311fa08278a2..5c91388867f17896c4dc79b890f65d527a0fd1e5 100644 (file)
@@ -33,6 +33,9 @@ enum {
        PRECISE = 1,
        LOOP = 2,
        PC_BITS = PRECISE | LOOP,
+
+       // Pointer map
+       BitsPerPointer = 2,
 };
 
 // Bits in per-word bitmap.
@@ -1409,10 +1412,11 @@ scanbitvector(byte *scanp, BitVector *bv)
                        i = remptrs;
                else
                        i = 32;
+               i /= BitsPerPointer;
                for(; i > 0; i--) {
-                       if(w & 1)
+                       if(w & 3)
                                addroot((Obj){scanp, PtrSize, 0});
-                       w >>= 1;
+                       w >>= BitsPerPointer;
                        scanp += PtrSize;
                }
        }
@@ -1444,7 +1448,7 @@ addframeroots(Stkframe *frame, void*)
                } else if(locals->n > 0) {
                        // Locals bitmap information, scan just the
                        // pointers in locals.
-                       size = locals->n*PtrSize;
+                       size = (locals->n*PtrSize) / BitsPerPointer;
                        scanbitvector(frame->varp - size, locals);
                }
        }