Skip to content

Commit

Permalink
runtime: make mSpanStateBox accessors nosplit
Browse files Browse the repository at this point in the history
get, at least, is called from typedmemclr which must not be interruptible.
These were previously nosplit by accident before CL 424395 (the only
call they had was an intrinsic, so they were leaf functions, so they had
no prologue). After CL 424395 they contained a call (in noinline builds),
thus had a prologue, thus had a suspension point.

I have no idea how we might test this.

This is another motivating use case for having a nosplitrec directive
in the runtime.

Fixes #55156
Fixes #54779
Fixes #54906
Fixes #54907

Change-Id: I851d733d71bda7172c4c96e027657e22b499ee00
Reviewed-on: https://go-review.googlesource.com/c/go/+/431919
Reviewed-by: Cherry Mui <[email protected]>
Run-TryBot: Keith Randall <[email protected]>
Reviewed-by: Keith Randall <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
randall77 committed Sep 19, 2022
1 parent 2d74194 commit f1b7b2f
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/runtime/mbarrier.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
// If the caller knows that typ has pointers, it can alternatively
// call memclrHasPointers.
//
// TODO: A "go:nosplitrec" annotation would be perfect for this.
//
//go:nosplit
func typedmemclr(typ *_type, ptr unsafe.Pointer) {
if writeBarrier.needed && typ.ptrdata != 0 {
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/mheap.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,17 @@ type mSpanStateBox struct {
s atomic.Uint8
}

// It is nosplit to match get, below.

//go:nosplit
func (b *mSpanStateBox) set(s mSpanState) {
b.s.Store(uint8(s))
}

// It is nosplit because it's called indirectly by typedmemclr,
// which must not be preempted.

//go:nosplit
func (b *mSpanStateBox) get() mSpanState {
return mSpanState(b.s.Load())
}
Expand Down

0 comments on commit f1b7b2f

Please sign in to comment.