diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/malloc.go | 24 | ||||
| -rw-r--r-- | src/runtime/mem_linux.go | 4 | ||||
| -rw-r--r-- | src/runtime/mgcscavenge.go | 8 | ||||
| -rw-r--r-- | src/runtime/mheap.go | 2 |
4 files changed, 29 insertions, 9 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 5a21e80e18..d768054198 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -325,12 +325,21 @@ const ( var physPageSize uintptr // physHugePageSize is the size in bytes of the OS's default physical huge -// page size whose allocation is opaque to the application. +// page size whose allocation is opaque to the application. It is assumed +// and verified to be a power of two. // // If set, this must be set by the OS init code (typically in osinit) before // mallocinit. However, setting it at all is optional, and leaving the default // value is always safe (though potentially less efficient). -var physHugePageSize uintptr +// +// Since physHugePageSize is always assumed to be a power of two, +// physHugePageShift is defined as physHugePageSize == 1 << physHugePageShift. +// The purpose of physHugePageShift is to avoid doing divisions in +// performance critical functions. +var ( + physHugePageSize uintptr + physHugePageShift uint +) // OS memory management abstraction layer // @@ -432,6 +441,17 @@ func mallocinit() { print("system page size (", physPageSize, ") must be a power of 2\n") throw("bad system page size") } + if physHugePageSize&(physHugePageSize-1) != 0 { + print("system huge page size (", physHugePageSize, ") must be a power of 2\n") + throw("bad system huge page size") + } + if physHugePageSize != 0 { + // Since physHugePageSize is a power of 2, it suffices to increase + // physHugePageShift until 1<<physHugePageShift == physHugePageSize. + for 1<<physHugePageShift != physHugePageSize { + physHugePageShift++ + } + } // Initialize the heap. mheap_.init() diff --git a/src/runtime/mem_linux.go b/src/runtime/mem_linux.go index cda2c78eaf..524915fb31 100644 --- a/src/runtime/mem_linux.go +++ b/src/runtime/mem_linux.go @@ -68,11 +68,11 @@ func sysUnused(v unsafe.Pointer, n uintptr) { // flag on the huge pages containing v and v+n-1, and // only if those aren't aligned. var head, tail uintptr - if uintptr(v)%physHugePageSize != 0 { + if uintptr(v)&(physHugePageSize-1) != 0 { // Compute huge page containing v. head = uintptr(v) &^ (physHugePageSize - 1) } - if (uintptr(v)+n)%physHugePageSize != 0 { + if (uintptr(v)+n)&(physHugePageSize-1) != 0 { // Compute huge page containing v+n-1. tail = (uintptr(v) + n - 1) &^ (physHugePageSize - 1) } diff --git a/src/runtime/mgcscavenge.go b/src/runtime/mgcscavenge.go index 151c84e996..45a9eb2b2a 100644 --- a/src/runtime/mgcscavenge.go +++ b/src/runtime/mgcscavenge.go @@ -130,7 +130,7 @@ func gcPaceScavenger() { if physHugePageSize != 0 { // Start by computing the amount of free memory we have in huge pages // in total. Trivially, this is all the huge page work we need to do. - hugeWork := uint64(mheap_.free.unscavHugePages * physHugePageSize) + hugeWork := uint64(mheap_.free.unscavHugePages) << physHugePageShift // ...but it could turn out that there's more huge work to do than // total work, so cap it at total work. This might happen for very large @@ -138,14 +138,14 @@ func gcPaceScavenger() { // that there are free chunks of memory larger than a huge page that we don't want // to scavenge. if hugeWork >= totalWork { - hugePages := totalWork / uint64(physHugePageSize) - hugeWork = hugePages * uint64(physHugePageSize) + hugePages := totalWork >> physHugePageShift + hugeWork = hugePages << physHugePageShift } // Everything that's not huge work is regular work. At this point we // know huge work so we can calculate how much time that will take // based on scavengePageRate (which applies to pages of any size). regularWork = totalWork - hugeWork - hugeTime = hugeWork / uint64(physHugePageSize) * scavengeHugePagePeriod + hugeTime = (hugeWork >> physHugePageShift) * scavengeHugePagePeriod } // Finally, we can compute how much time it'll take to do the regular work // and the total time to do all the work. diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go index af2818a2bd..91ad47bdd0 100644 --- a/src/runtime/mheap.go +++ b/src/runtime/mheap.go @@ -561,7 +561,7 @@ func (s *mspan) hugePages() uintptr { end &^= physHugePageSize - 1 } if start < end { - return (end - start) / physHugePageSize + return (end - start) >> physHugePageShift } return 0 } |
