]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/trace: iterate over frames instead of PCs
authorDavid Lazar <lazard@golang.org>
Thu, 13 Apr 2017 13:40:49 +0000 (09:40 -0400)
committerDavid Lazar <lazard@golang.org>
Fri, 14 Apr 2017 12:21:21 +0000 (12:21 +0000)
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>
src/runtime/trace.go

index 4f87d4ce2a396ac7bf83be8be40d499045a77832..93d52a9844bb145d2d8b24a609b84b4f82e2f0fc 100644 (file)
@@ -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:]
        }