From 7ab3e22624058d5d53f9de8291031344a8d09cc2 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 12 Dec 2024 15:10:26 +0100 Subject: pkg/ifaceprobe: optimize cache Instead of storing real PC values store indexes into the PCs table. This significantly reduces size of the cache (in my case from 1823 MB to 473 MB) and actually makes use of the cache simpler (don't need separate map). --- pkg/declextract/fileops.go | 6 +----- pkg/ifaceprobe/ifaceprobe.go | 47 ++++++++++++++++++++++---------------------- 2 files changed, 24 insertions(+), 29 deletions(-) (limited to 'pkg') diff --git a/pkg/declextract/fileops.go b/pkg/declextract/fileops.go index 78016d57b..d28c48337 100644 --- a/pkg/declextract/fileops.go +++ b/pkg/declextract/fileops.go @@ -89,10 +89,6 @@ func (ctx *context) mapFopsToFiles() map[*FileOps][]string { uniqueFuncs[fn]++ } } - pcToFunc := make(map[uint64]string) - for _, pc := range ctx.probe.PCs { - pcToFunc[pc.PC] = pc.Func - } // matchedFuncs holds functions are present in any file_operations callbacks // (lots of coverage is not related to any file_operations at all). matchedFuncs := make(map[string]bool) @@ -102,7 +98,7 @@ func (ctx *context) mapFopsToFiles() map[*FileOps][]string { funcs := make(map[string]bool) fileToFuncs[file.Name] = funcs for _, pc := range file.Cover { - fn := pcToFunc[pc] + fn := ctx.probe.PCs[pc].Func if len(funcToFops[fn]) != 0 { funcs[fn] = true matchedFuncs[fn] = true diff --git a/pkg/ifaceprobe/ifaceprobe.go b/pkg/ifaceprobe/ifaceprobe.go index b2b3569df..f16be42a4 100644 --- a/pkg/ifaceprobe/ifaceprobe.go +++ b/pkg/ifaceprobe/ifaceprobe.go @@ -30,12 +30,11 @@ type Info struct { } type FileInfo struct { - Name string // Full file name, e.g. /dev/null. - Cover []uint64 // Combined coverage for operations on the file. + Name string // Full file name, e.g. /dev/null. + Cover []int // Combined coverage for operations on the file. } type PCInfo struct { - PC uint64 Func string File string } @@ -82,7 +81,7 @@ func (pr *prober) run() (*Info, error) { }() info := &Info{} - dedup := make(map[uint64]bool) + pcIndexes := make(map[uint64]int) kernelObj := filepath.Join(pr.cfg.KernelObj, pr.cfg.SysTarget.KernelObject) sourceBase := filepath.Clean(pr.cfg.KernelSrc) + string(filepath.Separator) i := 0 @@ -102,25 +101,28 @@ func (pr *prober) run() (*Info, error) { continue } fileDedup[pc] = true - fi.Cover = append(fi.Cover, pc) - if dedup[pc] { - continue - } - dedup[pc] = true - frames, err := symb.Symbolize(kernelObj, pc) - if err != nil { - return nil, err + pcIndex, ok := pcIndexes[pc] + if !ok { + pcIndex = -1 + frames, err := symb.Symbolize(kernelObj, pc) + if err != nil { + return nil, err + } + if len(frames) != 0 { + // Look only at the non-inline frame, + // callbacks we are looking for can't be inlined. + frame := frames[len(frames)-1] + pcIndex = len(info.PCs) + info.PCs = append(info.PCs, PCInfo{ + Func: frame.Func, + File: strings.TrimPrefix(filepath.Clean(frame.File), sourceBase), + }) + } + pcIndexes[pc] = pcIndex } - if len(frames) == 0 { - continue + if pcIndex >= 0 { + fi.Cover = append(fi.Cover, pcIndex) } - // Look only at the non-inline frame, callbacks we are looking for can't be inlined. - frame := frames[len(frames)-1] - info.PCs = append(info.PCs, PCInfo{ - PC: pc, - Func: frame.Func, - File: strings.TrimPrefix(filepath.Clean(frame.File), sourceBase), - }) } } slices.Sort(fi.Cover) @@ -129,9 +131,6 @@ func (pr *prober) run() (*Info, error) { slices.SortFunc(info.Files, func(a, b FileInfo) int { return strings.Compare(a.Name, b.Name) }) - slices.SortFunc(info.PCs, func(a, b PCInfo) int { - return int(a.PC - b.PC) - }) select { case err := <-pr.errc: return nil, err -- cgit mrf-deployment