Skip to content

Commit c69dfaf

Browse files
adonovangopherbot
authored andcommitted
[gopls-release-branch.0.15] gopls/internal/cache: add debug assertions to refine golang/go#66732
Also, use go1.19 generic helpers for atomics. Updates golang/go#66732 Updates golang/go#66730 Change-Id: I7aa447144353ff2ac5906ca746e2f98b115aa732 Reviewed-on: https://go-review.googlesource.com/c/tools/+/577435 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Alan Donovan <[email protected]> (cherry picked from commit f6298eb) Reviewed-on: https://go-review.googlesource.com/c/tools/+/577596
1 parent 91b4992 commit c69dfaf

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

gopls/internal/cache/analysis.go

+33-17
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"golang.org/x/tools/gopls/internal/util/astutil"
4242
"golang.org/x/tools/gopls/internal/util/bug"
4343
"golang.org/x/tools/gopls/internal/util/frob"
44+
"golang.org/x/tools/gopls/internal/util/maps"
4445
"golang.org/x/tools/internal/event"
4546
"golang.org/x/tools/internal/event/tag"
4647
"golang.org/x/tools/internal/facts"
@@ -177,8 +178,6 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
177178

178179
var tagStr string // sorted comma-separated list of PackageIDs
179180
{
180-
// TODO(adonovan): replace with a generic map[S]any -> string
181-
// function in the tag package, and use maps.Keys + slices.Sort.
182181
keys := make([]string, 0, len(pkgs))
183182
for id := range pkgs {
184183
keys = append(keys, string(id))
@@ -303,10 +302,10 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
303302
}
304303
// Add edge from predecessor.
305304
if from != nil {
306-
atomic.AddInt32(&from.unfinishedSuccs, 1) // TODO(adonovan): use generics
305+
from.unfinishedSuccs.Add(+1) // incref
307306
an.preds = append(an.preds, from)
308307
}
309-
atomic.AddInt32(&an.unfinishedPreds, 1)
308+
an.unfinishedPreds.Add(+1)
310309
return an, nil
311310
}
312311

@@ -387,7 +386,7 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
387386
// prevents workers from enqeuing, and thus finishing, and thus allowing the
388387
// group to make progress: deadlock.
389388
limiter := make(chan unit, runtime.GOMAXPROCS(0))
390-
var completed int64
389+
var completed atomic.Int64
391390

392391
var enqueue func(*analysisNode)
393392
enqueue = func(an *analysisNode) {
@@ -399,13 +398,13 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
399398
if err != nil {
400399
return err // cancelled, or failed to produce a package
401400
}
402-
maybeReport(atomic.AddInt64(&completed, 1))
401+
maybeReport(completed.Add(1))
403402
an.summary = summary
404403

405404
// Notify each waiting predecessor,
406405
// and enqueue it when it becomes a leaf.
407406
for _, pred := range an.preds {
408-
if atomic.AddInt32(&pred.unfinishedSuccs, -1) == 0 {
407+
if pred.unfinishedSuccs.Add(-1) == 0 { // decref
409408
enqueue(pred)
410409
}
411410
}
@@ -427,6 +426,18 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
427426
return nil, err // cancelled, or failed to produce a package
428427
}
429428

429+
// Inv: all root nodes now have a summary (#66732).
430+
//
431+
// We know this is falsified empirically. This means either
432+
// the summary was "successfully" set to nil (above), or there
433+
// is a problem with the graph such the enqueuing leaves does
434+
// not lead to completion of roots (or an error).
435+
for _, root := range roots {
436+
if root.summary == nil {
437+
bug.Report("root analysisNode has nil summary")
438+
}
439+
}
440+
430441
// Report diagnostics only from enabled actions that succeeded.
431442
// Errors from creating or analyzing packages are ignored.
432443
// Diagnostics are reported in the order of the analyzers argument.
@@ -458,6 +469,7 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
458469
}
459470

460471
// Inv: root.summary is the successful result of run (via runCached).
472+
// TODO(adonovan): fix: root.summary is sometimes nil! (#66732).
461473
summary, ok := root.summary.Actions[stableNames[a]]
462474
if summary == nil {
463475
panic(fmt.Sprintf("analyzeSummary.Actions[%q] = (nil, %t); got %v (#60551)",
@@ -475,7 +487,7 @@ func (s *Snapshot) Analyze(ctx context.Context, pkgs map[PackageID]*metadata.Pac
475487
}
476488

477489
func (an *analysisNode) decrefPreds() {
478-
if atomic.AddInt32(&an.unfinishedPreds, -1) == 0 {
490+
if an.unfinishedPreds.Add(-1) == 0 {
479491
an.summary.Actions = nil
480492
}
481493
}
@@ -510,8 +522,8 @@ type analysisNode struct {
510522
analyzers []*analysis.Analyzer // set of analyzers to run
511523
preds []*analysisNode // graph edges:
512524
succs map[PackageID]*analysisNode // (preds -> self -> succs)
513-
unfinishedSuccs int32
514-
unfinishedPreds int32 // effectively a summary.Actions refcount
525+
unfinishedSuccs atomic.Int32
526+
unfinishedPreds atomic.Int32 // effectively a summary.Actions refcount
515527
allDeps map[PackagePath]*analysisNode // all dependencies including self
516528
exportDeps map[PackagePath]*analysisNode // subset of allDeps ref'd by export data (+self)
517529
summary *analyzeSummary // serializable result of analyzing this package
@@ -664,6 +676,9 @@ func (an *analysisNode) runCached(ctx context.Context) (*analyzeSummary, error)
664676
if data, err := filecache.Get(cacheKind, key); err == nil {
665677
// cache hit
666678
analyzeSummaryCodec.Decode(data, &summary)
679+
if summary == nil { // debugging #66732
680+
bug.Reportf("analyzeSummaryCodec.Decode yielded nil *analyzeSummary")
681+
}
667682
} else if err != filecache.ErrNotFound {
668683
return nil, bug.Errorf("internal error reading shared cache: %v", err)
669684
} else {
@@ -673,8 +688,11 @@ func (an *analysisNode) runCached(ctx context.Context) (*analyzeSummary, error)
673688
if err != nil {
674689
return nil, err
675690
}
691+
if summary == nil { // debugging #66732 (can't happen)
692+
bug.Reportf("analyzeNode.run returned nil *analyzeSummary")
693+
}
676694

677-
atomic.AddInt32(&an.unfinishedPreds, +1) // incref
695+
an.unfinishedPreds.Add(+1) // incref
678696
go func() {
679697
defer an.decrefPreds() //decref
680698

@@ -742,13 +760,11 @@ func (an *analysisNode) cacheKey() [sha256.Size]byte {
742760
}
743761

744762
// vdeps, in PackageID order
745-
depIDs := make([]string, 0, len(an.succs))
746-
for depID := range an.succs {
747-
depIDs = append(depIDs, string(depID))
748-
}
749-
sort.Strings(depIDs) // TODO(adonovan): avoid conversions by using slices.Sort[PackageID]
763+
depIDs := maps.Keys(an.succs)
764+
// TODO(adonovan): use go1.2x slices.Sort(depIDs).
765+
sort.Slice(depIDs, func(i, j int) bool { return depIDs[i] < depIDs[j] })
750766
for _, depID := range depIDs {
751-
vdep := an.succs[PackageID(depID)]
767+
vdep := an.succs[depID]
752768
fmt.Fprintf(hasher, "dep: %s\n", vdep.mp.PkgPath)
753769
fmt.Fprintf(hasher, "export: %s\n", vdep.summary.DeepExportHash)
754770

0 commit comments

Comments
 (0)