diff options
-rw-r--r-- | src/runtime/mbitmap.go | 6 | ||||
-rw-r--r-- | src/runtime/stubs.go | 7 |
2 files changed, 12 insertions, 1 deletions
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go index 30ec5f1cc9..71efe33741 100644 --- a/src/runtime/mbitmap.go +++ b/src/runtime/mbitmap.go @@ -1912,7 +1912,11 @@ Run: // The bitmask starts at s.startAddr. // The result must be deallocated with dematerializeGCProg. func materializeGCProg(ptrdata uintptr, prog *byte) *mspan { - s := mheap_.allocManual((ptrdata/(8*sys.PtrSize)+pageSize-1)/pageSize, &memstats.gc_sys) + // Each word of ptrdata needs one bit in the bitmap. + bitmapBytes := divRoundUp(ptrdata, 8*sys.PtrSize) + // Compute the number of pages needed for bitmapBytes. + pages := divRoundUp(bitmapBytes, pageSize) + s := mheap_.allocManual(pages, &memstats.gc_sys) runGCProg(addb(prog, 4), nil, (*byte)(unsafe.Pointer(s.startAddr)), 1) return s } diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go index 26aaf2224d..8d1c698400 100644 --- a/src/runtime/stubs.go +++ b/src/runtime/stubs.go @@ -295,6 +295,13 @@ func round(n, a uintptr) uintptr { return (n + a - 1) &^ (a - 1) } +// divRoundUp returns ceil(n / a). +func divRoundUp(n, a uintptr) uintptr { + // a is generally a power of two. This will get inlined and + // the compiler will optimize the division. + return (n + a - 1) / a +} + // checkASM reports whether assembly runtime checks have passed. func checkASM() bool |