// MapNextArenaHint reserves a page at the next arena growth hint,
// preventing the arena from growing there, and returns the range of
// addresses that are no longer viable.
-func MapNextArenaHint() (start, end uintptr) {
+//
+// This may fail to reserve memory. If it fails, it still returns the
+// address range it attempted to reserve.
+func MapNextArenaHint() (start, end uintptr, ok bool) {
hint := mheap_.arenaHints
addr := hint.addr
if hint.down {
} else {
start, end = addr, addr+heapArenaBytes
}
- sysReserve(unsafe.Pointer(addr), physPageSize)
+ got := sysReserve(unsafe.Pointer(addr), physPageSize)
+ ok = (addr == uintptr(got))
+ if !ok {
+ // We were unable to get the requested reservation.
+ // Release what we did get and fail.
+ sysFreeOS(got, physPageSize)
+ }
return
}
for i := 0; i < 5; i++ {
// Reserve memory at the next hint so it can't be used
// for the heap.
- start, end := MapNextArenaHint()
+ start, end, ok := MapNextArenaHint()
+ if !ok {
+ t.Skipf("failed to reserve memory at next arena hint [%#x, %#x)", start, end)
+ }
+ t.Logf("reserved [%#x, %#x)", start, end)
disallowed = append(disallowed, [2]uintptr{start, end})
// Allocate until the runtime tries to use the hint we
// just mapped over.