mirror of
https://github.com/golang/go
synced 2024-11-19 13:04:45 -07:00
runtime: fix various contiguous bitmap assumptions
There are various places that assume the heap bitmap is contiguous and scan it sequentially. We're about to split up the heap bitmap. This commit modifies all of these except heapBitsSetType to use the heapBits abstractions so they can transparently switch to a discontiguous bitmap. Updates #10460. This is a step toward supporting sparse heaps. Change-Id: I2f3994a5785e4dccb66602fb3950bbd290d9392c Reviewed-on: https://go-review.googlesource.com/85882 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
29e9c4d4a4
commit
f61057c497
@ -88,6 +88,7 @@ const (
|
||||
|
||||
heapBitsShift = 1 // shift offset between successive bitPointer or bitScan entries
|
||||
heapBitmapScale = sys.PtrSize * (8 / 2) // number of data bytes described by one heap bitmap byte
|
||||
wordsPerBitmapByte = 8 / 2 // heap words described by one bitmap byte
|
||||
|
||||
// all scan/pointer bits in a byte
|
||||
bitScanAll = bitScan | bitScan<<heapBitsShift | bitScan<<(2*heapBitsShift) | bitScan<<(3*heapBitsShift)
|
||||
@ -460,6 +461,14 @@ func (h heapBits) forward(n uintptr) heapBits {
|
||||
return heapBits{addb(h.bitp, n/4), uint32(n%4) * heapBitsShift}
|
||||
}
|
||||
|
||||
// forwardOrBoundary is like forward, but stops at boundaries between
|
||||
// contiguous sections of the bitmap. It returns the number of words
|
||||
// advanced over, which will be <= n.
|
||||
func (h heapBits) forwardOrBoundary(n uintptr) (heapBits, uintptr) {
|
||||
// The bitmap is contiguous right now, so this is just forward.
|
||||
return h.forward(n), n
|
||||
}
|
||||
|
||||
// The caller can test morePointers and isPointer by &-ing with bitScan and bitPointer.
|
||||
// The result includes in its higher bits the bits for subsequent words
|
||||
// described by the same bitmap byte.
|
||||
@ -717,24 +726,29 @@ func (h heapBits) initSpan(s *mspan) {
|
||||
s.allocBits = newAllocBits(s.nelems)
|
||||
|
||||
// Clear bits corresponding to objects.
|
||||
if total%heapBitmapScale != 0 {
|
||||
nw := total / sys.PtrSize
|
||||
if nw%wordsPerBitmapByte != 0 {
|
||||
throw("initSpan: unaligned length")
|
||||
}
|
||||
if h.shift != 0 {
|
||||
throw("initSpan: unaligned base")
|
||||
}
|
||||
nbyte := total / heapBitmapScale
|
||||
for nw > 0 {
|
||||
hNext, anw := h.forwardOrBoundary(nw)
|
||||
nbyte := anw / wordsPerBitmapByte
|
||||
if sys.PtrSize == 8 && size == sys.PtrSize {
|
||||
bitp := h.bitp
|
||||
end := addb(bitp, nbyte)
|
||||
for bitp != end {
|
||||
for i := uintptr(0); i < nbyte; i++ {
|
||||
*bitp = bitPointerAll | bitScanAll
|
||||
bitp = add1(bitp)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
memclrNoHeapPointers(unsafe.Pointer(h.bitp), nbyte)
|
||||
}
|
||||
h = hNext
|
||||
nw -= anw
|
||||
}
|
||||
}
|
||||
|
||||
// initCheckmarkSpan initializes a span for being checkmarked.
|
||||
// It clears the checkmark bits, which are set to 1 in normal operation.
|
||||
@ -745,10 +759,9 @@ func (h heapBits) initCheckmarkSpan(size, n, total uintptr) {
|
||||
// Only possible on 64-bit system, since minimum size is 8.
|
||||
// Must clear type bit (checkmark bit) of every word.
|
||||
// The type bit is the lower of every two-bit pair.
|
||||
bitp := h.bitp
|
||||
for i := uintptr(0); i < n; i += 4 {
|
||||
*bitp &^= bitPointerAll
|
||||
bitp = add1(bitp)
|
||||
for i := uintptr(0); i < n; i += wordsPerBitmapByte {
|
||||
*h.bitp &^= bitPointerAll
|
||||
h = h.forward(wordsPerBitmapByte)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -769,10 +782,9 @@ func (h heapBits) clearCheckmarkSpan(size, n, total uintptr) {
|
||||
// Only possible on 64-bit system, since minimum size is 8.
|
||||
// Must clear type bit (checkmark bit) of every word.
|
||||
// The type bit is the lower of every two-bit pair.
|
||||
bitp := h.bitp
|
||||
for i := uintptr(0); i < n; i += 4 {
|
||||
*bitp |= bitPointerAll
|
||||
bitp = add1(bitp)
|
||||
for i := uintptr(0); i < n; i += wordsPerBitmapByte {
|
||||
*h.bitp |= bitPointerAll
|
||||
h = h.forward(wordsPerBitmapByte)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user