diff options
author | David Lazar <lazard@golang.org> | 2017-04-13 09:40:49 -0400 |
---|---|---|
committer | David Lazar <lazard@golang.org> | 2017-04-14 12:21:21 +0000 |
commit | 3249cb0ab465c5310e09868236405ba6c40929a4 (patch) | |
tree | 4022eab699c41c8e0ecef793000485ea652cd75c /src/runtime/trace.go | |
parent | a7276742e69a9d9a34834d13fcf5867051bea3f1 (diff) | |
download | go-3249cb0ab465c5310e09868236405ba6c40929a4.tar.gz go-3249cb0ab465c5310e09868236405ba6c40929a4.zip |
runtime/trace: iterate over frames instead of PCs
Now the runtime/trace tests pass with -l=4.
This also gets rid of the frames cache for multiple reasons:
1) The frames cache was used to avoid repeated calls to funcname and
funcline. Now these calls happen inside the CallersFrames iterator.
2) Maintaining a frames cache is harder: map[uintptr]traceFrame
doesn't work since each PC can map to multiple traceFrames.
3) It's not clear that the cache is important.
Change-Id: I2914ac0b3ba08e39b60149d99a98f9f532b35bbb
Reviewed-on: https://go-review.googlesource.com/40591
Run-TryBot: David Lazar <lazard@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/trace.go')
-rw-r--r-- | src/runtime/trace.go | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/runtime/trace.go b/src/runtime/trace.go index 4f87d4ce2a..93d52a9844 100644 --- a/src/runtime/trace.go +++ b/src/runtime/trace.go @@ -764,10 +764,22 @@ func (tab *traceStackTable) newStack(n int) *traceStack { return (*traceStack)(tab.mem.alloc(unsafe.Sizeof(traceStack{}) + uintptr(n)*sys.PtrSize)) } +// allFrames returns all of the Frames corresponding to pcs. +func allFrames(pcs []uintptr) []Frame { + frames := make([]Frame, 0, len(pcs)) + ci := CallersFrames(pcs) + for { + f, more := ci.Next() + frames = append(frames, f) + if !more { + return frames + } + } +} + // dump writes all previously cached stacks to trace buffers, // releases all memory and resets state. func (tab *traceStackTable) dump() { - frames := make(map[uintptr]traceFrame) var tmp [(2 + 4*traceStackSize) * traceBytesPerNumber]byte buf := traceFlush(0).ptr() for _, stk := range tab.tab { @@ -775,11 +787,12 @@ func (tab *traceStackTable) dump() { for ; stk != nil; stk = stk.link.ptr() { tmpbuf := tmp[:0] tmpbuf = traceAppend(tmpbuf, uint64(stk.id)) - tmpbuf = traceAppend(tmpbuf, uint64(stk.n)) - for _, pc := range stk.stack() { + frames := allFrames(stk.stack()) + tmpbuf = traceAppend(tmpbuf, uint64(len(frames))) + for _, f := range frames { var frame traceFrame - frame, buf = traceFrameForPC(buf, frames, pc) - tmpbuf = traceAppend(tmpbuf, uint64(pc)) + frame, buf = traceFrameForPC(buf, f) + tmpbuf = traceAppend(tmpbuf, uint64(f.PC)) tmpbuf = traceAppend(tmpbuf, uint64(frame.funcID)) tmpbuf = traceAppend(tmpbuf, uint64(frame.fileID)) tmpbuf = traceAppend(tmpbuf, uint64(frame.line)) @@ -809,26 +822,17 @@ type traceFrame struct { line uint64 } -func traceFrameForPC(buf *traceBuf, frames map[uintptr]traceFrame, pc uintptr) (traceFrame, *traceBuf) { - if frame, ok := frames[pc]; ok { - return frame, buf - } - +func traceFrameForPC(buf *traceBuf, f Frame) (traceFrame, *traceBuf) { var frame traceFrame - f := findfunc(pc) - if !f.valid() { - frames[pc] = frame - return frame, buf - } - fn := funcname(f) + fn := f.Function const maxLen = 1 << 10 if len(fn) > maxLen { fn = fn[len(fn)-maxLen:] } frame.funcID, buf = traceString(buf, fn) - file, line := funcline(f, pc-sys.PCQuantum) - frame.line = uint64(line) + frame.line = uint64(f.Line) + file := f.File if len(file) > maxLen { file = file[len(file)-maxLen:] } |