From 3824d3d71ef1479b71ca624b728356657f62e1d3 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 26 May 2023 15:49:22 -0400 Subject: [PATCH] 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 TryBot-Result: Gopher Robot Reviewed-by: Bryan Mills Auto-Submit: Michael Pratt --- src/cmd/go/internal/load/pkg.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 191118b1e7..a66df86f5c 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -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) -- 2.50.0