mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
f0d44dbeaf
commit
a7c6d89166
5 changed files with 25 additions and 21 deletions
|
|
@ -1936,7 +1936,11 @@ twobitwritesymbol(Array *arr, Sym *sym)
|
||||||
break;
|
break;
|
||||||
for(j = 0; j < bv->n; j += 32) {
|
for(j = 0; j < bv->n; j += 32) {
|
||||||
word = bv->b[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
|
duint32(sym, 0, i); // number of bitmaps
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ dumpbv(BitVector *bv, uintptr offset)
|
||||||
uintptr i;
|
uintptr i;
|
||||||
|
|
||||||
for(i = 0; i < bv->n; i += BitsPerPointer) {
|
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 BitsDead:
|
||||||
case BitsScalar:
|
case BitsScalar:
|
||||||
break;
|
break;
|
||||||
|
|
@ -259,7 +259,7 @@ dumpbv(BitVector *bv, uintptr offset)
|
||||||
dumpint(offset + i / BitsPerPointer * PtrSize);
|
dumpint(offset + i / BitsPerPointer * PtrSize);
|
||||||
break;
|
break;
|
||||||
case BitsMultiWord:
|
case BitsMultiWord:
|
||||||
switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) {
|
switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) {
|
||||||
default:
|
default:
|
||||||
runtime·throw("unexpected garbage collection bits");
|
runtime·throw("unexpected garbage collection bits");
|
||||||
case BitsIface:
|
case BitsIface:
|
||||||
|
|
@ -813,9 +813,9 @@ dumpbvtypes(BitVector *bv, byte *base)
|
||||||
uintptr i;
|
uintptr i;
|
||||||
|
|
||||||
for(i = 0; i < bv->n; i += BitsPerPointer) {
|
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;
|
continue;
|
||||||
switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) {
|
switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) {
|
||||||
default:
|
default:
|
||||||
runtime·throw("unexpected garbage collection bits");
|
runtime·throw("unexpected garbage collection bits");
|
||||||
case BitsIface:
|
case BitsIface:
|
||||||
|
|
@ -860,5 +860,5 @@ makeheapobjbv(byte *p, uintptr size)
|
||||||
tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8));
|
tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8));
|
||||||
tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8);
|
tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8);
|
||||||
}
|
}
|
||||||
return (BitVector){i*BitsPerPointer, (uint32*)tmpbuf};
|
return (BitVector){i*BitsPerPointer, tmpbuf};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -589,14 +589,14 @@ bool runtime·freespecial(Special *s, void *p, uintptr size, bool freed);
|
||||||
struct BitVector
|
struct BitVector
|
||||||
{
|
{
|
||||||
int32 n; // # of bits
|
int32 n; // # of bits
|
||||||
uint32 *data;
|
uint8 *bytedata;
|
||||||
};
|
};
|
||||||
typedef struct StackMap StackMap;
|
typedef struct StackMap StackMap;
|
||||||
struct StackMap
|
struct StackMap
|
||||||
{
|
{
|
||||||
int32 n; // number of bitmaps
|
int32 n; // number of bitmaps
|
||||||
int32 nbit; // number of bits in each bitmap
|
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
|
// Returns pointer map data for the given stackmap index
|
||||||
// (the index is encoded in PCDATA_StackMapIndex).
|
// (the index is encoded in PCDATA_StackMapIndex).
|
||||||
|
|
|
||||||
|
|
@ -438,11 +438,11 @@ markroot(ParFor *desc, uint32 i)
|
||||||
// Note: if you add a case here, please also update heapdump.c:dumproots.
|
// Note: if you add a case here, please also update heapdump.c:dumproots.
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case RootData:
|
case RootData:
|
||||||
scanblock(runtime·data, runtime·edata - runtime·data, (byte*)runtime·gcdatamask.data);
|
scanblock(runtime·data, runtime·edata - runtime·data, runtime·gcdatamask.bytedata);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RootBss:
|
case RootBss:
|
||||||
scanblock(runtime·bss, runtime·ebss - runtime·bss, (byte*)runtime·gcbssmask.data);
|
scanblock(runtime·bss, runtime·ebss - runtime·bss, runtime·gcbssmask.bytedata);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RootFinalizers:
|
case RootFinalizers:
|
||||||
|
|
@ -610,7 +610,7 @@ runtime·stackmapdata(StackMap *stackmap, int32 n)
|
||||||
{
|
{
|
||||||
if(n < 0 || n >= stackmap->n)
|
if(n < 0 || n >= stackmap->n)
|
||||||
runtime·throw("stackmapdata: index out of range");
|
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.
|
// Scan a stack frame: local variables and function arguments/results.
|
||||||
|
|
@ -668,17 +668,17 @@ scanframe(Stkframe *frame, void *unused)
|
||||||
}
|
}
|
||||||
bv = runtime·stackmapdata(stackmap, pcdata);
|
bv = runtime·stackmapdata(stackmap, pcdata);
|
||||||
size = (bv.n * PtrSize) / BitsPerPointer;
|
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.
|
// Scan arguments.
|
||||||
// Use pointer information if known.
|
// Use pointer information if known.
|
||||||
if(frame->argmap != nil) {
|
if(frame->argmap != nil) {
|
||||||
bv = *frame->argmap;
|
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) {
|
} else if((stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps)) != nil) {
|
||||||
bv = runtime·stackmapdata(stackmap, pcdata);
|
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 {
|
} else {
|
||||||
if(Debug > 2)
|
if(Debug > 2)
|
||||||
runtime·printf("frame %s conservative args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
|
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");
|
runtime·throw("unrollglobgcprog: program does not end with insEnd");
|
||||||
if(mask[masksize] != 0xa1)
|
if(mask[masksize] != 0xa1)
|
||||||
runtime·throw("unrollglobgcprog: overflow");
|
runtime·throw("unrollglobgcprog: overflow");
|
||||||
return (BitVector){masksize*8, (uint32*)mask};
|
return (BitVector){masksize*8, mask};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1833,7 +1833,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len)
|
||||||
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
||||||
for(i = 0; i < n; i += PtrSize) {
|
for(i = 0; i < n; i += PtrSize) {
|
||||||
off = (p+i-runtime·data)/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;
|
(*mask)[i/PtrSize] = bits;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -1845,7 +1845,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len)
|
||||||
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
||||||
for(i = 0; i < n; i += PtrSize) {
|
for(i = 0; i < n; i += PtrSize) {
|
||||||
off = (p+i-runtime·bss)/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;
|
(*mask)[i/PtrSize] = bits;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -1895,7 +1895,7 @@ runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len)
|
||||||
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
*mask = runtime·mallocgc(*len, nil, FlagNoScan);
|
||||||
for(i = 0; i < n; i += PtrSize) {
|
for(i = 0; i < n; i += PtrSize) {
|
||||||
off = (p+i-(byte*)frame.varp+size)/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;
|
(*mask)[i/PtrSize] = bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -370,8 +370,8 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
|
||||||
num = bv->n / BitsPerPointer;
|
num = bv->n / BitsPerPointer;
|
||||||
for(i = 0; i < num; i++) {
|
for(i = 0; i < num; i++) {
|
||||||
if(StackDebug >= 4)
|
if(StackDebug >= 4)
|
||||||
runtime·printf(" %p:%s:%p\n", &scanp[i], mapnames[bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3], scanp[i]);
|
runtime·printf(" %p:%s:%p\n", &scanp[i], mapnames[bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3], scanp[i]);
|
||||||
switch(bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3) {
|
switch(bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3) {
|
||||||
case BitsDead:
|
case BitsDead:
|
||||||
if(runtime·debug.gcdead)
|
if(runtime·debug.gcdead)
|
||||||
scanp[i] = (byte*)PoisonStack;
|
scanp[i] = (byte*)PoisonStack;
|
||||||
|
|
@ -394,7 +394,7 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BitsMultiWord:
|
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:
|
default:
|
||||||
runtime·throw("unexpected garbage collection bits");
|
runtime·throw("unexpected garbage collection bits");
|
||||||
case BitsEface:
|
case BitsEface:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue