提交 a61b6c0d 编写于 作者: A aarzilli 提交者: Derek Parker

proc: avoid constructing unnecessary strings when evaluating variables

Avoids constructing:

1. name of runtime.curg fields while executing parseG
2. the location expression while evaluating any variable.

Benchmark before:

BenchmarkConditionalBreakpoints-4   	       1	4953889884 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	4419775128 ns/op

Updates #1549
上级 431dea7e
......@@ -809,29 +809,51 @@ func (bi *BinaryInfo) LoadImageFromData(dwdata *dwarf.Data, debugFrameBytes, deb
bi.Images = append(bi.Images, image)
}
func (bi *BinaryInfo) locationExpr(entry godwarf.Entry, attr dwarf.Attr, pc uint64) ([]byte, string, error) {
func (bi *BinaryInfo) locationExpr(entry godwarf.Entry, attr dwarf.Attr, pc uint64) ([]byte, *locationExpr, error) {
a := entry.Val(attr)
if a == nil {
return nil, "", fmt.Errorf("no location attribute %s", attr)
return nil, nil, fmt.Errorf("no location attribute %s", attr)
}
if instr, ok := a.([]byte); ok {
var descr bytes.Buffer
fmt.Fprintf(&descr, "[block] ")
op.PrettyPrint(&descr, instr)
return instr, descr.String(), nil
return instr, &locationExpr{isBlock: true, instr: instr}, nil
}
off, ok := a.(int64)
if !ok {
return nil, "", fmt.Errorf("could not interpret location attribute %s", attr)
return nil, nil, fmt.Errorf("could not interpret location attribute %s", attr)
}
instr := bi.loclistEntry(off, pc)
if instr == nil {
return nil, "", fmt.Errorf("could not find loclist entry at %#x for address %#x", off, pc)
return nil, nil, fmt.Errorf("could not find loclist entry at %#x for address %#x", off, pc)
}
return instr, &locationExpr{pc: pc, off: off, instr: instr}, nil
}
type locationExpr struct {
isBlock bool
isEscaped bool
off int64
pc uint64
instr []byte
}
func (le *locationExpr) String() string {
if le == nil {
return ""
}
var descr bytes.Buffer
fmt.Fprintf(&descr, "[%#x:%#x] ", off, pc)
op.PrettyPrint(&descr, instr)
return instr, descr.String(), nil
if le.isBlock {
fmt.Fprintf(&descr, "[block] ")
op.PrettyPrint(&descr, le.instr)
} else {
fmt.Fprintf(&descr, "[%#x:%#x] ", le.off, le.pc)
op.PrettyPrint(&descr, le.instr)
}
if le.isEscaped {
fmt.Fprintf(&descr, " (escaped)")
}
return descr.String()
}
// LocationCovers returns the list of PC addresses that is covered by the
......@@ -877,10 +899,10 @@ func (bi *BinaryInfo) LocationCovers(entry *dwarf.Entry, attr dwarf.Attr) ([][2]
// This will either be an int64 address or a slice of Pieces for locations
// that don't correspond to a single memory address (registers, composite
// locations).
func (bi *BinaryInfo) Location(entry godwarf.Entry, attr dwarf.Attr, pc uint64, regs op.DwarfRegisters) (int64, []op.Piece, string, error) {
func (bi *BinaryInfo) Location(entry godwarf.Entry, attr dwarf.Attr, pc uint64, regs op.DwarfRegisters) (int64, []op.Piece, *locationExpr, error) {
instr, descr, err := bi.locationExpr(entry, attr, pc)
if err != nil {
return 0, nil, "", err
return 0, nil, nil, err
}
addr, pieces, err := op.ExecuteStackProgram(regs, instr, bi.Arch.PtrSize())
return addr, pieces, descr, err
......
......@@ -266,7 +266,8 @@ func (scope *EvalScope) Locals() ([]*Variable, error) {
}
v.Name = name[1:]
v.Flags |= VariableEscaped
v.LocationExpr = locationExpr + " (escaped)"
locationExpr.isEscaped = true
v.LocationExpr = locationExpr
v.DeclLine = declLine
vars[i] = v
}
......
......@@ -118,8 +118,8 @@ type Variable struct {
loaded bool
Unreadable error
LocationExpr string // location expression
DeclLine int64 // line number of this variable's declaration
LocationExpr *locationExpr // location expression
DeclLine int64 // line number of this variable's declaration
}
// LoadConfig controls how variables are loaded from the targets memory.
......@@ -441,8 +441,6 @@ func newGVariable(thread Thread, gaddr uintptr, deref bool) (*Variable, error) {
return nil, err
}
name := ""
if deref {
typ = &godwarf.PtrType{
CommonType: godwarf.CommonType{
......@@ -453,11 +451,9 @@ func newGVariable(thread Thread, gaddr uintptr, deref bool) (*Variable, error) {
},
Type: typ,
}
} else {
name = "runtime.curg"
}
return newVariableFromThread(thread, name, gaddr, typ), nil
return newVariableFromThread(thread, "", gaddr, typ), nil
}
// Defer returns the top-most defer of the goroutine.
......@@ -851,6 +847,8 @@ func (v *Variable) parseG() (*G, error) {
f, l, fn := v.bi.PCToLine(uint64(pc))
v.Name = "runtime.curg"
g := &G{
ID: int(id),
GoPC: uint64(gopc),
......
......@@ -148,7 +148,7 @@ func ConvertVar(v *proc.Variable) *Variable {
Flags: VariableFlags(v.Flags),
Base: v.Base,
LocationExpr: v.LocationExpr,
LocationExpr: v.LocationExpr.String(),
DeclLine: v.DeclLine,
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册