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
This commit is contained in:
Russ Cox 2014-09-12 07:36:23 -04:00
parent f0d44dbeaf
commit a7c6d89166
5 changed files with 25 additions and 21 deletions

View file

@ -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

View file

@ -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};
}

View file

@ -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).

View file

@ -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;
}
}

View file

@ -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: