1
0
mirror of https://github.com/golang/go synced 2024-11-23 23:30:10 -07:00

runtime: simplify heapBitsSetType doubleCheck

The heapBitsSetType function has a slow doubleCheck debugging mode
that checks the bitmap written out by the rest of the function using
far more obvious logic. But even this has some surprisingly complex
logic in it. Simplify it a bit. This also happens to fix the logic on
32-bit.

Fixes #40335.

Change-Id: I5cee482ad8adbd01cf5b98e35a270fe941ba4940
Reviewed-on: https://go-review.googlesource.com/c/go/+/244538
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Austin Clements 2020-06-05 16:44:29 -04:00
parent 7bbd5ca5a6
commit 7148abc1b9

View File

@ -1403,17 +1403,20 @@ Phase4:
// Double check the whole bitmap. // Double check the whole bitmap.
if doubleCheck { if doubleCheck {
// x+size may not point to the heap, so back up one // x+size may not point to the heap, so back up one
// word and then call next(). // word and then advance it the way we do above.
end := heapBitsForAddr(x + size - sys.PtrSize).next() end := heapBitsForAddr(x + size - sys.PtrSize)
endAI := arenaIdx(end.arena) if outOfPlace {
if !outOfPlace && (end.bitp == nil || (end.shift == 0 && end.bitp == &mheap_.arenas[endAI.l1()][endAI.l2()].bitmap[0])) { // In out-of-place copying, we just advance
// The unrolling code above walks hbitp just // using next.
// past the bitmap without moving to the next end = end.next()
// arena. Synthesize this for end.bitp. } else {
end.arena-- // Don't use next because that may advance to
endAI = arenaIdx(end.arena) // the next arena and the in-place logic
end.bitp = addb(&mheap_.arenas[endAI.l1()][endAI.l2()].bitmap[0], heapArenaBitmapBytes) // doesn't do that.
end.last = nil end.shift += heapBitsShift
if end.shift == 4*heapBitsShift {
end.bitp, end.shift = add1(end.bitp), 0
}
} }
if typ.kind&kindGCProg == 0 && (hbitp != end.bitp || (w == nw+2) != (end.shift == 2)) { if typ.kind&kindGCProg == 0 && (hbitp != end.bitp || (w == nw+2) != (end.shift == 2)) {
println("ended at wrong bitmap byte for", typ.string(), "x", dataSize/typ.size) println("ended at wrong bitmap byte for", typ.string(), "x", dataSize/typ.size)
@ -1437,8 +1440,9 @@ Phase4:
var have, want uint8 var have, want uint8
have = (*h.bitp >> h.shift) & (bitPointer | bitScan) have = (*h.bitp >> h.shift) & (bitPointer | bitScan)
if i >= totalptr { if i >= totalptr {
want = 0 // deadmarker
if typ.kind&kindGCProg != 0 && i < (totalptr+3)/4*4 { if typ.kind&kindGCProg != 0 && i < (totalptr+3)/4*4 {
// heapBitsSetTypeGCProg always fills
// in full nibbles of bitScan.
want = bitScan want = bitScan
} }
} else { } else {