From 979b82bfef62cbd5954bf1ec69c0fec5dbf2a1e0 Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Wed, 18 Dec 2019 17:36:47 -0800 Subject: [PATCH] internal/lsp/cache: fix excessive recursion in (*snapshot).clone() It wasn't infinite, but gopls would sit at 100% cpu for ~25 seconds whenever I made a change to a package imported by essentially everything in my project. Change-Id: Ifa253a4de06897260e0791888284527258e8de48 Reviewed-on: https://go-review.googlesource.com/c/tools/+/212000 Run-TryBot: Muir Manders TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- internal/lsp/cache/snapshot.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index 42d3112a1f..4314e49dd8 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -516,6 +516,10 @@ func (s *snapshot) clone(ctx context.Context, withoutFile source.File) *snapshot transitiveIDs := make(map[packageID]struct{}) var addRevDeps func(packageID) addRevDeps = func(id packageID) { + if _, seen := transitiveIDs[id]; seen { + return + } + transitiveIDs[id] = struct{}{} for _, rid := range s.getImportedByLocked(id) { addRevDeps(rid)