From: Michael Anthony Knyszek Date: Mon, 14 Jul 2025 19:28:57 +0000 (+0000) Subject: runtime: only clear inline mark bits on span alloc if necessary X-Git-Tag: go1.25rc3~5^2~21 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6d4a91c7a5b5723aa1fc1461eb3e9602ccf9606a;p=gostls13.git runtime: only clear inline mark bits on span alloc if necessary 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 LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui Reviewed-by: Michael Pratt --- diff --git a/src/runtime/mgcmark_greenteagc.go b/src/runtime/mgcmark_greenteagc.go index 018f7df6ff..6af711108f 100644 --- a/src/runtime/mgcmark_greenteagc.go +++ b/src/runtime/mgcmark_greenteagc.go @@ -110,7 +110,7 @@ func (o *spanScanOwnership) or(v spanScanOwnership) spanScanOwnership { return spanScanOwnership(atomic.Or32(o32, uint32(v)<> 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.