Commit 5042317d authored by Clément Chigot's avatar Clément Chigot Committed by Ian Lance Taylor

runtime: add arenaBaseOffset on aix/ppc64

On AIX, addresses returned by mmap are between 0x0a00000000000000
and 0x0afffffffffffff. The previous solution to handle these large
addresses was to increase the arena size up to 60 bits addresses,
cf CL 138736.

However, with the new page allocator, the 60bit heap addresses are
causing huge memory allocations, especially by (s *pageAlloc).init. mmap
and munmap syscalls dealing with these allocations are reducing
performances of every Go programs.

In order to avoid these allocations, arenaBaseOffset is set to
0x0a00000000000000 and heap addresses are on 48bit, as others operating
systems.

Updates: #35451

Change-Id: Ice916b8578f76703428ec12a82024147a7592bc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/206841
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: default avatarMichael Knyszek <mknyszek@google.com>
parent 72f333a1
...@@ -831,9 +831,13 @@ func FreePageAlloc(pp *PageAlloc) { ...@@ -831,9 +831,13 @@ func FreePageAlloc(pp *PageAlloc) {
// 64 bit and 32 bit platforms, allowing the tests to share code // 64 bit and 32 bit platforms, allowing the tests to share code
// between the two. // between the two.
// //
// On AIX, the arenaBaseOffset is 0x0a00000000000000. However, this
// constant can't be used here because it is negative and will cause
// a constant overflow.
//
// This should not be higher than 0x100*pallocChunkBytes to support // This should not be higher than 0x100*pallocChunkBytes to support
// mips and mipsle, which only have 31-bit address spaces. // mips and mipsle, which only have 31-bit address spaces.
var BaseChunkIdx = ChunkIdx(chunkIndex((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes)) var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + 0x0a00000000000000*sys.GoosAix))
// PageBase returns an address given a chunk index and a page index // PageBase returns an address given a chunk index and a page index
// relative to that chunk. // relative to that chunk.
......
...@@ -192,10 +192,6 @@ const ( ...@@ -192,10 +192,6 @@ const (
// exceed Go's 48 bit limit, it's extremely unlikely in // exceed Go's 48 bit limit, it's extremely unlikely in
// practice. // practice.
// //
// On aix/ppc64, the limits is increased to 1<<60 to accept addresses
// returned by mmap syscall. These are in range:
// 0x0a00000000000000 - 0x0afffffffffffff
//
// On 32-bit platforms, we accept the full 32-bit address // On 32-bit platforms, we accept the full 32-bit address
// space because doing so is cheap. // space because doing so is cheap.
// mips32 only has access to the low 2GB of virtual memory, so // mips32 only has access to the low 2GB of virtual memory, so
...@@ -210,7 +206,7 @@ const ( ...@@ -210,7 +206,7 @@ const (
// arenaBaseOffset to offset into the top 4 GiB. // arenaBaseOffset to offset into the top 4 GiB.
// //
// WebAssembly currently has a limit of 4GB linear memory. // WebAssembly currently has a limit of 4GB linear memory.
heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosAix)*(1-sys.GoosDarwin*sys.GoarchArm64))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 60*sys.GoosAix + 33*sys.GoosDarwin*sys.GoarchArm64 heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosDarwin*sys.GoarchArm64))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 33*sys.GoosDarwin*sys.GoarchArm64
// maxAlloc is the maximum size of an allocation. On 64-bit, // maxAlloc is the maximum size of an allocation. On 64-bit,
// it's theoretically possible to allocate 1<<heapAddrBits bytes. On // it's theoretically possible to allocate 1<<heapAddrBits bytes. On
...@@ -229,7 +225,6 @@ const ( ...@@ -229,7 +225,6 @@ const (
// Platform Addr bits Arena size L1 entries L2 entries // Platform Addr bits Arena size L1 entries L2 entries
// -------------- --------- ---------- ---------- ----------- // -------------- --------- ---------- ---------- -----------
// */64-bit 48 64MB 1 4M (32MB) // */64-bit 48 64MB 1 4M (32MB)
// aix/64-bit 60 256MB 4096 4M (32MB)
// windows/64-bit 48 4MB 64 1M (8MB) // windows/64-bit 48 4MB 64 1M (8MB)
// */32-bit 32 4MB 1 1024 (4KB) // */32-bit 32 4MB 1 1024 (4KB)
// */mips(le) 31 4MB 1 512 (2KB) // */mips(le) 31 4MB 1 512 (2KB)
...@@ -251,7 +246,7 @@ const ( ...@@ -251,7 +246,7 @@ const (
// logHeapArenaBytes is log_2 of heapArenaBytes. For clarity, // logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
// prefer using heapArenaBytes where possible (we need the // prefer using heapArenaBytes where possible (we need the
// constant to compute some other constants). // constant to compute some other constants).
logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoosAix)*(1-sys.GoarchWasm)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (8+20)*sys.GoosAix + (2+20)*sys.GoarchWasm logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoarchWasm)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (2+20)*sys.GoarchWasm
// heapArenaBitmapBytes is the size of each heap arena's bitmap. // heapArenaBitmapBytes is the size of each heap arena's bitmap.
heapArenaBitmapBytes = heapArenaBytes / (sys.PtrSize * 8 / 2) heapArenaBitmapBytes = heapArenaBytes / (sys.PtrSize * 8 / 2)
...@@ -271,10 +266,7 @@ const ( ...@@ -271,10 +266,7 @@ const (
// We use the L1 map on 64-bit Windows because the arena size // We use the L1 map on 64-bit Windows because the arena size
// is small, but the address space is still 48 bits, and // is small, but the address space is still 48 bits, and
// there's a high cost to having a large L2. // there's a high cost to having a large L2.
// arenaL1Bits = 6 * (_64bit * sys.GoosWindows)
// We use the L1 map on aix/ppc64 to keep the same L2 value
// as on Linux.
arenaL1Bits = 6*(_64bit*sys.GoosWindows) + 12*sys.GoosAix
// arenaL2Bits is the number of bits of the arena number // arenaL2Bits is the number of bits of the arena number
// covered by the second level arena index. // covered by the second level arena index.
...@@ -301,9 +293,15 @@ const ( ...@@ -301,9 +293,15 @@ const (
// bits. This offset lets us handle "negative" addresses (or // bits. This offset lets us handle "negative" addresses (or
// high addresses if viewed as unsigned). // high addresses if viewed as unsigned).
// //
// On aix/ppc64, this offset allows to keep the heapAddrBits to
// 48. Otherwize, it would be 60 in order to handle mmap addresses
// (in range 0x0a00000000000000 - 0x0afffffffffffff). But in this
// case, the memory reserved in (s *pageAlloc).init for chunks
// is causing important slowdowns.
//
// On other platforms, the user address space is contiguous // On other platforms, the user address space is contiguous
// and starts at 0, so no offset is necessary. // and starts at 0, so no offset is necessary.
arenaBaseOffset = sys.GoarchAmd64 * (1 << 47) arenaBaseOffset = sys.GoarchAmd64*(1<<47) + (^0x0a00000000000000+1)&uintptrMask*sys.GoosAix
// Max number of threads to run garbage collection. // Max number of threads to run garbage collection.
// 2, 3, and 4 are all plausible maximums depending // 2, 3, and 4 are all plausible maximums depending
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment