]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: fix bucketOf to only look at ptrdata entries in gcdata
authorIan Lance Taylor <iant@golang.org>
Thu, 16 Feb 2017 22:20:24 +0000 (14:20 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 22 Feb 2017 02:19:48 +0000 (02:19 +0000)
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>
src/reflect/type.go

index 8df9e0ca6b5b72c0893f463da4d8714245e1a72a..c182d8c7da89e4836862c90f2b9c57b121aa8d97 100644 (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