提交 222cf7fc 编写于 作者: A Alessandro Arzilli 提交者: Derek Parker

proc/eval: optimize variable lookup (#925)

Variable lookup is slow because it requires a full scan of debug_info
to check for package variables, this doesn't matter much in interactive
use but can slow down evaluation of breakpoint conditions
significantly.

Providing benchmark proof for this is hard since this effect doesn't
show for small programs with small debug_info sections.
上级 07e53f7c
......@@ -34,6 +34,7 @@ type BinaryInfo struct {
lineInfo line.DebugLines
goSymTable *gosym.Table
types map[string]dwarf.Offset
packageVars map[string]dwarf.Offset
functions []functionDebugInfo
gStructOffset uint64
......
......@@ -132,6 +132,7 @@ func (v sortFunctionsDebugInfoByLowpc) Swap(i, j int) {
func (bi *BinaryInfo) loadDebugInfoMaps(wg *sync.WaitGroup) {
defer wg.Done()
bi.types = make(map[string]dwarf.Offset)
bi.packageVars = make(map[string]dwarf.Offset)
bi.functions = []functionDebugInfo{}
reader := bi.DwarfReader()
for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() {
......@@ -140,23 +141,23 @@ func (bi *BinaryInfo) loadDebugInfoMaps(wg *sync.WaitGroup) {
}
switch entry.Tag {
case dwarf.TagArrayType, dwarf.TagBaseType, dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType, dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType, dwarf.TagEnumerationType, dwarf.TagPointerType, dwarf.TagSubroutineType, dwarf.TagTypedef, dwarf.TagUnspecifiedType:
name, ok := entry.Val(dwarf.AttrName).(string)
if !ok {
continue
if name, ok := entry.Val(dwarf.AttrName).(string); ok {
if _, exists := bi.types[name]; !exists {
bi.types[name] = entry.Offset
}
}
if _, exists := bi.types[name]; !exists {
bi.types[name] = entry.Offset
reader.SkipChildren()
case dwarf.TagVariable:
if n, ok := entry.Val(dwarf.AttrName).(string); ok {
bi.packageVars[n] = entry.Offset
}
case dwarf.TagSubprogram:
lowpc, ok := entry.Val(dwarf.AttrLowpc).(uint64)
if !ok {
continue
}
highpc, ok := entry.Val(dwarf.AttrHighpc).(uint64)
if !ok {
continue
lowpc, ok1 := entry.Val(dwarf.AttrLowpc).(uint64)
highpc, ok2 := entry.Val(dwarf.AttrHighpc).(uint64)
if ok1 && ok2 {
bi.functions = append(bi.functions, functionDebugInfo{lowpc, highpc, entry.Offset})
}
bi.functions = append(bi.functions, functionDebugInfo{lowpc, highpc, entry.Offset})
reader.SkipChildren()
}
}
sort.Sort(sortFunctionsDebugInfoByLowpc(bi.functions))
......
......@@ -650,18 +650,14 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
}
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
reader := scope.DwarfReader()
for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
if err != nil {
return nil, err
}
n, ok := entry.Val(dwarf.AttrName).(string)
if !ok {
continue
}
for n, off := range scope.BinInfo.packageVars {
if n == name || strings.HasSuffix(n, "/"+name) {
reader := scope.DwarfReader()
reader.Seek(off)
entry, err := reader.Next()
if err != nil {
return nil, err
}
return scope.extractVarInfoFromEntry(entry, reader)
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册