1
0
mirror of https://github.com/golang/go synced 2024-09-30 19:38:33 -06:00

reflect: fix bucketOf to only look at ptrdata entries in gcdata

The gcdata field only records ptrdata entries, not size entries.

Also fix an obsolete comment: the enforced limit on pointer maps is
now 2048 bytes, not 16 bytes.

I wasn't able to contruct a test case for this. It would require
building a type whose size is greater than 64 bytes but less than 128
bytes, with at least one pointer in first 64 bytes but no pointers
after the first 64 bytes, such that the linker arranges for the one
byte gcbits value to be immediately followed by a non-zero byte.

Change-Id: I9118d3e4ec6f07fd18b72f621c1e5f4fdfe5f80b
Reviewed-on: https://go-review.googlesource.com/37142
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
Ian Lance Taylor 2017-02-16 14:20:24 -08:00
parent db6e27c38d
commit b5e5194306

View File

@ -2205,9 +2205,6 @@ func bucketOf(ktyp, etyp *rtype) *rtype {
// Prepare GC data if any.
// A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+2*ptrSize bytes,
// or 2072 bytes, or 259 pointer-size words, or 33 bytes of pointer bitmap.
// Normally the enforced limit on pointer maps is 16 bytes,
// but larger ones are acceptable, 33 bytes isn't too too big,
// and it's easier to generate a pointer bitmap than a GC program.
// Note that since the key and value are known to be <= 128 bytes,
// they're guaranteed to have bitmaps instead of GC programs.
var gcdata *byte
@ -2234,7 +2231,7 @@ func bucketOf(ktyp, etyp *rtype) *rtype {
panic("reflect: unexpected GC program in MapOf")
}
kmask := (*[16]byte)(unsafe.Pointer(ktyp.gcdata))
for i := uintptr(0); i < ktyp.size/ptrSize; i++ {
for i := uintptr(0); i < ktyp.ptrdata/ptrSize; i++ {
if (kmask[i/8]>>(i%8))&1 != 0 {
for j := uintptr(0); j < bucketSize; j++ {
word := base + j*ktyp.size/ptrSize + i
@ -2250,7 +2247,7 @@ func bucketOf(ktyp, etyp *rtype) *rtype {
panic("reflect: unexpected GC program in MapOf")
}
emask := (*[16]byte)(unsafe.Pointer(etyp.gcdata))
for i := uintptr(0); i < etyp.size/ptrSize; i++ {
for i := uintptr(0); i < etyp.ptrdata/ptrSize; i++ {
if (emask[i/8]>>(i%8))&1 != 0 {
for j := uintptr(0); j < bucketSize; j++ {
word := base + j*etyp.size/ptrSize + i