proc/proc: Cache 'GoroutineInfo' result during halt

The GoroutineInfo method can be slow if there are many goroutines. This
patch caches the results during a halt so they are not needlessly
recomputed.

Fixes #234
This commit is contained in:
Ilia Choly
2015-09-17 13:33:42 -04:00
committed by Derek Parker
parent b733b66236
commit c185b7d004

View File

@ -39,6 +39,7 @@ type Process struct {
// Normally SelectedGoroutine is CurrentThread.GetG, it will not be only if SwitchGoroutine is called with a goroutine that isn't attached to a thread // Normally SelectedGoroutine is CurrentThread.GetG, it will not be only if SwitchGoroutine is called with a goroutine that isn't attached to a thread
SelectedGoroutine *G SelectedGoroutine *G
allGCache []*G
dwarf *dwarf.Data dwarf *dwarf.Data
goSymTable *gosym.Table goSymTable *gosym.Table
frameEntries frame.FrameDescriptionEntries frameEntries frame.FrameDescriptionEntries
@ -446,6 +447,10 @@ func (dbp *Process) SwitchGoroutine(gid int) error {
// Returns an array of G structures representing the information // Returns an array of G structures representing the information
// Delve cares about from the internal runtime G structure. // Delve cares about from the internal runtime G structure.
func (dbp *Process) GoroutinesInfo() ([]*G, error) { func (dbp *Process) GoroutinesInfo() ([]*G, error) {
if dbp.allGCache != nil {
return dbp.allGCache, nil
}
var ( var (
threadg = map[int]*Thread{} threadg = map[int]*Thread{}
allg []*G allg []*G
@ -498,6 +503,7 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
} }
allg = append(allg, g) allg = append(allg, g)
} }
dbp.allGCache = allg
return allg, nil return allg, nil
} }
@ -668,6 +674,7 @@ func (dbp *Process) handleBreakpointOnThread(id int) (*Thread, error) {
} }
func (dbp *Process) run(fn func() error) error { func (dbp *Process) run(fn func() error) error {
dbp.allGCache = nil
if dbp.exited { if dbp.exited {
return fmt.Errorf("process has already exited") return fmt.Errorf("process has already exited")
} }