1
0
mirror of https://github.com/golang/go synced 2024-11-13 12:30:21 -07:00

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 <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Michael Anthony Knyszek 2024-10-03 18:22:46 +00:00 committed by Gopher Robot
parent d8997c8c1f
commit 8df6413e11

View File

@ -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