aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/trace.go
diff options
context:
space:
mode:
authorDavid Lazar <lazard@golang.org>2017-04-13 09:40:49 -0400
committerDavid Lazar <lazard@golang.org>2017-04-14 12:21:21 +0000
commit3249cb0ab465c5310e09868236405ba6c40929a4 (patch)
tree4022eab699c41c8e0ecef793000485ea652cd75c /src/runtime/trace.go
parenta7276742e69a9d9a34834d13fcf5867051bea3f1 (diff)
downloadgo-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.go40
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:]
}