From: Michael Anthony Knyszek Date: Thu, 3 Oct 2024 18:22:46 +0000 (+0000) Subject: runtime: recompute assistG before and after malloc X-Git-Tag: go1.24rc1~671 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8df6413e116eb471c69e0722ea4319a228efafa2;p=gostls13.git runtime: recompute assistG before and after malloc This change stops tracking assistG across malloc to reduce number of slots the compiler must keep track of in mallocgc, which adds to register pressure. It also makes the call to deductAssistCredit only happen if the GC is running. This is a microoptimization that on its own changes very little, but together with other optimizations and a breaking up of the various malloc paths will matter all together ("death by a thousand cuts"). Change-Id: I4cfac7f3e8e873ba66ff3b553072737a4707e2c2 Reviewed-on: https://go-review.googlesource.com/c/go/+/617876 Reviewed-by: Keith Randall Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Auto-Submit: Michael Knyszek --- diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index d376a4a26a..074a724ffd 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -1042,9 +1042,10 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } } - // assistG is the G to charge for this allocation, or nil if - // GC is not currently active. - assistG := deductAssistCredit(size) + // Assist the GC if needed. + if gcBlackenEnabled != 0 { + deductAssistCredit(size) + } // Set mp.mallocing to keep from being preempted by GC. mp := acquirem() @@ -1298,13 +1299,11 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } } - if assistG != nil { - // Account for internal fragmentation in the assist - // debt now that we know it. - // - // N.B. Use the full size because that's how the rest - // of the GC accounts for bytes marked. - assistG.gcAssistBytes -= int64(fullSize - dataSize) + // Adjust our GC assist debt to account for internal fragmentation. + if gcBlackenEnabled != 0 { + if assistG := getg().m.curg; assistG != nil { + assistG.gcAssistBytes -= int64(fullSize - size) + } } if shouldhelpgc { @@ -1338,26 +1337,22 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { // Caller must be preemptible. // // Returns the G for which the assist credit was accounted. -func deductAssistCredit(size uintptr) *g { - var assistG *g - if gcBlackenEnabled != 0 { - // Charge the current user G for this allocation. - assistG = getg() - if assistG.m.curg != nil { - assistG = assistG.m.curg - } - // Charge the allocation against the G. We'll account - // for internal fragmentation at the end of mallocgc. - assistG.gcAssistBytes -= int64(size) - - if assistG.gcAssistBytes < 0 { - // This G is in debt. Assist the GC to correct - // this before allocating. This must happen - // before disabling preemption. - gcAssistAlloc(assistG) - } +func deductAssistCredit(size uintptr) { + // Charge the current user G for this allocation. + assistG := getg() + if assistG.m.curg != nil { + assistG = assistG.m.curg + } + // Charge the allocation against the G. We'll account + // for internal fragmentation at the end of mallocgc. + assistG.gcAssistBytes -= int64(size) + + if assistG.gcAssistBytes < 0 { + // This G is in debt. Assist the GC to correct + // this before allocating. This must happen + // before disabling preemption. + gcAssistAlloc(assistG) } - return assistG } // memclrNoHeapPointersChunked repeatedly calls memclrNoHeapPointers