diff options
| author | Keith Randall <khr@golang.org> | 2014-05-08 08:35:49 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2014-05-08 08:35:49 -0700 |
| commit | 65c63dc4aabba3ecd320427fb20bc1cdbe0d2a3d (patch) | |
| tree | 8773cd3a19ea070f92bbfc3d6a31c818ae20c74e /src/pkg/runtime/heapdump.c | |
| parent | 1c2cc125fb2baad78167ee543f1d96aea9135734 (diff) | |
| download | go-65c63dc4aabba3ecd320427fb20bc1cdbe0d2a3d.tar.xz | |
runtime: write memory profile statistics to the heap dump.
LGTM=rsc
R=rsc, khr
CC=golang-codereviews
https://golang.org/cl/97010043
Diffstat (limited to 'src/pkg/runtime/heapdump.c')
| -rw-r--r-- | src/pkg/runtime/heapdump.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c index 9132e2c186..42d1601aa1 100644 --- a/src/pkg/runtime/heapdump.c +++ b/src/pkg/runtime/heapdump.c @@ -49,6 +49,8 @@ enum { TagBss = 13, TagDefer = 14, TagPanic = 15, + TagMemProf = 16, + TagAllocSample = 17, TypeInfo_Conservative = 127, }; @@ -690,6 +692,74 @@ dumpmemstats(void) } static void +dumpmemprof_callback(Bucket *b, uintptr nstk, uintptr *stk, uintptr size, uintptr allocs, uintptr frees) +{ + uintptr i, pc; + Func *f; + byte buf[20]; + String file; + int32 line; + + dumpint(TagMemProf); + dumpint((uintptr)b); + dumpint(size); + dumpint(nstk); + for(i = 0; i < nstk; i++) { + pc = stk[i]; + f = runtime·findfunc(pc); + if(f == nil) { + runtime·snprintf(buf, sizeof(buf), "%X", (uint64)pc); + dumpcstr((int8*)buf); + dumpcstr("?"); + dumpint(0); + } else { + dumpcstr(runtime·funcname(f)); + // TODO: Why do we need to back up to a call instruction here? + // Maybe profiler should do this. + if(i > 0 && pc > f->entry) { + if(thechar == '6' || thechar == '8') + pc--; + else + pc -= 4; // arm, etc + } + line = runtime·funcline(f, pc, &file); + dumpstr(file); + dumpint(line); + } + } + dumpint(allocs); + dumpint(frees); +} + +static void +dumpmemprof(void) +{ + MSpan *s, **allspans; + uint32 spanidx; + Special *sp; + SpecialProfile *spp; + byte *p; + + runtime·iterate_memprof(dumpmemprof_callback); + + allspans = runtime·mheap.allspans; + for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) { + s = allspans[spanidx]; + if(s->state != MSpanInUse) + continue; + for(sp = s->specials; sp != nil; sp = sp->next) { + if(sp->kind != KindSpecialProfile) + continue; + spp = (SpecialProfile*)sp; + p = (byte*)((s->start << PageShift) + spp->offset); + dumpint(TagAllocSample); + dumpint((uintptr)p); + dumpint((uintptr)spp->b); + } + } +} + +static void mdump(G *gp) { byte *hdr; @@ -713,6 +783,7 @@ mdump(G *gp) dumpms(); dumproots(); dumpmemstats(); + dumpmemprof(); dumpint(TagEOF); flush(); |
