diff options
author | Michael Anthony Knyszek <mknyszek@google.com> | 2020-05-12 16:08:50 +0000 |
---|---|---|
committer | Michael Knyszek <mknyszek@google.com> | 2020-05-14 16:20:19 +0000 |
commit | 796786cd0cc1ed71da65fe9f1760b390b189c5cd (patch) | |
tree | afc30d5e46518025a2596b2ac679b5bd24107c70 /src/runtime/mpagealloc.go | |
parent | 364a05e2feab48611bb5e4f26f47a02b9b49a988 (diff) | |
download | go-796786cd0cc1ed71da65fe9f1760b390b189c5cd.tar.gz go-796786cd0cc1ed71da65fe9f1760b390b189c5cd.zip |
runtime: make maxOffAddr reflect the actual address space upper bound
Currently maxOffAddr is defined in terms of the whole 64-bit address
space, assuming that it's all supported, by using ^uintptr(0) as the
maximal address in the offset space. In reality, the maximal address in
the offset space is (1<<heapAddrBits)-1 because we don't have more than
that actually available to us on a given platform.
On most platforms this is fine, because arenaBaseOffset is just
connecting two segments of address space, but on AIX we use it as an
actual offset for the starting address of the available address space,
which is limited. This means using ^uintptr(0) as the maximal address in
the offset address space causes wrap-around, especially when we just
want to represent a range approximately like [addr, infinity), which
today we do by using maxOffAddr.
To fix this, we define maxOffAddr more appropriately, in terms of
(1<<heapAddrBits)-1.
This change also redefines arenaBaseOffset to not be the negation of the
virtual address corresponding to address zero in the virtual address
space, but instead directly as the virtual address corresponding to
zero. This matches the existing documentation more closely and makes the
logic around arenaBaseOffset decidedly simpler, especially when trying
to reason about its use on AIX.
Fixes #38966.
Change-Id: I1336e5036a39de846f64cc2d253e8536dee57611
Reviewed-on: https://go-review.googlesource.com/c/go/+/233497
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/mpagealloc.go')
-rw-r--r-- | src/runtime/mpagealloc.go | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go index a28dd26cb5..60f7f9ff58 100644 --- a/src/runtime/mpagealloc.go +++ b/src/runtime/mpagealloc.go @@ -99,12 +99,12 @@ type chunkIdx uint // chunkIndex returns the global index of the palloc chunk containing the // pointer p. func chunkIndex(p uintptr) chunkIdx { - return chunkIdx((p + arenaBaseOffset) / pallocChunkBytes) + return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes) } // chunkIndex returns the base address of the palloc chunk at index ci. func chunkBase(ci chunkIdx) uintptr { - return uintptr(ci)*pallocChunkBytes - arenaBaseOffset + return uintptr(ci)*pallocChunkBytes + arenaBaseOffset } // chunkPageIndex computes the index of the page that contains p, @@ -136,13 +136,13 @@ func (i chunkIdx) l2() uint { // offAddrToLevelIndex converts an address in the offset address space // to the index into summary[level] containing addr. func offAddrToLevelIndex(level int, addr offAddr) int { - return int((addr.a + arenaBaseOffset) >> levelShift[level]) + return int((addr.a - arenaBaseOffset) >> levelShift[level]) } // levelIndexToOffAddr converts an index into summary[level] into // the corresponding address in the offset address space. func levelIndexToOffAddr(level, idx int) offAddr { - return offAddr{(uintptr(idx) << levelShift[level]) - arenaBaseOffset} + return offAddr{(uintptr(idx) << levelShift[level]) + arenaBaseOffset} } // addrsToSummaryRange converts base and limit pointers into a range @@ -159,8 +159,8 @@ func addrsToSummaryRange(level int, base, limit uintptr) (lo int, hi int) { // of a summary's max page count boundary for this level // (1 << levelLogPages[level]). So, make limit an inclusive upper bound // then shift, then add 1, so we get an exclusive upper bound at the end. - lo = int((base + arenaBaseOffset) >> levelShift[level]) - hi = int(((limit-1)+arenaBaseOffset)>>levelShift[level]) + 1 + lo = int((base - arenaBaseOffset) >> levelShift[level]) + hi = int(((limit-1)-arenaBaseOffset)>>levelShift[level]) + 1 return } |