From a7c6d89166fd7bf6c9af6013cbfaa21971ba28f0 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 12 Sep 2014 07:36:23 -0400 Subject: [PATCH] runtime: tell the truth about BitVector type Dmitriy changed all the execution to interpret the BitVector as an array of bytes. Update the declaration and generation of the bitmaps to match, to avoid problems on big-endian machines. LGTM=khr R=khr CC=dvyukov, golang-codereviews https://golang.org/cl/140570044 --- src/cmd/gc/plive.c | 6 +++++- src/runtime/heapdump.c | 10 +++++----- src/runtime/malloc.h | 4 ++-- src/runtime/mgc0.c | 20 ++++++++++---------- src/runtime/stack.c | 6 +++--- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c index d2f384b2dd..0feb2c710a 100644 --- a/src/cmd/gc/plive.c +++ b/src/cmd/gc/plive.c @@ -1936,7 +1936,11 @@ twobitwritesymbol(Array *arr, Sym *sym) break; for(j = 0; j < bv->n; j += 32) { word = bv->b[j/32]; - off = duint32(sym, off, word); + // Runtime reads the bitmaps as byte arrays. Oblige. + off = duint8(sym, off, word); + off = duint8(sym, off, word>>8); + off = duint8(sym, off, word>>16); + off = duint8(sym, off, word>>24); } } duint32(sym, 0, i); // number of bitmaps diff --git a/src/runtime/heapdump.c b/src/runtime/heapdump.c index db2c552b72..3d7960aab0 100644 --- a/src/runtime/heapdump.c +++ b/src/runtime/heapdump.c @@ -250,7 +250,7 @@ dumpbv(BitVector *bv, uintptr offset) uintptr i; for(i = 0; i < bv->n; i += BitsPerPointer) { - switch(bv->data[i/32] >> i%32 & 3) { + switch(bv->bytedata[i/8] >> i%8 & 3) { case BitsDead: case BitsScalar: break; @@ -259,7 +259,7 @@ dumpbv(BitVector *bv, uintptr offset) dumpint(offset + i / BitsPerPointer * PtrSize); break; case BitsMultiWord: - switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) { + switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) { default: runtime·throw("unexpected garbage collection bits"); case BitsIface: @@ -813,9 +813,9 @@ dumpbvtypes(BitVector *bv, byte *base) uintptr i; for(i = 0; i < bv->n; i += BitsPerPointer) { - if((bv->data[i/32] >> i%32 & 3) != BitsMultiWord) + if((bv->bytedata[i/8] >> i%8 & 3) != BitsMultiWord) continue; - switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) { + switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) { default: runtime·throw("unexpected garbage collection bits"); case BitsIface: @@ -860,5 +860,5 @@ makeheapobjbv(byte *p, uintptr size) tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8)); tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8); } - return (BitVector){i*BitsPerPointer, (uint32*)tmpbuf}; + return (BitVector){i*BitsPerPointer, tmpbuf}; } diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h index b6856768db..60b87da78c 100644 --- a/src/runtime/malloc.h +++ b/src/runtime/malloc.h @@ -589,14 +589,14 @@ bool runtime·freespecial(Special *s, void *p, uintptr size, bool freed); struct BitVector { int32 n; // # of bits - uint32 *data; + uint8 *bytedata; }; typedef struct StackMap StackMap; struct StackMap { int32 n; // number of bitmaps int32 nbit; // number of bits in each bitmap - uint32 data[]; + uint8 bytedata[]; // bitmaps, each starting on a 32-bit boundary }; // Returns pointer map data for the given stackmap index // (the index is encoded in PCDATA_StackMapIndex). diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index af0b6285a3..4221aaab2f 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -438,11 +438,11 @@ markroot(ParFor *desc, uint32 i) // Note: if you add a case here, please also update heapdump.c:dumproots. switch(i) { case RootData: - scanblock(runtime·data, runtime·edata - runtime·data, (byte*)runtime·gcdatamask.data); + scanblock(runtime·data, runtime·edata - runtime·data, runtime·gcdatamask.bytedata); break; case RootBss: - scanblock(runtime·bss, runtime·ebss - runtime·bss, (byte*)runtime·gcbssmask.data); + scanblock(runtime·bss, runtime·ebss - runtime·bss, runtime·gcbssmask.bytedata); break; case RootFinalizers: @@ -610,7 +610,7 @@ runtime·stackmapdata(StackMap *stackmap, int32 n) { if(n < 0 || n >= stackmap->n) runtime·throw("stackmapdata: index out of range"); - return (BitVector){stackmap->nbit, stackmap->data + n*((stackmap->nbit+31)/32)}; + return (BitVector){stackmap->nbit, stackmap->bytedata + n*((stackmap->nbit+31)/32*4)}; } // Scan a stack frame: local variables and function arguments/results. @@ -668,17 +668,17 @@ scanframe(Stkframe *frame, void *unused) } bv = runtime·stackmapdata(stackmap, pcdata); size = (bv.n * PtrSize) / BitsPerPointer; - scanblock((byte*)(frame->varp - size), bv.n/BitsPerPointer*PtrSize, (byte*)bv.data); + scanblock((byte*)(frame->varp - size), bv.n/BitsPerPointer*PtrSize, bv.bytedata); } // Scan arguments. // Use pointer information if known. if(frame->argmap != nil) { bv = *frame->argmap; - scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, (byte*)bv.data); + scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, bv.bytedata); } else if((stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps)) != nil) { bv = runtime·stackmapdata(stackmap, pcdata); - scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, (byte*)bv.data); + scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, bv.bytedata); } else { if(Debug > 2) runtime·printf("frame %s conservative args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen); @@ -1642,7 +1642,7 @@ unrollglobgcprog(byte *prog, uintptr size) runtime·throw("unrollglobgcprog: program does not end with insEnd"); if(mask[masksize] != 0xa1) runtime·throw("unrollglobgcprog: overflow"); - return (BitVector){masksize*8, (uint32*)mask}; + return (BitVector){masksize*8, mask}; } void @@ -1833,7 +1833,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len) *mask = runtime·mallocgc(*len, nil, FlagNoScan); for(i = 0; i < n; i += PtrSize) { off = (p+i-runtime·data)/PtrSize; - bits = (((byte*)runtime·gcdatamask.data)[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask; + bits = (runtime·gcdatamask.bytedata[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask; (*mask)[i/PtrSize] = bits; } return; @@ -1845,7 +1845,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len) *mask = runtime·mallocgc(*len, nil, FlagNoScan); for(i = 0; i < n; i += PtrSize) { off = (p+i-runtime·bss)/PtrSize; - bits = (((byte*)runtime·gcbssmask.data)[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask; + bits = (runtime·gcbssmask.bytedata[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask; (*mask)[i/PtrSize] = bits; } return; @@ -1895,7 +1895,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len) *mask = runtime·mallocgc(*len, nil, FlagNoScan); for(i = 0; i < n; i += PtrSize) { off = (p+i-(byte*)frame.varp+size)/PtrSize; - bits = (bv.data[off*BitsPerPointer/32] >> ((off*BitsPerPointer)%32))&BitsMask; + bits = (bv.bytedata[off*BitsPerPointer/8] >> ((off*BitsPerPointer)%8))&BitsMask; (*mask)[i/PtrSize] = bits; } } diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 53ad90a5de..f29266eb6b 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -370,8 +370,8 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) num = bv->n / BitsPerPointer; for(i = 0; i < num; i++) { if(StackDebug >= 4) - runtime·printf(" %p:%s:%p\n", &scanp[i], mapnames[bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3], scanp[i]); - switch(bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3) { + runtime·printf(" %p:%s:%p\n", &scanp[i], mapnames[bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3], scanp[i]); + switch(bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3) { case BitsDead: if(runtime·debug.gcdead) scanp[i] = (byte*)PoisonStack; @@ -394,7 +394,7 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) } break; case BitsMultiWord: - switch(bv->data[(i+1) / (32 / BitsPerPointer)] >> ((i+1) * BitsPerPointer & 31) & 3) { + switch(bv->bytedata[(i+1) / (8 / BitsPerPointer)] >> ((i+1) * BitsPerPointer & 7) & 3) { default: runtime·throw("unexpected garbage collection bits"); case BitsEface: -- 2.48.1