]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: only clear inline mark bits on span alloc if necessary
authorMichael Anthony Knyszek <mknyszek@google.com>
Mon, 14 Jul 2025 19:28:57 +0000 (19:28 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 15 Jul 2025 19:24:32 +0000 (12:24 -0700)
This change modifies initInlineMarkBits to only clear mark bits if the
span wasn't just freshly allocated from the OS, where we know the bits
are already zeroed. This probably doesn't make a huge difference most of
the time, but it's an easy optimization and helps rule it out as a
source of slowdown.

For #73581.

Change-Id: I78cd4d8968bb0bf6536c0a38ef9397475c39f0ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/687937
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/mgcmark_greenteagc.go

index 018f7df6ffefc3a0b2fe4985a5a5cfd8716a1a4e..6af711108fc1109c60ee11d80d3b8b1182e57dbd 100644 (file)
@@ -110,7 +110,7 @@ func (o *spanScanOwnership) or(v spanScanOwnership) spanScanOwnership {
        return spanScanOwnership(atomic.Or32(o32, uint32(v)<<off) >> off)
 }
 
-func (imb *spanInlineMarkBits) init(class spanClass) {
+func (imb *spanInlineMarkBits) init(class spanClass, needzero bool) {
        if imb == nil {
                // This nil check and throw is almost pointless. Normally we would
                // expect imb to never be nil. However, this is called on potentially
@@ -131,7 +131,9 @@ func (imb *spanInlineMarkBits) init(class spanClass) {
                // See go.dev/issue/74375 for details.
                throw("runtime: span inline mark bits nil?")
        }
-       *imb = spanInlineMarkBits{}
+       if needzero {
+               *imb = spanInlineMarkBits{}
+       }
        imb.class = class
 }
 
@@ -180,7 +182,8 @@ func (s *mspan) initInlineMarkBits() {
        if doubleCheckGreenTea && !gcUsesSpanInlineMarkBits(s.elemsize) {
                throw("expected span with inline mark bits")
        }
-       s.inlineMarkBits().init(s.spanclass)
+       // Zeroing is only necessary if this span wasn't just freshly allocated from the OS.
+       s.inlineMarkBits().init(s.spanclass, s.needzero != 0)
 }
 
 // moveInlineMarks merges the span's inline mark bits into dst and clears them.
@@ -205,7 +208,7 @@ func (s *mspan) moveInlineMarks(dst *gcBits) {
        }
 
        // Reset the inline mark bits.
-       imb.init(s.spanclass)
+       imb.init(s.spanclass, true /* We know these bits are always dirty now. */)
 }
 
 // inlineMarkBits returns the inline mark bits for the span.