summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-10-07 11:06:51 -0400
committerRuss Cox <rsc@golang.org>2014-10-07 11:06:51 -0400
commit44ae5998770a185d1f8518b6917e1c094bc62a19 (patch)
tree272222847117acc2ce64d1a80d36777e72fb975b /src/cmd/gc
parent049be2f16a585e45be4d8fe17660a537934488ee (diff)
downloadgo-44ae5998770a185d1f8518b6917e1c094bc62a19.tar.gz
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 issue 8864. LGTM=r R=golang-codereviews, dvyukov, r CC=golang-codereviews, iant, khr, rlh https://codereview.appspot.com/155820043
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/reflect.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index 4892ab757..d0ebf6b48 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);