From: Russ Cox Date: Tue, 7 Oct 2014 15:06:51 +0000 (-0400) Subject: runtime: remove type-punning for Type.gc[0], gc[1] X-Git-Tag: go1.4beta1~176 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=18172c42ff48611df564e5af8bf00515bbac612a;p=gostls13.git runtime: remove type-punning for Type.gc[0], gc[1] Depending on flags&KindGCProg, gc[0] and gc[1] are either pointers or inlined bitmap bits. That's not compatible with a precise garbage collector: it needs to be always pointers or never pointers. Change the inlined bitmap case to store a pointer to an out-of-line bitmap in gc[0]. The out-of-line bitmaps are dedup'ed, so that for example all pointer types share the same out-of-line bitmap. Fixes #8864. LGTM=r R=golang-codereviews, dvyukov, r CC=golang-codereviews, iant, khr, rlh https://golang.org/cl/155820043 --- diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index 4892ab7570..d0ebf6b481 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -716,9 +716,10 @@ static int dcommontype(Sym *s, int ot, Type *t) { int i, alg, sizeofAlg, gcprog; - Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1; + Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1, *sbits; uint8 gcmask[16]; static Sym *algarray; + uint64 x1, x2; char *p; if(ot != 0) @@ -804,8 +805,26 @@ dcommontype(Sym *s, int ot, Type *t) ot = dsymptr(s, ot, gcprog1, 0); } else { gengcmask(t, gcmask); - for(i = 0; i < 2*widthptr; i++) - ot = duint8(s, ot, gcmask[i]); + x1 = 0; + for(i=0; i<8; i++) + x1 = x1<<8 | gcmask[i]; + if(widthptr == 4) { + p = smprint("gcbits.%#016x", x1); + } else { + x2 = 0; + for(i=0; i<8; i++) + x2 = x2<<8 | gcmask[i+8]; + p = smprint("gcbits.%#016llux%016llux", x1, x2); + } + sbits = pkglookup(p, runtimepkg); + if((sbits->flags & SymUniq) == 0) { + sbits->flags |= SymUniq; + for(i = 0; i < 2*widthptr; i++) + duint8(sbits, i, gcmask[i]); + ggloblsym(sbits, 2*widthptr, DUPOK|RODATA); + } + ot = dsymptr(s, ot, sbits, 0); + ot = duintptr(s, ot, 0); } p = smprint("%-uT", t); //print("dcommontype: %s\n", p); diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c index c530669425..037263dce7 100644 --- a/src/cmd/ld/decodesym.c +++ b/src/cmd/ld/decodesym.c @@ -111,7 +111,10 @@ decodetype_gcprog(LSym *s) uint8* decodetype_gcmask(LSym *s) { - return (uint8*)(s->p + 1*PtrSize + 8 + 1*PtrSize); + LSym *mask; + + mask = decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize); + return mask->p; } // Type.ArrayType.elem and Type.SliceType.Elem diff --git a/src/reflect/type.go b/src/reflect/type.go index f099546d27..a36c0ba604 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1523,8 +1523,8 @@ func (gc *gcProg) appendProg(t *rtype) { // The program is stored in t.gc[0], skip unroll flag. prog = (*[1 << 30]byte)(unsafe.Pointer(t.gc[0]))[1:] } else { - // The mask is embed directly in t.gc. - prog = (*[1 << 30]byte)(unsafe.Pointer(&t.gc[0]))[:] + // The mask is linked directly in t.gc. + prog = (*[2 * ptrSize]byte)(unsafe.Pointer(t.gc[0]))[:] } for i := uintptr(0); i < nptr; i++ { gc.appendWord(extractGCWord(prog, i)) diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 99d14e3145..9b4264f2b3 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -270,7 +270,7 @@ func mallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer { } ptrmask = (*uint8)(add(unsafe.Pointer(ptrmask), 1)) // skip the unroll flag byte } else { - ptrmask = (*uint8)(unsafe.Pointer(&typ.gc[0])) // embed mask + ptrmask = (*uint8)(unsafe.Pointer(typ.gc[0])) // pointer to unrolled mask } if size == 2*ptrSize { *xbits = *ptrmask | bitBoundary diff --git a/src/runtime/type.h b/src/runtime/type.h index de82e886f2..f5b4f9d13f 100644 --- a/src/runtime/type.h +++ b/src/runtime/type.h @@ -23,7 +23,7 @@ struct Type uint8 kind; void* alg; // gc stores type info required for garbage collector. - // If (kind&KindGCProg)==0, then gc directly contains sparse GC bitmap + // If (kind&KindGCProg)==0, then gc[0] points at sparse GC bitmap // (no indirection), 4 bits per word. // If (kind&KindGCProg)!=0, then gc[1] points to a compiler-generated // read-only GC program; and gc[0] points to BSS space for sparse GC bitmap.