]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: allocate wbshadow at high address
authorRuss Cox <rsc@golang.org>
Wed, 31 Dec 2014 03:39:48 +0000 (22:39 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 6 Jan 2015 22:28:52 +0000 (22:28 +0000)
sysReserve doesn't actually reserve the full amount requested on
64-bit systems, because of problems with ulimit. Instead it checks
that it can get the first 64 kB and assumes it can grab the rest as
needed. This doesn't work well with the "let the kernel pick an address"
mode, so don't do that. Pick a high address instead.

Change-Id: I4de143a0e6fdeb467fa6ecf63dcd0c1c1618a31c
Reviewed-on: https://go-review.googlesource.com/2345
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/malloc1.go

index 7c2a4c2f270053a3de77dab77c9236199029295c..740541225c4cabbb55f2bdd0bda8fff831153978 100644 (file)
@@ -235,7 +235,7 @@ func wbshadowinit() {
        }
 
        var reserved bool
-       p1 := sysReserve(nil, mheap_.arena_end-mheap_.arena_start, &reserved)
+       p1 := sysReserveHigh(mheap_.arena_end-mheap_.arena_start, &reserved)
        if p1 == nil {
                throw("cannot map shadow heap")
        }
@@ -275,7 +275,7 @@ func wbshadowinit() {
        mheap_.data_start = start
        mheap_.data_end = end
        reserved = false
-       p1 = sysReserve(nil, end-start, &reserved)
+       p1 = sysReserveHigh(end-start, &reserved)
        if p1 == nil {
                throw("cannot map shadow data")
        }
@@ -286,6 +286,29 @@ func wbshadowinit() {
        mheap_.shadow_enabled = true
 }
 
+// sysReserveHigh reserves space somewhere high in the address space.
+// sysReserve doesn't actually reserve the full amount requested on
+// 64-bit systems, because of problems with ulimit. Instead it checks
+// that it can get the first 64 kB and assumes it can grab the rest as
+// needed. This doesn't work well with the "let the kernel pick an address"
+// mode, so don't do that. Pick a high address instead.
+func sysReserveHigh(n uintptr, reserved *bool) unsafe.Pointer {
+       if ptrSize == 4 {
+               return sysReserve(nil, n, reserved)
+       }
+
+       for i := 0; i <= 0x7f; i++ {
+               p := uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
+               *reserved = false
+               p = uintptr(sysReserve(unsafe.Pointer(p), n, reserved))
+               if p != 0 {
+                       return unsafe.Pointer(p)
+               }
+       }
+
+       return sysReserve(nil, n, reserved)
+}
+
 func mHeap_SysAlloc(h *mheap, n uintptr) unsafe.Pointer {
        if n > uintptr(h.arena_end)-uintptr(h.arena_used) {
                // We are in 32-bit mode, maybe we didn't use all possible address space yet.