aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/runtime/mbitmap.go6
-rw-r--r--src/runtime/stubs.go7
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