]> Cypherpunks repositories - gostls13.git/commitdiff
undo CL 13010045 / 04f8101b46dd
authorCarl Shapiro <cshapiro@google.com>
Wed, 21 Aug 2013 20:51:00 +0000 (13:51 -0700)
committerCarl Shapiro <cshapiro@google.com>
Wed, 21 Aug 2013 20:51:00 +0000 (13:51 -0700)
Update the original change but do not read interface types in
the arguments area.  Once the arguments area is zeroed as the
locals area is we can safely read interface type values there
too.

««« original CL description
undo CL 12785045 / 71ce80dc4195

This has broken the 32-bit builds.

««« original CL description
cmd/gc, runtime: use type information to scan interface values

R=golang-dev, rsc, dvyukov
CC=golang-dev
https://golang.org/cl/12785045
»»»

R=khr, golang-dev, khr
CC=golang-dev
https://golang.org/cl/13010045
»»»

R=khr, khr
CC=golang-dev
https://golang.org/cl/13073045

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

index f39163406785d7d66b860202b212876539bb0ea2..d649fc49daf805c9aaa6a0d2b6020ce7ce1c86b3 100644 (file)
@@ -257,7 +257,6 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
                bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1);
                if(isnilinter(t))
                        bvset(bv, ((*xoffset / widthptr) * BitsPerPointer));
-               bvset(bv, ((*xoffset + widthptr) / widthptr) * BitsPerPointer);
                *xoffset += t->width;
                break;
 
index 459a980b96f139ead4b537c12544f5b5f25a99c9..7b4c6a8ba14572fc625a21c48a4022af9954e2d6 100644 (file)
@@ -36,6 +36,10 @@ enum {
 
        // Pointer map
        BitsPerPointer = 2,
+       BitsNoPointer = 0,
+       BitsPointer = 1,
+       BitsIface = 2,
+       BitsEface = 3,
 };
 
 // Bits in per-word bitmap.
@@ -1398,26 +1402,52 @@ struct BitVector
        uint32 data[];
 };
 
+// Scans an interface data value when the interface type indicates
+// that it is a pointer.
+static void
+scaninterfacedata(uintptr bits, byte *scanp, bool afterprologue)
+{
+       Itab *tab;
+       Type *type;
+
+       if(afterprologue) {
+               if(bits == BitsIface) {
+                       tab = *(Itab**)scanp;
+                       if(tab->type->size <= sizeof(void*) && (tab->type->kind & KindNoPointers))
+                               return;
+               } else { // bits == BitsEface
+                       type = *(Type**)scanp;
+                       if(type->size <= sizeof(void*) && (type->kind & KindNoPointers))
+                               return;
+               }
+       }
+       addroot((Obj){scanp+PtrSize, PtrSize, 0});
+}
+
 // Starting from scanp, scans words corresponding to set bits.
 static void
-scanbitvector(byte *scanp, BitVector *bv)
+scanbitvector(byte *scanp, BitVector *bv, bool afterprologue)
 {
-       uint32 *wp;
-       uint32 w;
+       uintptr word, bits;
+       uint32 *wordp;
        int32 i, remptrs;
 
-       wp = bv->data;
+       wordp = bv->data;
        for(remptrs = bv->n; remptrs > 0; remptrs -= 32) {
-               w = *wp++;
+               word = *wordp++;
                if(remptrs < 32)
                        i = remptrs;
                else
                        i = 32;
                i /= BitsPerPointer;
                for(; i > 0; i--) {
-                       if(w & 3)
-                               addroot((Obj){scanp, PtrSize, 0});
-                       w >>= BitsPerPointer;
+                       bits = word & 3;
+                       if(bits != BitsNoPointer && *(void**)scanp != nil)
+                               if(bits == BitsPointer)
+                                       addroot((Obj){scanp, PtrSize, 0});
+                               else
+                                       scaninterfacedata(bits, scanp, afterprologue);
+                       word >>= BitsPerPointer;
                        scanp += PtrSize;
                }
        }
@@ -1430,12 +1460,14 @@ addframeroots(Stkframe *frame, void*)
        Func *f;
        BitVector *args, *locals;
        uintptr size;
+       bool afterprologue;
 
        f = frame->fn;
 
        // Scan local variables if stack frame has been allocated.
        // Use pointer information if known.
-       if(frame->varp > (byte*)frame->sp) {
+       afterprologue = (frame->varp > (byte*)frame->sp);
+       if(afterprologue) {
                locals = runtime·funcdata(f, FUNCDATA_GCLocals);
                if(locals == nil) {
                        // No locals information, scan everything.
@@ -1450,7 +1482,7 @@ addframeroots(Stkframe *frame, void*)
                        // Locals bitmap information, scan just the
                        // pointers in locals.
                        size = (locals->n*PtrSize) / BitsPerPointer;
-                       scanbitvector(frame->varp - size, locals);
+                       scanbitvector(frame->varp - size, locals, afterprologue);
                }
        }
 
@@ -1458,7 +1490,7 @@ addframeroots(Stkframe *frame, void*)
        // Use pointer information if known.
        args = runtime·funcdata(f, FUNCDATA_GCArgs);
        if(args != nil && args->n > 0)
-               scanbitvector(frame->argp, args);
+               scanbitvector(frame->argp, args, false);
        else
                addroot((Obj){frame->argp, frame->arglen, 0});
 }