Source File
mpagealloc.go
Belonging Package
runtime
package runtime
import (
)
var maxSearchAddr = maxOffAddr
func ( uintptr) chunkIdx {
return chunkIdx(( - arenaBaseOffset) / pallocChunkBytes)
}
func ( chunkIdx) uintptr {
return uintptr()*pallocChunkBytes + arenaBaseOffset
}
func ( uintptr) uint {
return uint( % pallocChunkBytes / pageSize)
}
return 0
} else {
return uint() >> pallocChunksL1Shift
}
}
func ( chunkIdx) () uint {
if pallocChunksL1Bits == 0 {
return uint()
} else {
return uint() & (1<<pallocChunksL2Bits - 1)
}
}
func ( int, offAddr) int {
return int((.a - arenaBaseOffset) >> levelShift[])
}
func (, int) offAddr {
return offAddr{(uintptr() << levelShift[]) + arenaBaseOffset}
}
= int(( - arenaBaseOffset) >> levelShift[])
= int(((-1)-arenaBaseOffset)>>levelShift[]) + 1
return
}
chunks [1 << pallocChunksL1Bits]*[1 << pallocChunksL2Bits]pallocData
inUse addrRanges
gen uint32
reservationBytes uintptr
released uintptr
scavLWM offAddr
freeHWM offAddr
}
test bool
}
func ( *pageAlloc) ( *mutex, *sysMemStat) {
print("runtime: root level max pages = ", 1<<levelLogPages[0], "\n")
print("runtime: summary max pages = ", maxPackedValue, "\n")
throw("root level max pages doesn't fit in summary")
}
.sysStat =
.sysInit()
.mheapLock =
.scav.scavLWM = maxSearchAddr
}
func ( *pageAlloc) (, uintptr) {
assertLockHeld(.mheapLock)
:= alignUp(+, pallocChunkBytes)
= alignDown(, pallocChunkBytes)
.sysGrow(, )
:= .start == 0
, := chunkIndex(), chunkIndex()
if || < .start {
.start =
}
if > .end {
.end =
.inUse.add(makeAddrRange(, ))
if := (offAddr{}); .lessThan(.searchAddr) {
.searchAddr =
}
for := chunkIndex(); < chunkIndex(); ++ {
func ( *pageAlloc) (, uintptr, , bool) {
assertLockHeld(.mheapLock)
:= + *pageSize - 1
, := chunkIndex(), chunkIndex()
for := range {
[] = 0
}
} else {
for := range {
[] = freeChunkSum
}
}
:= true
= false
:= levelBits[+1]
:= levelLogPages[+1]
, := addrsToSummaryRange(, , +1)
for := ; < ; ++ {
:= .summary[+1][<< : (+1)<<]
:= mergeSummaries(, )
:= .summary[][]
if != {
= true
.summary[][] =
}
}
}
}
func ( *pageAlloc) (, uintptr) uintptr {
assertLockHeld(.mheapLock)
:= + *pageSize - 1
, := chunkIndex(), chunkIndex()
, := chunkPageIndex(), chunkPageIndex()
:= uint(0)
:= .chunkOf()
+= .scavenged.popcntRange(, +1-)
.allocRange(, +1-)
:= .chunkOf()
+= .scavenged.popcntRange(, pallocChunkPages-)
.allocRange(, pallocChunkPages-)
for := + 1; < ; ++ {
:= .chunkOf()
+= .scavenged.popcntRange(0, pallocChunkPages)
.allocAll()
}
= .chunkOf()
+= .scavenged.popcntRange(0, +1)
.allocRange(0, +1)
}
.update(, , true, true)
return uintptr() * pageSize
}
func ( *pageAlloc) ( offAddr) offAddr {
assertLockHeld(.mheapLock)
return maxOffAddr
}
}
return
}
:= 0
:= struct {
, offAddr
}{
: minOffAddr,
: maxOffAddr,
. =
. = .add( - 1)
:= packPallocSum(0, 0, 0)
:= -1
:
:= 1 << levelBits[]
:= levelLogPages[]
<<= levelBits[]
:= .summary[][ : +]
:= 0
if := offAddrToLevelIndex(, .searchAddr); &^(-1) == {
= & ( - 1)
}
= 0
continue
}
(levelIndexToOffAddr(, +), (uintptr(1)<<)*pageSize)
:= .start()
if == 0 {
= uint() <<
+=
break
}
+=
=
=
continue
}
+= 1 <<
}
:= levelIndexToOffAddr(, ).add(uintptr() * pageSize).addr()
return , .findMappedAddr(.)
}
return 0, maxSearchAddr
}
print("runtime: summary[", -1, "][", , "] = ", .start(), ", ", .max(), ", ", .end(), "\n")
print("runtime: level = ", , ", npages = ", , ", j0 = ", , "\n")
print("runtime: p.searchAddr = ", hex(.searchAddr.addr()), ", i = ", , "\n")
print("runtime: levelShift[level] = ", levelShift[], ", levelBits[level] = ", levelBits[], "\n")
for := 0; < len(); ++ {
:= []
print("runtime: summary[", , "][", +, "] = (", .start(), ", ", .max(), ", ", .end(), ")\n")
}
throw("bad summary data")
}
if chunkIndex(.searchAddr.addr()) >= .end {
return 0, 0
}
:= minOffAddr
:= chunkIndex(.searchAddr.addr())
if := .summary[len(.summary)-1][].max(); >= uint() {
, := .chunkOf().find(, chunkPageIndex(.searchAddr.addr()))
if == ^uint(0) {
print("runtime: max = ", , ", npages = ", , "\n")
print("runtime: searchIdx = ", chunkPageIndex(.searchAddr.addr()), ", p.searchAddr = ", hex(.searchAddr.addr()), "\n")
throw("bad summary data")
}
= chunkBase() + uintptr()*pageSize
= offAddr{chunkBase() + uintptr()*pageSize}
goto
}
, = .find()
if == 0 {
.searchAddr = maxSearchAddr
}
return 0, 0
}
= .allocRange(, )
if .searchAddr.lessThan() {
.searchAddr =
}
return ,
}
func ( *pageAlloc) (, uintptr) {
assertLockHeld(.mheapLock)
if := (offAddr{}); .lessThan(.searchAddr) {
.searchAddr =
:= chunkIndex()
.chunkOf().free1(chunkPageIndex())
, := chunkIndex(), chunkIndex()
, := chunkPageIndex(), chunkPageIndex()
func (, , uint) pallocSum {
if == maxPackedValue {
return pallocSum(uint64(1 << 63))
}
return pallocSum((uint64() & (maxPackedValue - 1)) |
((uint64() & (maxPackedValue - 1)) << logMaxPackedValue) |
((uint64() & (maxPackedValue - 1)) << (2 * logMaxPackedValue)))
}
func ( pallocSum) () uint {
if uint64()&uint64(1<<63) != 0 {
return maxPackedValue
}
return uint(uint64() & (maxPackedValue - 1))
}
func ( pallocSum) () uint {
if uint64()&uint64(1<<63) != 0 {
return maxPackedValue
}
return uint((uint64() >> logMaxPackedValue) & (maxPackedValue - 1))
}
func ( pallocSum) () uint {
if uint64()&uint64(1<<63) != 0 {
return maxPackedValue
}
return uint((uint64() >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
}
func ( pallocSum) () (uint, uint, uint) {
if uint64()&uint64(1<<63) != 0 {
return maxPackedValue, maxPackedValue, maxPackedValue
}
return uint(uint64() & (maxPackedValue - 1)),
uint((uint64() >> logMaxPackedValue) & (maxPackedValue - 1)),
uint((uint64() >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
}
, , := [0].unpack()
, , := [].unpack()
if == uint()<< {
+=
}
if + > {
= +
}
if > {
=
}
if == 1<< {
+= 1 <<
} else {
=
}
}
return packPallocSum(, , )
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |