]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.9] runtime: fall back to small mmaps if we fail to grow reservation
authorAustin Clements <austin@google.com>
Fri, 28 Jul 2017 22:06:03 +0000 (18:06 -0400)
committerAustin Clements <austin@google.com>
Mon, 31 Jul 2017 17:45:59 +0000 (17:45 +0000)
Right now, if it's possible to grow the arena reservation but
mheap.sysAlloc fails to get 256MB more of memory, it simply fails.
However, on 32-bit we have a fallback path that uses much smaller
mmaps that could take in this situation, but fail to.

This commit fixes mheap.sysAlloc to use a common failure path in case
it can't grow the reservation. On 32-bit, this path includes the
fallback.

Ideally, mheap.sysAlloc would attempt smaller reservation growths
first, but taking the fallback path is a simple change for Go 1.9.

Updates #21044 (fixes one of two issues).

Cherry-pick of CL 51713. Updates #21234.

Change-Id: I1e0035ffba986c3551479d5742809e43da5e7c73
Reviewed-on: https://go-review.googlesource.com/52190
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/malloc.go

index 885065974834f15f634e9afcf5dc10311d84e05c..0ebd2c0ab2306afa4006c00dfac820b203e3fce9 100644 (file)
@@ -416,7 +416,10 @@ func (h *mheap) sysAlloc(n uintptr) unsafe.Pointer {
                        var reserved bool
                        p := uintptr(sysReserve(unsafe.Pointer(h.arena_end), p_size, &reserved))
                        if p == 0 {
-                               return nil
+                               // TODO: Try smaller reservation
+                               // growths in case we're in a crowded
+                               // 32-bit address space.
+                               goto reservationFailed
                        }
                        // p can be just about anywhere in the address
                        // space, including before arena_end.
@@ -476,6 +479,7 @@ func (h *mheap) sysAlloc(n uintptr) unsafe.Pointer {
                return unsafe.Pointer(p)
        }
 
+reservationFailed:
        // If using 64-bit, our reservation is all we have.
        if sys.PtrSize != 4 {
                return nil