From f61057c497e9ccb88dae093778d97aeee941af13 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 8 Dec 2017 22:24:59 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/mbitmap.go | 52 ++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go index 8e414ecaf3..e4f6b52b88 100644 --- a/src/runtime/mbitmap.go +++ b/src/runtime/mbitmap.go @@ -86,8 +86,9 @@ const ( bitPointer = 1 << 0 bitScan = 1 << 4 - 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 + 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< 0 { + hNext, anw := h.forwardOrBoundary(nw) + nbyte := anw / wordsPerBitmapByte + if sys.PtrSize == 8 && size == sys.PtrSize { + bitp := h.bitp + for i := uintptr(0); i < nbyte; i++ { + *bitp = bitPointerAll | bitScanAll + bitp = add1(bitp) + } + } else { + memclrNoHeapPointers(unsafe.Pointer(h.bitp), nbyte) } - return + h = hNext + nw -= anw } - memclrNoHeapPointers(unsafe.Pointer(h.bitp), nbyte) } // initCheckmarkSpan initializes a span for being checkmarked. @@ -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) } } }