]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement dumpmemstats in terms of readmemstats_m
authorMichael Anthony Knyszek <mknyszek@google.com>
Thu, 17 Sep 2020 21:19:28 +0000 (21:19 +0000)
committerMichael Knyszek <mknyszek@google.com>
Mon, 26 Oct 2020 21:49:01 +0000 (21:49 +0000)
Since MemStats is now populated directly and some values are derived,
avoid duplicating the logic by instead populating the heap dump directly
from MemStats (external version) instead of memstats (runtime internal
version).

Change-Id: I0bec96bfa02d2ffd1b56475779c124a760e64238
Reviewed-on: https://go-review.googlesource.com/c/go/+/255817
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/heapdump.go

index 6fcd9746af9b56dde053614c398506f3c3954592..33e224d5877090bd13cc410a28b0655dae11d98c 100644 (file)
@@ -20,8 +20,19 @@ import (
 func runtime_debug_WriteHeapDump(fd uintptr) {
        stopTheWorld("write heap dump")
 
+       // Keep m on this G's stack instead of the system stack.
+       // Both readmemstats_m and writeheapdump_m have pretty large
+       // peak stack depths and we risk blowing the system stack.
+       // This is safe because the world is stopped, so we don't
+       // need to worry about anyone shrinking and therefore moving
+       // our stack.
+       var m MemStats
        systemstack(func() {
-               writeheapdump_m(fd)
+               // Call readmemstats_m here instead of deeper in
+               // writeheapdump_m because we might blow the system stack
+               // otherwise.
+               readmemstats_m(&m)
+               writeheapdump_m(fd, &m)
        })
 
        startTheWorld()
@@ -539,39 +550,40 @@ func dumpms() {
        }
 }
 
-func dumpmemstats() {
+//go:systemstack
+func dumpmemstats(m *MemStats) {
        // These ints should be identical to the exported
        // MemStats structure and should be ordered the same
        // way too.
        dumpint(tagMemStats)
-       dumpint(memstats.alloc)
-       dumpint(memstats.total_alloc)
-       dumpint(memstats.sys)
-       dumpint(memstats.nlookup)
-       dumpint(memstats.nmalloc)
-       dumpint(memstats.nfree)
-       dumpint(memstats.alloc)
-       dumpint(memstats.heap_sys.load())
-       dumpint(memstats.heap_sys.load() - memstats.heap_inuse)
-       dumpint(memstats.heap_inuse)
-       dumpint(memstats.heap_released)
-       dumpint(memstats.heap_objects)
-       dumpint(memstats.stacks_inuse)
-       dumpint(memstats.stacks_sys.load())
-       dumpint(memstats.mspan_inuse)
-       dumpint(memstats.mspan_sys.load())
-       dumpint(memstats.mcache_inuse)
-       dumpint(memstats.mcache_sys.load())
-       dumpint(memstats.buckhash_sys.load())
-       dumpint(memstats.gcMiscSys.load() + memstats.gcWorkBufInUse + memstats.gcProgPtrScalarBitsInUse)
-       dumpint(memstats.other_sys.load())
-       dumpint(memstats.next_gc)
-       dumpint(memstats.last_gc_unix)
-       dumpint(memstats.pause_total_ns)
+       dumpint(m.Alloc)
+       dumpint(m.TotalAlloc)
+       dumpint(m.Sys)
+       dumpint(m.Lookups)
+       dumpint(m.Mallocs)
+       dumpint(m.Frees)
+       dumpint(m.HeapAlloc)
+       dumpint(m.HeapSys)
+       dumpint(m.HeapIdle)
+       dumpint(m.HeapInuse)
+       dumpint(m.HeapReleased)
+       dumpint(m.HeapObjects)
+       dumpint(m.StackInuse)
+       dumpint(m.StackSys)
+       dumpint(m.MSpanInuse)
+       dumpint(m.MSpanSys)
+       dumpint(m.MCacheInuse)
+       dumpint(m.MCacheSys)
+       dumpint(m.BuckHashSys)
+       dumpint(m.GCSys)
+       dumpint(m.OtherSys)
+       dumpint(m.NextGC)
+       dumpint(m.LastGC)
+       dumpint(m.PauseTotalNs)
        for i := 0; i < 256; i++ {
-               dumpint(memstats.pause_ns[i])
+               dumpint(m.PauseNs[i])
        }
-       dumpint(uint64(memstats.numgc))
+       dumpint(uint64(m.NumGC))
 }
 
 func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, frees uintptr) {
@@ -642,7 +654,7 @@ func dumpmemprof() {
 
 var dumphdr = []byte("go1.7 heap dump\n")
 
-func mdump() {
+func mdump(m *MemStats) {
        // make sure we're done sweeping
        for _, s := range mheap_.allspans {
                if s.state.get() == mSpanInUse {
@@ -657,13 +669,13 @@ func mdump() {
        dumpgs()
        dumpms()
        dumproots()
-       dumpmemstats()
+       dumpmemstats(m)
        dumpmemprof()
        dumpint(tagEOF)
        flush()
 }
 
-func writeheapdump_m(fd uintptr) {
+func writeheapdump_m(fd uintptr, m *MemStats) {
        _g_ := getg()
        casgstatus(_g_.m.curg, _Grunning, _Gwaiting)
        _g_.waitreason = waitReasonDumpingHeap
@@ -677,7 +689,7 @@ func writeheapdump_m(fd uintptr) {
        dumpfd = fd
 
        // Call dump routine.
-       mdump()
+       mdump(m)
 
        // Reset dump file.
        dumpfd = 0