]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: make mSpanStateBox accessors nosplit
authorKeith Randall <khr@golang.org>
Mon, 19 Sep 2022 21:26:05 +0000 (17:26 -0400)
committerKeith Randall <khr@golang.org>
Mon, 19 Sep 2022 21:57:04 +0000 (21:57 +0000)
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 <cherryyz@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/runtime/mbarrier.go
src/runtime/mheap.go

index c3b45415a95339b484a6b377c3234849b0b87480..efe6c4f2d6346195ee155453042387e218a09836 100644 (file)
@@ -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 {
index c8a6cd29362e99038b6256a0b368f130ee579ebc..995cb2ae9c2ccdd63336fe3a1d1ab9096211ef45 100644 (file)
@@ -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())
 }