mirror of
https://github.com/golang/go
synced 2024-11-19 06:04:39 -07:00
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>
This commit is contained in:
parent
a7276742e6
commit
3249cb0ab4
@ -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:]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user