proc: Caching type offsets

Caches the mapping of type names to offset in debug_info to speed up
variable evaluation.

BEFORE:
	BenchmarkArray-4         	     100	  13'238'441 ns/op	   0.62 MB/s
	BenchmarkArrayPointer-4  	     200	  10'044'093 ns/op	   0.87 MB/s
	BenchmarkMap-4           	    1000	   1'332'530 ns/op	   0.77 MB/s
	BenchmarkGoroutinesInfo-4	      10	 114'677'462 ns/op
	BenchmarkLocalVariables-4	    2000	   1'223'975 ns/op
AFTER:
	BenchmarkArray-4         	     200	   9'925'686 ns/op	   0.83 MB/s
	BenchmarkArrayPointer-4  	     100	  11'143'930 ns/op	   0.78 MB/s
	BenchmarkMap-4           	    2000	   1'302'520 ns/op	   0.79 MB/s
	BenchmarkGoroutinesInfo-4	      30	  35'079'549 ns/op
	BenchmarkLocalVariables-4	    1000	   1'137'299 ns/op

Note in particular the speedup of BenchmarkGoroutinesInfo, since
proc.(*Variable).parseG is a function we call a lot.
This commit is contained in:
aarzilli
2016-03-05 13:04:11 +01:00
parent 758f76ffee
commit c66c6408a5
3 changed files with 31 additions and 20 deletions

View File

@ -58,6 +58,7 @@ type Process struct {
exited bool
ptraceChan chan func()
ptraceDoneChan chan interface{}
types map[string]dwarf.Offset
}
// New returns an initialized Process struct. Before returning,
@ -149,11 +150,12 @@ func (dbp *Process) LoadInformation(path string) error {
return err
}
wg.Add(4)
wg.Add(5)
go dbp.loadProcessInformation(&wg)
go dbp.parseDebugFrame(exe, &wg)
go dbp.obtainGoSymbols(exe, &wg)
go dbp.parseDebugLineInfo(exe, &wg)
go dbp.loadTypeMap(&wg)
wg.Wait()
return nil
@ -658,19 +660,9 @@ func (dbp *Process) Funcs() []gosym.Func {
// Types returns list of types present in the debugged program.
func (dbp *Process) Types() ([]string, error) {
reader := dbp.DwarfReader()
types := []string{}
seen := map[string]struct{}{}
for entry, err := reader.NextType(); entry != nil; entry, err = reader.NextType() {
if err != nil {
return nil, err
}
if n, ok := entry.Val(dwarf.AttrName).(string); ok {
if _, isseen := seen[n]; !isseen {
seen[n] = struct{}{}
types = append(types, n)
}
}
types := make([]string, 0, len(dbp.types))
for k := range dbp.types {
types = append(types, k)
}
return types, nil
}