diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index f43cc0370..97709750e 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -798,7 +798,7 @@ type TimedOperation struct { // fields must be passed to TimedOperation.Finish. This is useful for cases // where which path an operation took is only known after it happens. This // path can be part of the fields passed to Finish. -//+checkescape:all +// +checkescape:all //go:nosplit func (t *TimerMetric) Start(fields ...string) TimedOperation { return TimedOperation{ @@ -812,7 +812,7 @@ func (t *TimerMetric) Start(fields ...string) TimedOperation { // `extraFields` is the rest of the fields appended to the fields passed to // `TimerMetric.Start`. The concatenation of these two must be the exact // number of fields that the underlying metric has. -//+checkescape:all +// +checkescape:all //go:nosplit func (o TimedOperation) Finish(extraFields ...string) { ended := CheapNowNano() diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index 46a0b6ca8..3457a3f06 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -166,6 +166,7 @@ func (s *Sleeper) AddWaker(w *Waker) { // block, then we will need to explicitly wake a runtime P. // // Precondition: wakepOrSleep may be true iff block is true. +//go:nosplit func (s *Sleeper) nextWaker(block, wakepOrSleep bool) *Waker { // Attempt to replenish the local list if it's currently empty. if s.localList == nil { @@ -282,7 +283,7 @@ func (s *Sleeper) Fetch(block bool) *Waker { // // N.B. Like Fetch, this method is *not* thread-safe. This will also yield the current // P to the next goroutine, avoiding associated scheduled overhead. -//+checkescapes:all +// +checkescape:all //go:nosplit func (s *Sleeper) AssertAndFetch(n *Waker) *Waker { n.assert(false /* wakep */) @@ -325,6 +326,7 @@ func (s *Sleeper) Done() { // enqueueAssertedWaker enqueues an asserted waker to the "ready" circular list // of wakers that want to notify the sleeper. +//go:nosplit func (s *Sleeper) enqueueAssertedWaker(w *Waker, wakep bool) { // Add the new waker to the front of the list. for { diff --git a/pkg/sync/runtime_amd64.go b/pkg/sync/runtime_amd64.go index 04a63c93c..9d714e01b 100644 --- a/pkg/sync/runtime_amd64.go +++ b/pkg/sync/runtime_amd64.go @@ -20,10 +20,12 @@ func addrOfSpinning() *int32 // nmspinning caches addrOfSpinning. var nmspinning = addrOfSpinning() +//go:nosplit func preGoReadyWakeSuppression() { atomic.AddInt32(nmspinning, 1) } +//go:nosplit func postGoReadyWakeSuppression() { atomic.AddInt32(nmspinning, -1) } diff --git a/tools/checkescape/checkescape.go b/tools/checkescape/checkescape.go index 579d59611..397136739 100644 --- a/tools/checkescape/checkescape.go +++ b/tools/checkescape/checkescape.go @@ -84,6 +84,10 @@ const ( // magic is the magic annotation. magic = "// +checkescape" + // Bad versions of `magic` observed in the wilderness of the codebase. + badMagicNoSpace = "//+checkescape" + badMagicPlural = "// +checkescapes" + // magicParams is the magic annotation with specific parameters. magicParams = magic + ":" @@ -573,6 +577,10 @@ func findReasons(pass *analysis.Pass, fdecl *ast.FuncDecl) ([]EscapeReason, bool // Scan all lines. found := false for _, c := range fdecl.Doc.List { + if strings.HasPrefix(c.Text, badMagicNoSpace) || strings.HasPrefix(c.Text, badMagicPlural) { + pass.Reportf(fdecl.Pos(), "misspelled checkescape prefix: please use %q instead", magic) + continue + } // Does the comment contain a +checkescape line? if !strings.HasPrefix(c.Text, magic) && !strings.HasPrefix(c.Text, testMagic) { continue