runtime: adapt memory management to AIX mmap

On AIX:
    * mmap does not allow to map an already mapped range,
    * mmap range start at 0x30000000 for 32 bits processes,
    * mmap range start at 0x70000000_00000000 for 64 bits processes
    
    This is adapted from change 37845.
    
    Issue golang/go#19200
    
    Reviewed-on: https://go-review.googlesource.com/46772

From-SVN: r249713
This commit is contained in:
Ian Lance Taylor 2017-06-27 22:36:48 +00:00
parent f9dedc3f21
commit 7fd19291a5
4 changed files with 18 additions and 2 deletions

View File

@ -1,4 +1,4 @@
63b766d67098877496a4b79d7f41e731fbe8abc8 66d14d95a5a453682fe387319c80bc4fc40d96ad
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -291,6 +291,8 @@ func mallocinit() {
// allocation at 0x40 << 32 because when using 4k pages with 3-level // allocation at 0x40 << 32 because when using 4k pages with 3-level
// translation buffers, the user address space is limited to 39 bits // translation buffers, the user address space is limited to 39 bits
// On darwin/arm64, the address space is even smaller. // On darwin/arm64, the address space is even smaller.
// On AIX, mmap adresses range start at 0x07000000_00000000 for 64 bits
// processes.
arenaSize := round(_MaxMem, _PageSize) arenaSize := round(_MaxMem, _PageSize)
bitmapSize = arenaSize / (sys.PtrSize * 8 / 2) bitmapSize = arenaSize / (sys.PtrSize * 8 / 2)
spansSize = arenaSize / _PageSize * sys.PtrSize spansSize = arenaSize / _PageSize * sys.PtrSize
@ -301,12 +303,15 @@ func mallocinit() {
p = uintptr(i)<<40 | uintptrMask&(0x0013<<28) p = uintptr(i)<<40 | uintptrMask&(0x0013<<28)
case GOARCH == "arm64": case GOARCH == "arm64":
p = uintptr(i)<<40 | uintptrMask&(0x0040<<32) p = uintptr(i)<<40 | uintptrMask&(0x0040<<32)
case GOOS == "aix":
i = 1
p = uintptr(i)<<32 | uintptrMask&(0x70<<52)
default: default:
p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32) p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
} }
pSize = bitmapSize + spansSize + arenaSize + _PageSize pSize = bitmapSize + spansSize + arenaSize + _PageSize
p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved)) p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved))
if p != 0 { if p != 0 || GOOS == "aix" { // Useless to loop on AIX, as i is forced to 1
break break
} }
} }

View File

@ -270,6 +270,11 @@ func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
return return
} }
if GOOS == "aix" {
// AIX does not allow mapping a range that is already mapped.
// So always unmap first even if it is already unmapped.
munmap(v, n)
}
p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0) p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0)
if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM { if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM {
throw("runtime: out of memory") throw("runtime: out of memory")

View File

@ -139,6 +139,10 @@ uintptr getEnd(void)
uintptr uintptr
getEnd() getEnd()
{ {
#ifdef _AIX
// mmap adresses range start at 0x30000000 on AIX for 32 bits processes
uintptr end = 0x30000000U;
#else
uintptr end = 0; uintptr end = 0;
uintptr *pend; uintptr *pend;
@ -146,6 +150,8 @@ getEnd()
if (pend != nil) { if (pend != nil) {
end = *pend; end = *pend;
} }
#endif
return end; return end;
} }