mirror of
https://github.com/golang/go
synced 2024-11-24 06:30:22 -07:00
runtime: consolidate h_allspans and mheap_.allspans
These are two ways to refer to the allspans array that hark back to when the runtime was split between C and Go. Clean this up by making mheap_.allspans a slice and eliminating h_allspans. Change-Id: Ic9360d040cf3eb590b5dfbab0b82e8ace8525610 Reviewed-on: https://go-review.googlesource.com/30530 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
adda7ad295
commit
4d6207790b
@ -231,7 +231,7 @@ func CountPagesInUse() (pagesInUse, counted uintptr) {
|
||||
|
||||
pagesInUse = uintptr(mheap_.pagesInUse)
|
||||
|
||||
for _, s := range h_allspans {
|
||||
for _, s := range mheap_.allspans {
|
||||
if s.state == mSpanInUse {
|
||||
counted += s.npages
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ func dumproots() {
|
||||
dumpfields(firstmoduledata.gcbssmask)
|
||||
|
||||
// MSpan.types
|
||||
allspans := h_allspans
|
||||
allspans := mheap_.allspans
|
||||
for spanidx := uint32(0); spanidx < mheap_.nspan; spanidx++ {
|
||||
s := allspans[spanidx]
|
||||
if s.state == _MSpanInUse {
|
||||
@ -463,7 +463,7 @@ var freemark [_PageSize / 8]bool
|
||||
|
||||
func dumpobjs() {
|
||||
for i := uintptr(0); i < uintptr(mheap_.nspan); i++ {
|
||||
s := h_allspans[i]
|
||||
s := mheap_.allspans[i]
|
||||
if s.state != _MSpanInUse {
|
||||
continue
|
||||
}
|
||||
@ -608,7 +608,7 @@ func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs,
|
||||
|
||||
func dumpmemprof() {
|
||||
iterate_memprof(dumpmemprof_callback)
|
||||
allspans := h_allspans
|
||||
allspans := mheap_.allspans
|
||||
for spanidx := uint32(0); spanidx < mheap_.nspan; spanidx++ {
|
||||
s := allspans[spanidx]
|
||||
if s.state != _MSpanInUse {
|
||||
@ -632,7 +632,7 @@ var dumphdr = []byte("go1.7 heap dump\n")
|
||||
func mdump() {
|
||||
// make sure we're done sweeping
|
||||
for i := uintptr(0); i < uintptr(mheap_.nspan); i++ {
|
||||
s := h_allspans[i]
|
||||
s := mheap_.allspans[i]
|
||||
if s.state == _MSpanInUse {
|
||||
s.ensureSwept()
|
||||
}
|
||||
|
@ -1738,12 +1738,11 @@ func gcCopySpans() {
|
||||
// Even if this is stop-the-world, a concurrent exitsyscall can allocate a stack from heap.
|
||||
lock(&mheap_.lock)
|
||||
// Free the old cached mark array if necessary.
|
||||
if work.spans != nil && &work.spans[0] != &h_allspans[0] {
|
||||
if work.spans != nil && &work.spans[0] != &mheap_.allspans[0] {
|
||||
sysFree(unsafe.Pointer(&work.spans[0]), uintptr(len(work.spans))*unsafe.Sizeof(work.spans[0]), &memstats.other_sys)
|
||||
}
|
||||
// Cache the current array for sweeping.
|
||||
mheap_.gcspans = mheap_.allspans
|
||||
work.spans = h_allspans
|
||||
work.spans = mheap_.allspans
|
||||
unlock(&mheap_.lock)
|
||||
}
|
||||
|
||||
|
@ -33,15 +33,29 @@ type mheap struct {
|
||||
freelarge mSpanList // free lists length >= _MaxMHeapList
|
||||
busy [_MaxMHeapList]mSpanList // busy lists of large objects of given length
|
||||
busylarge mSpanList // busy lists of large objects length >= _MaxMHeapList
|
||||
allspans **mspan // all spans out there
|
||||
gcspans **mspan // copy of allspans referenced by gc marker or sweeper
|
||||
nspan uint32
|
||||
sweepgen uint32 // sweep generation, see comment in mspan
|
||||
sweepdone uint32 // all spans are swept
|
||||
|
||||
// allspans is a slice of all mspans ever created. Each mspan
|
||||
// appears exactly once.
|
||||
//
|
||||
// The memory for allspans is manually managed and can be
|
||||
// reallocated and move as the heap grows.
|
||||
//
|
||||
// In general, allspans is protected by mheap_.lock, which
|
||||
// prevents concurrent access as well as freeing the backing
|
||||
// store. Accesses during STW might not hold the lock, but
|
||||
// must ensure that allocation cannot happen around the
|
||||
// access (since that may free the backing store).
|
||||
allspans []*mspan // all spans out there
|
||||
nspan uint32
|
||||
|
||||
// span lookup
|
||||
spans **mspan
|
||||
spans_mapped uintptr
|
||||
|
||||
_ uint32 // align uint64 fields on 32-bit for atomics
|
||||
|
||||
// Proportional sweep
|
||||
pagesInUse uint64 // pages of spans in stats _MSpanInUse; R/W with mheap.lock
|
||||
spanBytesAlloc uint64 // bytes of spans allocated this cycle; updated atomically
|
||||
@ -233,8 +247,6 @@ func (s *mspan) layout() (size, n, total uintptr) {
|
||||
return
|
||||
}
|
||||
|
||||
var h_allspans []*mspan // TODO: make this h.allspans once mheap can be defined in Go
|
||||
|
||||
// h_spans is a lookup table to map virtual address page IDs to *mspan.
|
||||
// For allocated spans, their pages map to the span itself.
|
||||
// For free spans, only the lowest and highest pages map to the span itself. Internal
|
||||
@ -245,10 +257,10 @@ var h_spans []*mspan // TODO: make this h.spans once mheap can be defined in Go
|
||||
func recordspan(vh unsafe.Pointer, p unsafe.Pointer) {
|
||||
h := (*mheap)(vh)
|
||||
s := (*mspan)(p)
|
||||
if len(h_allspans) >= cap(h_allspans) {
|
||||
if len(h.allspans) >= cap(h.allspans) {
|
||||
n := 64 * 1024 / sys.PtrSize
|
||||
if n < cap(h_allspans)*3/2 {
|
||||
n = cap(h_allspans) * 3 / 2
|
||||
if n < cap(h.allspans)*3/2 {
|
||||
n = cap(h.allspans) * 3 / 2
|
||||
}
|
||||
var new []*mspan
|
||||
sp := (*slice)(unsafe.Pointer(&new))
|
||||
@ -256,21 +268,21 @@ func recordspan(vh unsafe.Pointer, p unsafe.Pointer) {
|
||||
if sp.array == nil {
|
||||
throw("runtime: cannot allocate memory")
|
||||
}
|
||||
sp.len = len(h_allspans)
|
||||
sp.len = len(h.allspans)
|
||||
sp.cap = n
|
||||
if len(h_allspans) > 0 {
|
||||
copy(new, h_allspans)
|
||||
if len(h.allspans) > 0 {
|
||||
copy(new, h.allspans)
|
||||
}
|
||||
oldAllspans := h.allspans
|
||||
h.allspans = new
|
||||
// Don't free the old array if it's referenced by sweep.
|
||||
// See the comment in mgc.go.
|
||||
if h.allspans != mheap_.gcspans {
|
||||
sysFree(unsafe.Pointer(h.allspans), uintptr(cap(h_allspans))*sys.PtrSize, &memstats.other_sys)
|
||||
if len(oldAllspans) != 0 && &oldAllspans[0] != &work.spans[0] {
|
||||
sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys)
|
||||
}
|
||||
}
|
||||
h_allspans = new
|
||||
h.allspans = (**mspan)(sp.array)
|
||||
}
|
||||
h_allspans = append(h_allspans, s)
|
||||
h.nspan = uint32(len(h_allspans))
|
||||
h.allspans = append(h.allspans, s)
|
||||
h.nspan = uint32(len(h.allspans))
|
||||
}
|
||||
|
||||
// inheap reports whether b is a pointer into a (potentially dead) heap object.
|
||||
|
@ -529,7 +529,7 @@ func updatememstats(stats *gcstats) {
|
||||
// Scan all spans and count number of alive objects.
|
||||
lock(&mheap_.lock)
|
||||
for i := uint32(0); i < mheap_.nspan; i++ {
|
||||
s := h_allspans[i]
|
||||
s := mheap_.allspans[i]
|
||||
if s.state != mSpanInUse {
|
||||
continue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user