]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: tell the truth about BitVector type
authorRuss Cox <rsc@golang.org>
Fri, 12 Sep 2014 11:36:23 +0000 (07:36 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 12 Sep 2014 11:36:23 +0000 (07:36 -0400)
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
src/runtime/heapdump.c
src/runtime/malloc.h
src/runtime/mgc0.c
src/runtime/stack.c

index d2f384b2dd41472c4fc5159a940ce9f775790da7..0feb2c710ac439dc736cdaa820bdb7c019a92821 100644 (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
index db2c552b72c2e433a926e1e1b8e439ee800f8796..3d7960aab0acbbedfc913524ed6411ae2b3227f5 100644 (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};
 }
index b6856768db12356b7e1446f9342d1aa1a8ca284f..60b87da78c14759e74062eb35836936ab802f722 100644 (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).
index af0b6285a3041fc52f9294d9028ef8585fe6a9e5..4221aaab2fc9eef02550f14eb2f287a8f5cc115e 100644 (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;
                }
        }
index 53ad90a5debeb735edcf5a965038c15bc7075c0c..f29266eb6beba0a8ce44b0e0044c23adc3f9b525 100644 (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: