runtime: adapt memory management to AIX mmap
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Jun 2017 22:36:48 +0000 (22:36 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Jun 2017 22:36:48 +0000 (22:36 +0000)
    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

gcc/go/gofrontend/MERGE
libgo/go/runtime/malloc.go
libgo/go/runtime/mem_gccgo.go
libgo/runtime/runtime_c.c

index 500ab5e2734a08112f20b5002ef096a64402e4d6..b52320bc4b072023f5a815900cbe16b78db72669 100644 (file)
@@ -1,4 +1,4 @@
-63b766d67098877496a4b79d7f41e731fbe8abc8
+66d14d95a5a453682fe387319c80bc4fc40d96ad
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 05a69c98aadde8786d004657edc8cb381cf560b5..3912fc2da58a4c006aa8a4e400398fb36dba07d3 100644 (file)
@@ -291,6 +291,8 @@ func mallocinit() {
                // allocation at 0x40 << 32 because when using 4k pages with 3-level
                // translation buffers, the user address space is limited to 39 bits
                // 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)
                bitmapSize = arenaSize / (sys.PtrSize * 8 / 2)
                spansSize = arenaSize / _PageSize * sys.PtrSize
@@ -301,12 +303,15 @@ func mallocinit() {
                                p = uintptr(i)<<40 | uintptrMask&(0x0013<<28)
                        case GOARCH == "arm64":
                                p = uintptr(i)<<40 | uintptrMask&(0x0040<<32)
+                       case GOOS == "aix":
+                               i = 1
+                               p = uintptr(i)<<32 | uintptrMask&(0x70<<52)
                        default:
                                p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
                        }
                        pSize = bitmapSize + spansSize + arenaSize + _PageSize
                        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
                        }
                }
index 161ff26b137efba24ae16b0e8c3d270978fcbb56..ea3e5ebab4eac3effee5cc85478208f9f680f684 100644 (file)
@@ -270,6 +270,11 @@ func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
                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)
        if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM {
                throw("runtime: out of memory")
index 336b2611324f50cd0a46f2ede930ee22e7fc3452..6da35210440501849265ac74b92cc9dd9564a3f8 100644 (file)
@@ -139,6 +139,10 @@ uintptr getEnd(void)
 uintptr
 getEnd()
 {
+#ifdef _AIX
+  // mmap adresses range start at 0x30000000 on AIX for 32 bits processes
+  uintptr end = 0x30000000U;
+#else
   uintptr end = 0;
   uintptr *pend;
 
@@ -146,6 +150,8 @@ getEnd()
   if (pend != nil) {
     end = *pend;
   }
+#endif
+
   return end;
 }