mirror of
https://github.com/go-delve/delve.git
synced 2025-10-28 04:35:19 +08:00
pkg/proc: split off rangeParent from function extras (#4173)
The rangeParent calculation was changed 0b74953f0 to address slowness (due to repeated calculations) when calling PackageVariables. That changed caused to program to use a lot of memory due to having to calculate the range bodies of every function. This change reverts 0b74953f0 and splits off rangeBodies calculation from the extras method of Function, so that it isn't called from PackageVariables. Fixes #4146
This commit is contained in:
committed by
GitHub
parent
949bd82138
commit
7b33c542f4
@ -25,9 +25,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/derekparker/trie/v3"
|
|
||||||
"github.com/hashicorp/golang-lru/v2"
|
|
||||||
|
|
||||||
"github.com/go-delve/delve/pkg/astutil"
|
"github.com/go-delve/delve/pkg/astutil"
|
||||||
pdwarf "github.com/go-delve/delve/pkg/dwarf"
|
pdwarf "github.com/go-delve/delve/pkg/dwarf"
|
||||||
"github.com/go-delve/delve/pkg/dwarf/frame"
|
"github.com/go-delve/delve/pkg/dwarf/frame"
|
||||||
@ -41,6 +38,7 @@ import (
|
|||||||
"github.com/go-delve/delve/pkg/logflags"
|
"github.com/go-delve/delve/pkg/logflags"
|
||||||
"github.com/go-delve/delve/pkg/proc/debuginfod"
|
"github.com/go-delve/delve/pkg/proc/debuginfod"
|
||||||
"github.com/go-delve/delve/pkg/proc/evalop"
|
"github.com/go-delve/delve/pkg/proc/evalop"
|
||||||
|
"github.com/hashicorp/golang-lru/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -69,8 +67,6 @@ type BinaryInfo struct {
|
|||||||
// lookupGenericFunc maps function names, with their type parameters removed, to functions.
|
// lookupGenericFunc maps function names, with their type parameters removed, to functions.
|
||||||
// Functions that are not generic are not added to this map.
|
// Functions that are not generic are not added to this map.
|
||||||
lookupGenericFunc map[string][]*Function
|
lookupGenericFunc map[string][]*Function
|
||||||
// lookupRangeBodyFunc maps function names to the range body functions.
|
|
||||||
lookupRangeBodyFunc *trie.Trie[*Function]
|
|
||||||
|
|
||||||
// SymNames maps addr to a description *elf.Symbol of this addr.
|
// SymNames maps addr to a description *elf.Symbol of this addr.
|
||||||
SymNames map[uint64]*elf.Symbol
|
SymNames map[uint64]*elf.Symbol
|
||||||
@ -536,19 +532,18 @@ type Function struct {
|
|||||||
// extraCache contains information about this function that is only needed for
|
// extraCache contains information about this function that is only needed for
|
||||||
// some operations and is expensive to compute or store for every function.
|
// some operations and is expensive to compute or store for every function.
|
||||||
extraCache *functionExtra
|
extraCache *functionExtra
|
||||||
|
// rangeBodiesCache caches the list of range-over-func body closures for
|
||||||
|
// this function. Only one of extraCache.rangeParent and rangeBodiesCache
|
||||||
|
// should be set at any given time.
|
||||||
|
rangeBodiesCache []*Function
|
||||||
}
|
}
|
||||||
|
|
||||||
type functionExtra struct {
|
type functionExtra struct {
|
||||||
// closureStructType is the cached struct type for closures for this function
|
// closureStructType is the cached struct type for closures for this function
|
||||||
closureStructType *godwarf.StructType
|
closureStructType *godwarf.StructType
|
||||||
|
|
||||||
// rangeParent is set when this function is a range-over-func body closure
|
// rangeParent is set when this function is a range-over-func body closure
|
||||||
// and points to the function that the closure was generated from.
|
// and points to the function that the closure was generated from.
|
||||||
rangeParent *Function
|
rangeParent *Function
|
||||||
// rangeBodies is the list of range-over-func body closures for this
|
|
||||||
// function. Only one between rangeParent and rangeBodies should be set at
|
|
||||||
// any given time.
|
|
||||||
rangeBodies []*Function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// instRange returns the indexes in fn.Name of the type parameter
|
// instRange returns the indexes in fn.Name of the type parameter
|
||||||
@ -776,19 +771,31 @@ func (fn *Function) extra(bi *BinaryInfo) *functionExtra {
|
|||||||
fn.extraCache.rangeParent = bi.lookupOneFunc(rangeParentName)
|
fn.extraCache.rangeParent = bi.lookupOneFunc(rangeParentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find range-over-func bodies of this function
|
|
||||||
if fn.extraCache.rangeParent == nil {
|
|
||||||
lookupFunc := bi.LookupRangeBodyFunc()
|
|
||||||
for _, fn2 := range lookupFunc.PrefixSearchIter(fn.Name) {
|
|
||||||
if fn2.rangeParentName() == fn.Name {
|
|
||||||
fn.extraCache.rangeBodies = append(fn.extraCache.rangeBodies, fn2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fn.extraCache
|
return fn.extraCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rangeBodies returns the list of range-over-func body closures for this
|
||||||
|
// function.
|
||||||
|
func (fn *Function) rangeBodies(bi *BinaryInfo) []*Function {
|
||||||
|
if fn == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if fn.rangeBodiesCache != nil {
|
||||||
|
return fn.rangeBodiesCache
|
||||||
|
}
|
||||||
|
extra := fn.extra(bi)
|
||||||
|
if extra.rangeParent != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i := range bi.Functions {
|
||||||
|
fn2 := &bi.Functions[i]
|
||||||
|
if strings.HasPrefix(fn2.Name, fn.Name) && fn2.rangeParentName() == fn.Name {
|
||||||
|
fn.rangeBodiesCache = append(fn.rangeBodiesCache, fn2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fn.rangeBodiesCache
|
||||||
|
}
|
||||||
|
|
||||||
type constantsMap map[dwarfRef]*constantType
|
type constantsMap map[dwarfRef]*constantType
|
||||||
|
|
||||||
type constantType struct {
|
type constantType struct {
|
||||||
@ -2626,7 +2633,6 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB
|
|||||||
|
|
||||||
bi.lookupFunc = nil
|
bi.lookupFunc = nil
|
||||||
bi.lookupGenericFunc = nil
|
bi.lookupGenericFunc = nil
|
||||||
bi.lookupRangeBodyFunc = nil
|
|
||||||
|
|
||||||
for _, cu := range image.compileUnits {
|
for _, cu := range image.compileUnits {
|
||||||
if cu.lineInfo != nil {
|
if cu.lineInfo != nil {
|
||||||
@ -2672,16 +2678,6 @@ func (bi *BinaryInfo) LookupFunc() map[string][]*Function {
|
|||||||
return bi.lookupFunc
|
return bi.lookupFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bi *BinaryInfo) LookupRangeBodyFunc() *trie.Trie[*Function] {
|
|
||||||
if bi.lookupRangeBodyFunc == nil {
|
|
||||||
bi.lookupRangeBodyFunc = trie.New[*Function]()
|
|
||||||
for i := range bi.Functions {
|
|
||||||
bi.lookupRangeBodyFunc.Add(bi.Functions[i].Name, &bi.Functions[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bi.lookupRangeBodyFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bi *BinaryInfo) lookupOneFunc(name string) *Function {
|
func (bi *BinaryInfo) lookupOneFunc(name string) *Function {
|
||||||
if name == evalop.DebugPinnerFunctionName && bi.debugPinnerFn != nil {
|
if name == evalop.DebugPinnerFunctionName && bi.debugPinnerFn != nil {
|
||||||
return bi.debugPinnerFn
|
return bi.debugPinnerFn
|
||||||
|
|||||||
@ -855,7 +855,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error {
|
|||||||
rpoff = rangeFrames[len(rangeFrames)-2].FrameOffset()
|
rpoff = rangeFrames[len(rangeFrames)-2].FrameOffset()
|
||||||
}
|
}
|
||||||
rpc := astutil.And(sameGCond, astutil.Eql(astutil.PkgVar("runtime", "rangeParentOffset"), astutil.Int(rpoff)))
|
rpc := astutil.And(sameGCond, astutil.Eql(astutil.PkgVar("runtime", "rangeParentOffset"), astutil.Int(rpoff)))
|
||||||
for _, fn := range rangeParent.extra(bi).rangeBodies {
|
for _, fn := range rangeParent.rangeBodies(bi) {
|
||||||
if fn.Entry != 0 {
|
if fn.Entry != 0 {
|
||||||
pc, err := FirstPCAfterPrologue(dbp, fn, false)
|
pc, err := FirstPCAfterPrologue(dbp, fn, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -149,7 +149,7 @@ func dwarfToRuntimeType(bi *BinaryInfo, mem MemoryReadWriter, typ godwarf.Type)
|
|||||||
return 0, false, false, nil
|
return 0, false, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mds, err := bi.getModuleData(mem)
|
mds, err := LoadModuleData(bi, mem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, false, false, err
|
return 0, false, false, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2141,7 +2141,7 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mds, err := _type.bi.getModuleData(_type.mem)
|
mds, err := LoadModuleData(_type.bi, _type.mem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Unreadable = fmt.Errorf("error loading module data: %v", err)
|
v.Unreadable = fmt.Errorf("error loading module data: %v", err)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user