mirror of https://github.com/golang/go.git
cmd/go: always track visited packages in setPGOProfilePath
Currently we only track visited (copied) packages when a copy is required. When a copy is not required, we will rewalk each package's entire dependency graph every time we see it, which is terribly inefficient. Pull the visited package check up a level so that we visit packages only once regardless of how many times they are visited. Fixes #60455. Fixes #60428. Change-Id: I4e9b31eeeaa170db650c461a5de2ca984b9aba0f Reviewed-on: https://go-review.googlesource.com/c/go/+/498735 Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
6e248b8ff2
commit
3824d3d71e
|
|
@ -2950,17 +2950,21 @@ func setPGOProfilePath(pkgs []*Package) {
|
|||
continue // no profile
|
||||
}
|
||||
|
||||
copied := make(map[*Package]*Package)
|
||||
// Packages already visited. The value should replace
|
||||
// the key, as it may be a forked copy of the original
|
||||
// Package.
|
||||
visited := make(map[*Package]*Package)
|
||||
var split func(p *Package) *Package
|
||||
split = func(p *Package) *Package {
|
||||
if p1 := visited[p]; p1 != nil {
|
||||
return p1
|
||||
}
|
||||
|
||||
if len(pkgs) > 1 && p != pmain {
|
||||
// Make a copy, then attach profile.
|
||||
// No need to copy if there is only one root package (we can
|
||||
// attach profile directly in-place).
|
||||
// Also no need to copy the main package.
|
||||
if p1 := copied[p]; p1 != nil {
|
||||
return p1
|
||||
}
|
||||
if p.Internal.PGOProfile != "" {
|
||||
panic("setPGOProfilePath: already have profile")
|
||||
}
|
||||
|
|
@ -2969,9 +2973,11 @@ func setPGOProfilePath(pkgs []*Package) {
|
|||
// Unalias the Internal.Imports slice, which is we're going to
|
||||
// modify. We don't copy other slices as we don't change them.
|
||||
p1.Internal.Imports = slices.Clone(p.Internal.Imports)
|
||||
copied[p] = p1
|
||||
p1.Internal.ForMain = pmain.ImportPath
|
||||
visited[p] = p1
|
||||
p = p1
|
||||
p.Internal.ForMain = pmain.ImportPath
|
||||
} else {
|
||||
visited[p] = p
|
||||
}
|
||||
p.Internal.PGOProfile = file
|
||||
updateBuildInfo(p, file)
|
||||
|
|
|
|||
Loading…
Reference in New Issue