// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Garbage collector (GC).
//
// The GC runs concurrently with mutator threads, is type accurate (aka precise), allows multiple
// GC threads to run in parallel. It is a concurrent mark and sweep that uses a write barrier. It is
// non-generational and non-compacting. Allocation is done using size segregated per P allocation
// areas to minimize fragmentation while eliminating locks in the common case.
//
// The algorithm decomposes into several steps.
// This is a high level description of the algorithm being used. For an overview of GC a good
// place to start is Richard Jones' gchandbook.org.
//
// The algorithm's intellectual heritage includes Dijkstra's on-the-fly algorithm, see
// Edsger W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten, and E. F. M. Steffens. 1978.
// On-the-fly garbage collection: an exercise in cooperation. Commun. ACM 21, 11 (November 1978),
// 966-975.
// For journal quality proofs that these steps are complete, correct, and terminate see
// Hudson, R., and Moss, J.E.B. Copying Garbage Collection without stopping the world.
// Concurrency and Computation: Practice and Experience 15(3-5), 2003.
//
// 1. GC performs sweep termination.
//
//    a. Stop the world. This causes all Ps to reach a GC safe-point.
//
//    b. Sweep any unswept spans. There will only be unswept spans if
//    this GC cycle was forced before the expected time.
//
// 2. GC performs the mark phase.
//
//    a. Prepare for the mark phase by setting gcphase to _GCmark
//    (from _GCoff), enabling the write barrier, enabling mutator
//    assists, and enqueueing root mark jobs. No objects may be
//    scanned until all Ps have enabled the write barrier, which is
//    accomplished using STW.
//
//    b. Start the world. From this point, GC work is done by mark
//    workers started by the scheduler and by assists performed as
//    part of allocation. The write barrier shades both the
//    overwritten pointer and the new pointer value for any pointer
//    writes (see mbarrier.go for details). Newly allocated objects
//    are immediately marked black.
//
//    c. GC performs root marking jobs. This includes scanning all
//    stacks, shading all globals, and shading any heap pointers in
//    off-heap runtime data structures. Scanning a stack stops a
//    goroutine, shades any pointers found on its stack, and then
//    resumes the goroutine.
//
//    d. GC drains the work queue of grey objects, scanning each grey
//    object to black and shading all pointers found in the object
//    (which in turn may add those pointers to the work queue).
//
//    e. Because GC work is spread across local caches, GC uses a
//    distributed termination algorithm to detect when there are no
//    more root marking jobs or grey objects (see gcMarkDone). At this
//    point, GC transitions to mark termination.
//
// 3. GC performs mark termination.
//
//    a. Stop the world.
//
//    b. Set gcphase to _GCmarktermination, and disable workers and
//    assists.
//
//    c. Perform housekeeping like flushing mcaches.
//
// 4. GC performs the sweep phase.
//
//    a. Prepare for the sweep phase by setting gcphase to _GCoff,
//    setting up sweep state and disabling the write barrier.
//
//    b. Start the world. From this point on, newly allocated objects
//    are white, and allocating sweeps spans before use if necessary.
//
//    c. GC does concurrent sweeping in the background and in response
//    to allocation. See description below.
//
// 5. When sufficient allocation has taken place, replay the sequence
// starting with 1 above. See discussion of GC rate below.

// Concurrent sweep.
//
// The sweep phase proceeds concurrently with normal program execution.
// The heap is swept span-by-span both lazily (when a goroutine needs another span)
// and concurrently in a background goroutine (this helps programs that are not CPU bound).
// At the end of STW mark termination all spans are marked as "needs sweeping".
//
// The background sweeper goroutine simply sweeps spans one-by-one.
//
// To avoid requesting more OS memory while there are unswept spans, when a
// goroutine needs another span, it first attempts to reclaim that much memory
// by sweeping. When a goroutine needs to allocate a new small-object span, it
// sweeps small-object spans for the same object size until it frees at least
// one object. When a goroutine needs to allocate large-object span from heap,
// it sweeps spans until it frees at least that many pages into heap. There is
// one case where this may not suffice: if a goroutine sweeps and frees two
// nonadjacent one-page spans to the heap, it will allocate a new two-page
// span, but there can still be other one-page unswept spans which could be
// combined into a two-page span.
//
// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
// The finalizer goroutine is kicked off only when all spans are swept.
// When the next GC starts, it sweeps all not-yet-swept spans (if any).

// GC rate.
// Next GC is after we've allocated an extra amount of memory proportional to
// the amount already in use. The proportion is controlled by GOGC environment variable
// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
// (this mark is computed by the gcController.heapGoal method). This keeps the GC cost in
// linear proportion to the allocation cost. Adjusting GOGC just changes the linear constant
// (and also the amount of extra memory used).

// Oblets
//
// In order to prevent long pauses while scanning large objects and to
// improve parallelism, the garbage collector breaks up scan jobs for
// objects larger than maxObletBytes into "oblets" of at most
// maxObletBytes. When scanning encounters the beginning of a large
// object, it scans only the first oblet and enqueues the remaining
// oblets as new scan jobs.

package runtime

import (
	"internal/cpu"
	"internal/goarch"
	"internal/goexperiment"
	"internal/runtime/atomic"
	"internal/runtime/gc"
	"unsafe"
)

const (
	_DebugGC = 0

	// concurrentSweep is a debug flag. Disabling this flag
	// ensures all spans are swept while the world is stopped.
	concurrentSweep = true

	// debugScanConservative enables debug logging for stack
	// frames that are scanned conservatively.
	debugScanConservative = false

	// sweepMinHeapDistance is a lower bound on the heap distance
	// (in bytes) reserved for concurrent sweeping between GC
	// cycles.
	sweepMinHeapDistance = 1024 * 1024
)

// heapObjectsCanMove always returns false in the current garbage collector.
// It exists for go4.org/unsafe/assume-no-moving-gc, which is an
// unfortunate idea that had an even more unfortunate implementation.
// Every time a new Go release happened, the package stopped building,
// and the authors had to add a new file with a new //go:build line, and
// then the entire ecosystem of packages with that as a dependency had to
// explicitly update to the new version. Many packages depend on
// assume-no-moving-gc transitively, through paths like
// inet.af/netaddr -> go4.org/intern -> assume-no-moving-gc.
// This was causing a significant amount of friction around each new
// release, so we added this bool for the package to //go:linkname
// instead. The bool is still unfortunate, but it's not as bad as
// breaking the ecosystem on every new release.
//
// If the Go garbage collector ever does move heap objects, we can set
// this to true to break all the programs using assume-no-moving-gc.
//
//go:linkname heapObjectsCanMove
func heapObjectsCanMove() bool {
	return false
}

func gcinit() {
	if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
		throw("size of Workbuf is suboptimal")
	}
	// No sweep on the first cycle.
	sweep.active.state.Store(sweepDrainedMask)

	// Initialize GC pacer state.
	// Use the environment variable GOGC for the initial gcPercent value.
	// Use the environment variable GOMEMLIMIT for the initial memoryLimit value.
	gcController.init(readGOGC(), readGOMEMLIMIT())

	// Set up the cleanup block ptr mask.
	for i := range cleanupBlockPtrMask {
		cleanupBlockPtrMask[i] = 0xff
	}

	work.startSema = 1
	work.markDoneSema = 1
	work.spanSPMCs.list.init(unsafe.Offsetof(spanSPMC{}.allnode))
	lockInit(&work.sweepWaiters.lock, lockRankSweepWaiters)
	lockInit(&work.assistQueue.lock, lockRankAssistQueue)
	lockInit(&work.strongFromWeak.lock, lockRankStrongFromWeakQueue)
	lockInit(&work.wbufSpans.lock, lockRankWbufSpans)
	lockInit(&work.spanSPMCs.lock, lockRankSpanSPMCs)
	lockInit(&gcCleanups.lock, lockRankCleanupQueue)
}

// gcenable is called after the bulk of the runtime initialization,
// just before we're about to start letting user code run.
// It kicks off the background sweeper goroutine, the background
// scavenger goroutine, and enables GC.
func gcenable() {
	// Kick off sweeping and scavenging.
	c := make(chan int, 2)
	go bgsweep(c)
	go bgscavenge(c)
	<-c
	<-c
	memstats.enablegc = true // now that runtime is initialized, GC is okay
}

// Garbage collector phase.
// Indicates to write barrier and synchronization task to perform.
var gcphase uint32

// The compiler knows about this variable.
// If you change it, you must change builtin/runtime.go, too.
// If you change the first four bytes, you must also change the write
// barrier insertion code.
//
// writeBarrier should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
//   - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname writeBarrier
var writeBarrier struct {
	enabled bool    // compiler emits a check of this before calling write barrier
	pad     [3]byte // compiler uses 32-bit load for "enabled" field
	alignme uint64  // guarantee alignment so that compiler can use a 32 or 64-bit load
}

// gcBlackenEnabled is 1 if mutator assists and background mark
// workers are allowed to blacken objects. This must only be set when
// gcphase == _GCmark.
var gcBlackenEnabled uint32

const (
	_GCoff             = iota // GC not running; sweeping in background, write barrier disabled
	_GCmark                   // GC marking roots and workbufs: allocate black, write barrier ENABLED
	_GCmarktermination        // GC mark termination: allocate black, P's help GC, write barrier ENABLED
)

//go:nosplit
func setGCPhase(x uint32) {
	atomic.Store(&gcphase, x)
	writeBarrier.enabled = gcphase == _GCmark || gcphase == _GCmarktermination
}

// gcMarkWorkerMode represents the mode that a concurrent mark worker
// should operate in.
//
// Concurrent marking happens through four different mechanisms. One
// is mutator assists, which happen in response to allocations and are
// not scheduled. The other three are variations in the per-P mark
// workers and are distinguished by gcMarkWorkerMode.
type gcMarkWorkerMode int

const (
	// gcMarkWorkerNotWorker indicates that the next scheduled G is not
	// starting work and the mode should be ignored.
	gcMarkWorkerNotWorker gcMarkWorkerMode = iota

	// gcMarkWorkerDedicatedMode indicates that the P of a mark
	// worker is dedicated to running that mark worker. The mark
	// worker should run without preemption.
	gcMarkWorkerDedicatedMode

	// gcMarkWorkerFractionalMode indicates that a P is currently
	// running the "fractional" mark worker. The fractional worker
	// is necessary when GOMAXPROCS*gcBackgroundUtilization is not
	// an integer and using only dedicated workers would result in
	// utilization too far from the target of gcBackgroundUtilization.
	// The fractional worker should run until it is preempted and
	// will be scheduled to pick up the fractional part of
	// GOMAXPROCS*gcBackgroundUtilization.
	gcMarkWorkerFractionalMode

	// gcMarkWorkerIdleMode indicates that a P is running the mark
	// worker because it has nothing else to do. The idle worker
	// should run until it is preempted and account its time
	// against gcController.idleMarkTime.
	gcMarkWorkerIdleMode
)

// gcMarkWorkerModeStrings are the strings labels of gcMarkWorkerModes
// to use in execution traces.
var gcMarkWorkerModeStrings = [...]string{
	"Not worker",
	"GC (dedicated)",
	"GC (fractional)",
	"GC (idle)",
}

// pollFractionalWorkerExit reports whether a fractional mark worker
// should self-preempt. It assumes it is called from the fractional
// worker.
func pollFractionalWorkerExit() bool {
	// This should be kept in sync with the fractional worker
	// scheduler logic in findRunnableGCWorker.
	now := nanotime()
	delta := now - gcController.markStartTime
	if delta <= 0 {
		return true
	}
	p := getg().m.p.ptr()
	selfTime := p.gcFractionalMarkTime.Load() + (now - p.gcMarkWorkerStartTime)
	// Add some slack to the utilization goal so that the
	// fractional worker isn't behind again the instant it exits.
	return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal
}

var work workType

type workType struct {
	full  lfstack          // lock-free list of full blocks workbuf
	_     cpu.CacheLinePad // prevents false-sharing between full and empty
	empty lfstack          // lock-free list of empty blocks workbuf
	_     cpu.CacheLinePad // prevents false-sharing between empty and wbufSpans

	wbufSpans struct {
		lock mutex
		// free is a list of spans dedicated to workbufs, but
		// that don't currently contain any workbufs.
		free mSpanList
		// busy is a list of all spans containing workbufs on
		// one of the workbuf lists.
		busy mSpanList
	}
	_ cpu.CacheLinePad // prevents false-sharing between wbufSpans and spanWorkMask

	// spanqMask is a bitmap indicating which Ps have local work worth stealing.
	// Set or cleared by the owning P, cleared by stealing Ps.
	//
	// spanqMask is like a proxy for a global queue. An important invariant is that
	// forced flushing like gcw.dispose must set this bit on any P that has local
	// span work.
	spanqMask pMask
	_         cpu.CacheLinePad // prevents false-sharing between spanqMask and everything else

	// List of all spanSPMCs.
	//
	// Only used if goexperiment.GreenTeaGC.
	spanSPMCs struct {
		lock mutex
		list listHeadManual // *spanSPMC
	}

	// Restore 64-bit alignment on 32-bit.
	// _ uint32

	// bytesMarked is the number of bytes marked this cycle. This
	// includes bytes blackened in scanned objects, noscan objects
	// that go straight to black, objects allocated as black during
	// the cycle, and permagrey objects scanned by markroot during
	// the concurrent scan phase.
	//
	// This is updated atomically during the cycle. Updates may be batched
	// arbitrarily, since the value is only read at the end of the cycle.
	//
	// Because of benign races during marking, this number may not
	// be the exact number of marked bytes, but it should be very
	// close.
	//
	// Put this field here because it needs 64-bit atomic access
	// (and thus 8-byte alignment even on 32-bit architectures).
	bytesMarked uint64

	markrootNext atomic.Uint32 // next markroot job
	markrootJobs atomic.Uint32 // number of markroot jobs

	nproc  uint32
	tstart int64
	nwait  uint32

	// Number of roots of various root types. Set by gcPrepareMarkRoots.
	//
	// During normal GC cycle, nStackRoots == nMaybeRunnableStackRoots == len(stackRoots);
	// during goroutine leak detection, nMaybeRunnableStackRoots is the number of stackRoots
	// scheduled for marking.
	// In both variants, nStackRoots == len(stackRoots).
	nDataRoots, nBSSRoots, nSpanRoots, nStackRoots, nMaybeRunnableStackRoots int

	// The following fields monitor the GC phase of the current cycle during
	// goroutine leak detection.
	goroutineLeak struct {
		// Once set, it indicates that the GC will perform goroutine leak detection during
		// the next GC cycle; it is set by goroutineLeakGC and unset during gcStart.
		pending atomic.Bool
		// Once set, it indicates that the GC has started a goroutine leak detection run;
		// it is set during gcStart and unset during gcMarkTermination;
		//
		// Protected by STW.
		enabled bool
		// Once set, it indicates that the GC has performed goroutine leak detection during
		// the current GC cycle; it is set during gcMarkDone, right after goroutine leak detection,
		// and unset during gcMarkTermination;
		//
		// Protected by STW.
		done bool
		// The number of leaked goroutines during the last leak detection GC cycle.
		//
		// Write-protected by STW in findGoroutineLeaks.
		count int
	}

	// Base indexes of each root type. Set by gcPrepareMarkRoots.
	baseData, baseBSS, baseSpans, baseStacks, baseEnd uint32

	// stackRoots is a snapshot of all of the Gs that existed before the
	// beginning of concurrent marking.  During goroutine leak detection, stackRoots
	// is partitioned into two sets; to the left of nMaybeRunnableStackRoots are stackRoots
	// of running / runnable goroutines and to the right of nMaybeRunnableStackRoots are
	// stackRoots of unmarked / not runnable goroutines
	// The stackRoots array is re-partitioned after each marking phase iteration.
	stackRoots []*g

	// Each type of GC state transition is protected by a lock.
	// Since multiple threads can simultaneously detect the state
	// transition condition, any thread that detects a transition
	// condition must acquire the appropriate transition lock,
	// re-check the transition condition and return if it no
	// longer holds or perform the transition if it does.
	// Likewise, any transition must invalidate the transition
	// condition before releasing the lock. This ensures that each
	// transition is performed by exactly one thread and threads
	// that need the transition to happen block until it has
	// happened.
	//
	// startSema protects the transition from "off" to mark or
	// mark termination.
	startSema uint32
	// markDoneSema protects transitions from mark to mark termination.
	markDoneSema uint32

	bgMarkDone uint32 // cas to 1 when at a background mark completion point
	// Background mark completion signaling

	// mode is the concurrency mode of the current GC cycle.
	mode gcMode

	// userForced indicates the current GC cycle was forced by an
	// explicit user call.
	userForced bool

	// initialHeapLive is the value of gcController.heapLive at the
	// beginning of this GC cycle.
	initialHeapLive uint64

	// assistQueue is a queue of assists that are blocked because
	// there was neither enough credit to steal or enough work to
	// do.
	assistQueue struct {
		lock mutex
		q    gQueue
	}

	// sweepWaiters is a list of blocked goroutines to wake when
	// we transition from mark termination to sweep.
	sweepWaiters struct {
		lock mutex
		list gList
	}

	// strongFromWeak controls how the GC interacts with weak->strong
	// pointer conversions.
	strongFromWeak struct {
		// block is a flag set during mark termination that prevents
		// new weak->strong conversions from executing by blocking the
		// goroutine and enqueuing it onto q.
		//
		// Mutated only by one goroutine at a time in gcMarkDone,
		// with globally-synchronizing events like forEachP and
		// stopTheWorld.
		block bool

		// q is a queue of goroutines that attempted to perform a
		// weak->strong conversion during mark termination.
		//
		// Protected by lock.
		lock mutex
		q    gQueue
	}

	// cycles is the number of completed GC cycles, where a GC
	// cycle is sweep termination, mark, mark termination, and
	// sweep. This differs from memstats.numgc, which is
	// incremented at mark termination.
	cycles atomic.Uint32

	// Timing/utilization stats for this cycle.
	stwprocs, maxprocs                 int32
	tSweepTerm, tMark, tMarkTerm, tEnd int64 // nanotime() of phase start

	// pauseNS is the total STW time this cycle, measured as the time between
	// when stopping began (just before trying to stop Ps) and just after the
	// world started again.
	pauseNS int64

	// debug.gctrace heap sizes for this cycle.
	heap0, heap1, heap2 uint64

	// Cumulative estimated CPU usage.
	cpuStats
}

// GC runs a garbage collection and blocks the caller until the
// garbage collection is complete. It may also block the entire
// program.
func GC() {
	// We consider a cycle to be: sweep termination, mark, mark
	// termination, and sweep. This function shouldn't return
	// until a full cycle has been completed, from beginning to
	// end. Hence, we always want to finish up the current cycle
	// and start a new one. That means:
	//
	// 1. In sweep termination, mark, or mark termination of cycle
	// N, wait until mark termination N completes and transitions
	// to sweep N.
	//
	// 2. In sweep N, help with sweep N.
	//
	// At this point we can begin a full cycle N+1.
	//
	// 3. Trigger cycle N+1 by starting sweep termination N+1.
	//
	// 4. Wait for mark termination N+1 to complete.
	//
	// 5. Help with sweep N+1 until it's done.
	//
	// This all has to be written to deal with the fact that the
	// GC may move ahead on its own. For example, when we block
	// until mark termination N, we may wake up in cycle N+2.

	// Wait until the current sweep termination, mark, and mark
	// termination complete.
	n := work.cycles.Load()
	gcWaitOnMark(n)

	// We're now in sweep N or later. Trigger GC cycle N+1, which
	// will first finish sweep N if necessary and then enter sweep
	// termination N+1.
	gcStart(gcTrigger{kind: gcTriggerCycle, n: n + 1})

	// Wait for mark termination N+1 to complete.
	gcWaitOnMark(n + 1)

	// Finish sweep N+1 before returning. We do this both to
	// complete the cycle and because runtime.GC() is often used
	// as part of tests and benchmarks to get the system into a
	// relatively stable and isolated state.
	for work.cycles.Load() == n+1 && sweepone() != ^uintptr(0) {
		Gosched()
	}

	// Callers may assume that the heap profile reflects the
	// just-completed cycle when this returns (historically this
	// happened because this was a STW GC), but right now the
	// profile still reflects mark termination N, not N+1.
	//
	// As soon as all of the sweep frees from cycle N+1 are done,
	// we can go ahead and publish the heap profile.
	//
	// First, wait for sweeping to finish. (We know there are no
	// more spans on the sweep queue, but we may be concurrently
	// sweeping spans, so we have to wait.)
	for work.cycles.Load() == n+1 && !isSweepDone() {
		Gosched()
	}

	// Now we're really done with sweeping, so we can publish the
	// stable heap profile. Only do this if we haven't already hit
	// another mark termination.
	mp := acquirem()
	cycle := work.cycles.Load()
	if cycle == n+1 || (gcphase == _GCmark && cycle == n+2) {
		mProf_PostSweep()
	}
	releasem(mp)
}

// goroutineLeakGC runs a GC cycle that performs goroutine leak detection.
//
//go:linkname goroutineLeakGC runtime/pprof.runtime_goroutineLeakGC
func goroutineLeakGC() {
	// Set the pending flag to true, instructing the next GC cycle to
	// perform goroutine leak detection.
	work.goroutineLeak.pending.Store(true)

	// Spin GC cycles until the pending flag is unset.
	// This ensures that goroutineLeakGC waits for a GC cycle that
	// actually performs goroutine leak detection.
	//
	// This is needed in case multiple concurrent calls to GC
	// are simultaneously fired by the system, wherein some
	// of them are dropped.
	//
	// In the vast majority of cases, only one loop iteration is needed;
	// however, multiple concurrent calls to goroutineLeakGC could lead to
	// the execution of additional GC cycles.
	//
	// Examples:
	//
	// pending? |   G1                    | G2
	// ---------|-------------------------|-----------------------
	//     -    | goroutineLeakGC()       | goroutineLeakGC()
	//     -    | pending.Store(true)     | .
	//     X    | for pending.Load()      | .
	//     X    | GC()                    | .
	//     X    | > gcStart()             | .
	//     X    |   pending.Store(false)  | .
	// ...
	//     -    | > gcMarkDone()          | .
	//     -    |   .                     | pending.Store(true)
	// ...
	//     X    | > gcMarkTermination()   | .
	//     X    |   ...
	//     X    | < GC returns            | .
	//     X    | for pending.Load        | .
	//     X    | GC()                    | .
	//     X    | .                       | for pending.Load()
	//     X    | .                       | GC()
	// ...
	// The first to pick up the pending flag will start a
	// leak detection cycle.
	for work.goroutineLeak.pending.Load() {
		GC()
	}
}

// gcWaitOnMark blocks until GC finishes the Nth mark phase. If GC has
// already completed this mark phase, it returns immediately.
func gcWaitOnMark(n uint32) {
	for {
		// Disable phase transitions.
		lock(&work.sweepWaiters.lock)
		nMarks := work.cycles.Load()
		if gcphase != _GCmark {
			// We've already completed this cycle's mark.
			nMarks++
		}
		if nMarks > n {
			// We're done.
			unlock(&work.sweepWaiters.lock)
			return
		}

		// Wait until sweep termination, mark, and mark
		// termination of cycle N complete.
		work.sweepWaiters.list.push(getg())
		goparkunlock(&work.sweepWaiters.lock, waitReasonWaitForGCCycle, traceBlockUntilGCEnds, 1)
	}
}

// gcMode indicates how concurrent a GC cycle should be.
type gcMode int

const (
	gcBackgroundMode gcMode = iota // concurrent GC and sweep
	gcForceMode                    // stop-the-world GC now, concurrent sweep
	gcForceBlockMode               // stop-the-world GC now and STW sweep (forced by user)
)

// A gcTrigger is a predicate for starting a GC cycle. Specifically,
// it is an exit condition for the _GCoff phase.
type gcTrigger struct {
	kind gcTriggerKind
	now  int64  // gcTriggerTime: current time
	n    uint32 // gcTriggerCycle: cycle number to start
}

type gcTriggerKind int

const (
	// gcTriggerHeap indicates that a cycle should be started when
	// the heap size reaches the trigger heap size computed by the
	// controller.
	gcTriggerHeap gcTriggerKind = iota

	// gcTriggerTime indicates that a cycle should be started when
	// it's been more than forcegcperiod nanoseconds since the
	// previous GC cycle.
	gcTriggerTime

	// gcTriggerCycle indicates that a cycle should be started if
	// we have not yet started cycle number gcTrigger.n (relative
	// to work.cycles).
	gcTriggerCycle
)

// test reports whether the trigger condition is satisfied, meaning
// that the exit condition for the _GCoff phase has been met. The exit
// condition should be tested when allocating.
func (t gcTrigger) test() bool {
	if !memstats.enablegc || panicking.Load() != 0 || gcphase != _GCoff {
		return false
	}
	switch t.kind {
	case gcTriggerHeap:
		trigger, _ := gcController.trigger()
		return gcController.heapLive.Load() >= trigger
	case gcTriggerTime:
		if gcController.gcPercent.Load() < 0 {
			return false
		}
		lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
		return lastgc != 0 && t.now-lastgc > forcegcperiod
	case gcTriggerCycle:
		// t.n > work.cycles, but accounting for wraparound.
		return int32(t.n-work.cycles.Load()) > 0
	}
	return true
}

// gcStart starts the GC. It transitions from _GCoff to _GCmark (if
// debug.gcstoptheworld == 0) or performs all of GC (if
// debug.gcstoptheworld != 0).
//
// This may return without performing this transition in some cases,
// such as when called on a system stack or with locks held.
func gcStart(trigger gcTrigger) {
	// Since this is called from malloc and malloc is called in
	// the guts of a number of libraries that might be holding
	// locks, don't attempt to start GC in non-preemptible or
	// potentially unstable situations.
	mp := acquirem()
	if gp := getg(); gp == mp.g0 || mp.locks > 1 || mp.preemptoff != "" {
		releasem(mp)
		return
	}
	releasem(mp)
	mp = nil

	if gp := getg(); gp.bubble != nil {
		// Disassociate the G from its synctest bubble while allocating.
		// This is less elegant than incrementing the group's active count,
		// but avoids any contamination between GC and synctest.
		bubble := gp.bubble
		gp.bubble = nil
		defer func() {
			gp.bubble = bubble
		}()
	}

	// Pick up the remaining unswept/not being swept spans concurrently
	//
	// This shouldn't happen if we're being invoked in background
	// mode since proportional sweep should have just finished
	// sweeping everything, but rounding errors, etc, may leave a
	// few spans unswept. In forced mode, this is necessary since
	// GC can be forced at any point in the sweeping cycle.
	//
	// We check the transition condition continuously here in case
	// this G gets delayed in to the next GC cycle.
	for trigger.test() && sweepone() != ^uintptr(0) {
	}

	// Perform GC initialization and the sweep termination
	// transition.
	semacquire(&work.startSema)
	// Re-check transition condition under transition lock.
	if !trigger.test() {
		semrelease(&work.startSema)
		return
	}

	// In gcstoptheworld debug mode, upgrade the mode accordingly.
	// We do this after re-checking the transition condition so
	// that multiple goroutines that detect the heap trigger don't
	// start multiple STW GCs.
	mode := gcBackgroundMode
	if debug.gcstoptheworld == 1 {
		mode = gcForceMode
	} else if debug.gcstoptheworld == 2 {
		mode = gcForceBlockMode
	}

	// Ok, we're doing it! Stop everybody else
	semacquire(&gcsema)
	semacquire(&worldsema)

	// For stats, check if this GC was forced by the user.
	// Update it under gcsema to avoid gctrace getting wrong values.
	work.userForced = trigger.kind == gcTriggerCycle

	trace := traceAcquire()
	if trace.ok() {
		trace.GCStart()
		traceRelease(trace)
	}

	// Check and setup per-P state.
	for _, p := range allp {
		// Check that all Ps have finished deferred mcache flushes.
		if fg := p.mcache.flushGen.Load(); fg != mheap_.sweepgen {
			println("runtime: p", p.id, "flushGen", fg, "!= sweepgen", mheap_.sweepgen)
			throw("p mcache not flushed")
		}
		// Initialize ptrBuf if necessary.
		if goexperiment.GreenTeaGC && p.gcw.ptrBuf == nil {
			p.gcw.ptrBuf = (*[gc.PageSize / goarch.PtrSize]uintptr)(persistentalloc(gc.PageSize, goarch.PtrSize, &memstats.gcMiscSys))
		}
	}

	gcBgMarkStartWorkers()

	systemstack(gcResetMarkState)

	work.stwprocs, work.maxprocs = gomaxprocs, gomaxprocs
	if work.stwprocs > numCPUStartup {
		// This is used to compute CPU time of the STW phases, so it
		// can't be more than the CPU count, even if GOMAXPROCS is.
		work.stwprocs = numCPUStartup
	}
	work.heap0 = gcController.heapLive.Load()
	work.pauseNS = 0
	work.mode = mode

	now := nanotime()
	work.tSweepTerm = now
	var stw worldStop
	systemstack(func() {
		stw = stopTheWorldWithSema(stwGCSweepTerm)
	})

	// Accumulate fine-grained stopping time.
	work.cpuStats.accumulateGCPauseTime(stw.stoppingCPUTime, 1)

	if goexperiment.RuntimeSecret {
		// The world is stopped, which means every M is either idle, blocked
		// in a syscall or this M that we are running on now.
		// The blocked Ms had any secret spill on their signal stacks erased
		// when they entered their respective states. Now we have to handle
		// this one.
		eraseSecretsSignalStk()
	}

	// Finish sweep before we start concurrent scan.
	systemstack(func() {
		finishsweep_m()
	})

	// clearpools before we start the GC. If we wait the memory will not be
	// reclaimed until the next GC cycle.
	clearpools()

	work.cycles.Add(1)

	// Assists and workers can start the moment we start
	// the world.
	gcController.startCycle(now, int(gomaxprocs), trigger)

	// Notify the CPU limiter that assists may begin.
	gcCPULimiter.startGCTransition(true, now)

	// In STW mode, disable scheduling of user Gs. This may also
	// disable scheduling of this goroutine, so it may block as
	// soon as we start the world again.
	if mode != gcBackgroundMode {
		schedEnableUser(false)
	}

	// If goroutine leak detection is pending, enable it for this GC cycle.
	if work.goroutineLeak.pending.Load() {
		work.goroutineLeak.enabled = true
		work.goroutineLeak.pending.Store(false)
		// Set all sync objects of blocked goroutines as untraceable
		// by the GC. Only set as traceable at the end of the GC cycle.
		setSyncObjectsUntraceable()
	}

	// Enter concurrent mark phase and enable
	// write barriers.
	//
	// Because the world is stopped, all Ps will
	// observe that write barriers are enabled by
	// the time we start the world and begin
	// scanning.
	//
	// Write barriers must be enabled before assists are
	// enabled because they must be enabled before
	// any non-leaf heap objects are marked. Since
	// allocations are blocked until assists can
	// happen, we want to enable assists as early as
	// possible.
	setGCPhase(_GCmark)

	gcBgMarkPrepare() // Must happen before assists are enabled.
	gcPrepareMarkRoots()

	// Mark all active tinyalloc blocks. Since we're
	// allocating from these, they need to be black like
	// other allocations. The alternative is to blacken
	// the tiny block on every allocation from it, which
	// would slow down the tiny allocator.
	gcMarkTinyAllocs()

	// At this point all Ps have enabled the write
	// barrier, thus maintaining the no white to
	// black invariant. Enable mutator assists to
	// put back-pressure on fast allocating
	// mutators.
	atomic.Store(&gcBlackenEnabled, 1)

	// In STW mode, we could block the instant systemstack
	// returns, so make sure we're not preemptible.
	mp = acquirem()

	// Update the CPU stats pause time.
	//
	// Use maxprocs instead of stwprocs here because the total time
	// computed in the CPU stats is based on maxprocs, and we want them
	// to be comparable.
	work.cpuStats.accumulateGCPauseTime(nanotime()-stw.finishedStopping, work.maxprocs)

	// Concurrent mark.
	systemstack(func() {
		now = startTheWorldWithSema(0, stw)
		work.pauseNS += now - stw.startedStopping
		work.tMark = now

		// Release the CPU limiter.
		gcCPULimiter.finishGCTransition(now)
	})

	// Release the world sema before Gosched() in STW mode
	// because we will need to reacquire it later but before
	// this goroutine becomes runnable again, and we could
	// self-deadlock otherwise.
	semrelease(&worldsema)
	releasem(mp)

	// Make sure we block instead of returning to user code
	// in STW mode.
	if mode != gcBackgroundMode {
		Gosched()
	}

	semrelease(&work.startSema)
}

// gcMarkDoneFlushed counts the number of P's with flushed work.
//
// Ideally this would be a captured local in gcMarkDone, but forEachP
// escapes its callback closure, so it can't capture anything.
//
// This is protected by markDoneSema.
var gcMarkDoneFlushed uint32

// gcDebugMarkDone contains fields used to debug/test mark termination.
var gcDebugMarkDone struct {
	// spinAfterRaggedBarrier forces gcMarkDone to spin after it executes
	// the ragged barrier.
	spinAfterRaggedBarrier atomic.Bool

	// restartedDueTo27993 indicates that we restarted mark termination
	// due to the bug described in issue #27993.
	//
	// Protected by worldsema.
	restartedDueTo27993 bool
}

// gcMarkDone transitions the GC from mark to mark termination if all
// reachable objects have been marked (that is, there are no grey
// objects and can be no more in the future). Otherwise, it flushes
// all local work to the global queues where it can be discovered by
// other workers.
//
// All goroutines performing GC work must call gcBeginWork to signal
// that they're executing GC work. They must call gcEndWork when done.
// This should be called when all local mark work has been drained and
// there are no remaining workers. Specifically, when gcEndWork returns
// true.
//
// The calling context must be preemptible.
//
// Flushing local work is important because idle Ps may have local
// work queued. This is the only way to make that work visible and
// drive GC to completion.
//
// It is explicitly okay to have write barriers in this function. If
// it does transition to mark termination, then all reachable objects
// have been marked, so the write barrier cannot shade any more
// objects.
func gcMarkDone() {
	// Ensure only one thread is running the ragged barrier at a
	// time.
	semacquire(&work.markDoneSema)

top:
	// Re-check transition condition under transition lock.
	//
	// It's critical that this checks the global work queues are
	// empty before performing the ragged barrier. Otherwise,
	// there could be global work that a P could take after the P
	// has passed the ragged barrier.
	if !(gcphase == _GCmark && gcIsMarkDone()) {
		semrelease(&work.markDoneSema)
		return
	}

	// forEachP needs worldsema to execute, and we'll need it to
	// stop the world later, so acquire worldsema now.
	semacquire(&worldsema)

	// Prevent weak->strong conversions from generating additional
	// GC work. forEachP will guarantee that it is observed globally.
	work.strongFromWeak.block = true

	// Flush all local buffers and collect flushedWork flags.
	gcMarkDoneFlushed = 0
	forEachP(waitReasonGCMarkTermination, func(pp *p) {
		// Flush the write barrier buffer, since this may add
		// work to the gcWork.
		wbBufFlush1(pp)

		// Flush the gcWork, since this may create global work
		// and set the flushedWork flag.
		//
		// TODO(austin): Break up these workbufs to
		// better distribute work.
		pp.gcw.dispose()

		// Collect the flushedWork flag.
		if pp.gcw.flushedWork {
			atomic.Xadd(&gcMarkDoneFlushed, 1)
			pp.gcw.flushedWork = false
		}
	})

	if gcMarkDoneFlushed != 0 {
		// More grey objects were discovered since the
		// previous termination check, so there may be more
		// work to do. Keep going. It's possible the
		// transition condition became true again during the
		// ragged barrier, so re-check it.
		semrelease(&worldsema)
		goto top
	}

	// For debugging/testing.
	for gcDebugMarkDone.spinAfterRaggedBarrier.Load() {
	}

	// There was no global work, no local work, and no Ps
	// communicated work since we took markDoneSema. Therefore
	// there are no grey objects and no more objects can be
	// shaded. Transition to mark termination.
	now := nanotime()
	work.tMarkTerm = now
	getg().m.preemptoff = "gcing"
	var stw worldStop
	systemstack(func() {
		stw = stopTheWorldWithSema(stwGCMarkTerm)
	})
	// The gcphase is _GCmark, it will transition to _GCmarktermination
	// below. The important thing is that the wb remains active until
	// all marking is complete. This includes writes made by the GC.

	// Accumulate fine-grained stopping time.
	work.cpuStats.accumulateGCPauseTime(stw.stoppingCPUTime, 1)

	// There is sometimes work left over when we enter mark termination due
	// to write barriers performed after the completion barrier above.
	// Detect this and resume concurrent mark. This is obviously
	// unfortunate.
	//
	// See issue #27993 for details.
	//
	// Switch to the system stack to call wbBufFlush1, though in this case
	// it doesn't matter because we're non-preemptible anyway.
	restart := false
	systemstack(func() {
		for _, p := range allp {
			wbBufFlush1(p)
			if !p.gcw.empty() {
				restart = true
				break
			}
		}
	})

	// Check whether we need to resume the marking phase because of issue #27993
	// or because of goroutine leak detection.
	if restart || (work.goroutineLeak.enabled && !work.goroutineLeak.done) {
		if restart {
			// Restart because of issue #27993.
			gcDebugMarkDone.restartedDueTo27993 = true
		} else {
			// Marking has reached a fixed-point. Attempt to detect goroutine leaks.
			//
			// If the returned value is true, then detection already concluded for this cycle.
			// Otherwise, more runnable goroutines were discovered, requiring additional mark work.
			work.goroutineLeak.done = findGoroutineLeaks()
		}

		getg().m.preemptoff = ""
		systemstack(func() {
			// Accumulate the time we were stopped before we had to start again.
			work.cpuStats.accumulateGCPauseTime(nanotime()-stw.finishedStopping, work.maxprocs)

			// Start the world again.
			now := startTheWorldWithSema(0, stw)
			work.pauseNS += now - stw.startedStopping
		})
		semrelease(&worldsema)
		goto top
	}

	gcComputeStartingStackSize()

	// Disable assists and background workers. We must do
	// this before waking blocked assists.
	atomic.Store(&gcBlackenEnabled, 0)

	// Notify the CPU limiter that GC assists will now cease.
	gcCPULimiter.startGCTransition(false, now)

	// Wake all blocked assists. These will run when we
	// start the world again.
	gcWakeAllAssists()

	// Wake all blocked weak->strong conversions. These will run
	// when we start the world again.
	work.strongFromWeak.block = false
	gcWakeAllStrongFromWeak()

	// Likewise, release the transition lock. Blocked
	// workers and assists will run when we start the
	// world again.
	semrelease(&work.markDoneSema)

	// In STW mode, re-enable user goroutines. These will be
	// queued to run after we start the world.
	schedEnableUser(true)

	// endCycle depends on all gcWork cache stats being flushed.
	// The termination algorithm above ensured that up to
	// allocations since the ragged barrier.
	gcController.endCycle(now, int(gomaxprocs))

	// Perform mark termination. This will restart the world.
	gcMarkTermination(stw)
}

// isMaybeRunnable checks whether a goroutine may still be semantically runnable.
// For goroutines which are semantically runnable, this will eventually return true
// as the GC marking phase progresses. It returns false for leaked goroutines, or for
// goroutines which are not yet computed as possibly runnable by the GC.
func (gp *g) isMaybeRunnable() bool {
	// Check whether the goroutine is actually in a waiting state first.
	if readgstatus(gp) != _Gwaiting {
		// If the goroutine is not waiting, then clearly it is maybe runnable.
		return true
	}

	switch gp.waitreason {
	case waitReasonSelectNoCases,
		waitReasonChanSendNilChan,
		waitReasonChanReceiveNilChan:
		// Select with no cases or communicating on nil channels
		// make goroutines unrunnable by definition.
		return false
	case waitReasonChanReceive,
		waitReasonSelect,
		waitReasonChanSend:
		// Cycle all through all *sudog to check whether
		// the goroutine is waiting on a marked channel.
		for sg := gp.waiting; sg != nil; sg = sg.waitlink {
			if isMarkedOrNotInHeap(unsafe.Pointer(sg.c.get())) {
				return true
			}
		}
		return false
	case waitReasonSyncCondWait,
		waitReasonSyncWaitGroupWait,
		waitReasonSyncMutexLock,
		waitReasonSyncRWMutexLock,
		waitReasonSyncRWMutexRLock:
		// If waiting on mutexes, wait groups, or condition variables,
		// check if the synchronization primitive attached to the sudog is marked.
		if gp.waiting != nil {
			return isMarkedOrNotInHeap(gp.waiting.elem.get())
		}
	}
	return true
}

// findMaybeRunnableGoroutines checks to see if more blocked but maybe-runnable goroutines exist.
// If so, it adds them into root set and increments work.markrootJobs accordingly.
// Returns true if we need to run another phase of markroots; returns false otherwise.
func findMaybeRunnableGoroutines() (moreWork bool) {
	oldRootJobs := work.markrootJobs.Load()

	// To begin with we have a set of unchecked stackRoots between
	// vIndex and ivIndex. During the loop, anything < vIndex should be
	// valid stackRoots and anything >= ivIndex should be invalid stackRoots.
	// The loop terminates when the two indices meet.
	var vIndex, ivIndex int = work.nMaybeRunnableStackRoots, work.nStackRoots
	// Reorder goroutine list
	for vIndex < ivIndex {
		if work.stackRoots[vIndex].isMaybeRunnable() {
			vIndex = vIndex + 1
			continue
		}
		for ivIndex = ivIndex - 1; ivIndex != vIndex; ivIndex = ivIndex - 1 {
			if gp := work.stackRoots[ivIndex]; gp.isMaybeRunnable() {
				work.stackRoots[ivIndex] = work.stackRoots[vIndex]
				work.stackRoots[vIndex] = gp
				vIndex = vIndex + 1
				break
			}
		}
	}

	newRootJobs := work.baseStacks + uint32(vIndex)
	if newRootJobs > oldRootJobs {
		work.nMaybeRunnableStackRoots = vIndex
		work.markrootJobs.Store(newRootJobs)
	}
	return newRootJobs > oldRootJobs
}

// setSyncObjectsUntraceable scans allgs and sets the elem and c fields of all sudogs to
// an untrackable pointer. This prevents the GC from marking these objects as live in memory
// by following these pointers when runnning deadlock detection.
func setSyncObjectsUntraceable() {
	assertWorldStopped()

	forEachGRace(func(gp *g) {
		// Set as untraceable all synchronization objects of goroutines
		// blocked at concurrency operations that could leak.
		switch {
		case gp.waitreason.isSyncWait():
			// Synchronization primitives are reachable from the *sudog via
			// via the elem field.
			for sg := gp.waiting; sg != nil; sg = sg.waitlink {
				sg.elem.setUntraceable()
			}
		case gp.waitreason.isChanWait():
			// Channels and select statements are reachable from the *sudog via the c field.
			for sg := gp.waiting; sg != nil; sg = sg.waitlink {
				sg.c.setUntraceable()
			}
		}
	})
}

// gcRestoreSyncObjects restores the elem and c fields of all sudogs to their original values.
// Should be invoked after the goroutine leak detection phase.
func gcRestoreSyncObjects() {
	assertWorldStopped()

	forEachGRace(func(gp *g) {
		for sg := gp.waiting; sg != nil; sg = sg.waitlink {
			sg.elem.setTraceable()
			sg.c.setTraceable()
		}
	})
}

// findGoroutineLeaks scans the remaining stackRoots and marks any which are
// blocked over exclusively unreachable concurrency primitives as leaked (deadlocked).
// Returns true if the goroutine leak check was performed (or unnecessary).
// Returns false if the GC cycle has not yet computed all maybe-runnable goroutines.
func findGoroutineLeaks() bool {
	assertWorldStopped()

	// Report goroutine leaks and mark them unreachable, and resume marking
	// we still need to mark these unreachable *g structs as they
	// get reused, but their stack won't get scanned
	if work.nMaybeRunnableStackRoots == work.nStackRoots {
		// nMaybeRunnableStackRoots == nStackRoots means that all goroutines are marked.
		return true
	}

	// Check whether any more maybe-runnable goroutines can be found by the GC.
	if findMaybeRunnableGoroutines() {
		// We found more work, so we need to resume the marking phase.
		return false
	}

	// For the remaining goroutines, mark them as unreachable and leaked.
	work.goroutineLeak.count = work.nStackRoots - work.nMaybeRunnableStackRoots

	for i := work.nMaybeRunnableStackRoots; i < work.nStackRoots; i++ {
		gp := work.stackRoots[i]
		casgstatus(gp, _Gwaiting, _Gleaked)

		// Add the primitives causing the goroutine leaks
		// to the GC work queue, to ensure they are marked.
		//
		// NOTE(vsaioc): these primitives should also be reachable
		// from the goroutine's stack, but let's play it safe.
		switch {
		case gp.waitreason.isChanWait():
			for sg := gp.waiting; sg != nil; sg = sg.waitlink {
				shade(sg.c.uintptr())
			}
		case gp.waitreason.isSyncWait():
			for sg := gp.waiting; sg != nil; sg = sg.waitlink {
				shade(sg.elem.uintptr())
			}
		}
	}

	// Do not report the main goroutine if it is waiting on select{}.
	//
	// NOTE: We still treat the main goroutine as leaked during the analysis,
	// but revert its status to _Gwaiting after the analysis to not include
	// it in the goroutine leak profile.
	// This preserves the effectiveness of goroutine leak detection
	// if the main goroutine holds references to concurrency primitives causing
	// other leaks.
	//
	// Example:
	//
	// ```go
	// func main() {
	// 	ch := make(chan int)
	// 	go func() {
	// 		...
	// 		<-ch // Leaks
	// 	}()
	//
	// 	select {}
	// }
	// ```
	//
	// The main goroutine is blocked by select{}, but holds a reference to "ch".
	// Not treating the main goroutine as leaked would cause the analysis to
	// miss the legitimate leak at the child goroutine.
	//
	// The main goroutine should always be allgs[0], but double check
	// in case that invariant changes in the future.
	if gp0 := allgs[0]; gp0.goid == 1 && gp0.waitreason == waitReasonSelectNoCases {
		casgstatus(gp0, _Gleaked, _Gwaiting)
	}

	// Put the remaining roots as ready for marking and drain them.
	work.markrootJobs.Add(int32(work.nStackRoots - work.nMaybeRunnableStackRoots))
	work.nMaybeRunnableStackRoots = work.nStackRoots
	return true
}

// World must be stopped and mark assists and background workers must be
// disabled.
func gcMarkTermination(stw worldStop) {
	// Start marktermination (write barrier remains enabled for now).
	setGCPhase(_GCmarktermination)

	work.heap1 = gcController.heapLive.Load()
	startTime := nanotime()

	mp := acquirem()
	mp.preemptoff = "gcing"
	mp.traceback = 2
	curgp := mp.curg
	// N.B. The execution tracer is not aware of this status
	// transition and handles it specially based on the
	// wait reason.
	casGToWaitingForSuspendG(curgp, _Grunning, waitReasonGarbageCollection)

	// Run gc on the g0 stack. We do this so that the g stack
	// we're currently running on will no longer change. Cuts
	// the root set down a bit (g0 stacks are not scanned, and
	// we don't need to scan gc's internal state).  We also
	// need to switch to g0 so we can shrink the stack.
	systemstack(func() {
		gcMark(startTime)
		// Must return immediately.
		// The outer function's stack may have moved
		// during gcMark (it shrinks stacks, including the
		// outer function's stack), so we must not refer
		// to any of its variables. Return back to the
		// non-system stack to pick up the new addresses
		// before continuing.
	})

	var stwSwept bool
	systemstack(func() {
		work.heap2 = work.bytesMarked
		if debug.gccheckmark > 0 {
			runCheckmark(func(_ *gcWork) { gcPrepareMarkRoots() })
		}
		if debug.checkfinalizers > 0 {
			checkFinalizersAndCleanups()
		}

		// marking is complete so we can turn the write barrier off
		setGCPhase(_GCoff)
		stwSwept = gcSweep(work.mode)
	})

	mp.traceback = 0
	casgstatus(curgp, _Gwaiting, _Grunning)

	trace := traceAcquire()
	if trace.ok() {
		trace.GCDone()
		traceRelease(trace)
	}

	// all done
	mp.preemptoff = ""

	if gcphase != _GCoff {
		throw("gc done but gcphase != _GCoff")
	}

	// Record heapInUse for scavenger.
	memstats.lastHeapInUse = gcController.heapInUse.load()

	// Update GC trigger and pacing, as well as downstream consumers
	// of this pacing information, for the next cycle.
	systemstack(gcControllerCommit)

	// Update timing memstats
	now := nanotime()
	sec, nsec, _ := time_now()
	unixNow := sec*1e9 + int64(nsec)
	work.pauseNS += now - stw.startedStopping
	work.tEnd = now
	atomic.Store64(&memstats.last_gc_unix, uint64(unixNow)) // must be Unix time to make sense to user
	atomic.Store64(&memstats.last_gc_nanotime, uint64(now)) // monotonic time for us
	memstats.pause_ns[memstats.numgc%uint32(len(memstats.pause_ns))] = uint64(work.pauseNS)
	memstats.pause_end[memstats.numgc%uint32(len(memstats.pause_end))] = uint64(unixNow)
	memstats.pause_total_ns += uint64(work.pauseNS)

	// Accumulate CPU stats.
	//
	// Use maxprocs instead of stwprocs for GC pause time because the total time
	// computed in the CPU stats is based on maxprocs, and we want them to be
	// comparable.
	//
	// Pass gcMarkPhase=true to accumulate so we can get all the latest GC CPU stats
	// in there too.
	work.cpuStats.accumulateGCPauseTime(now-stw.finishedStopping, work.maxprocs)
	work.cpuStats.accumulate(now, true)

	// Compute overall GC CPU utilization.
	// Omit idle marking time from the overall utilization here since it's "free".
	memstats.gc_cpu_fraction = float64(work.cpuStats.GCTotalTime-work.cpuStats.GCIdleTime) / float64(work.cpuStats.TotalTime)

	// Reset assist time and background time stats.
	//
	// Do this now, instead of at the start of the next GC cycle, because
	// these two may keep accumulating even if the GC is not active.
	scavenge.assistTime.Store(0)
	scavenge.backgroundTime.Store(0)

	// Reset idle time stat.
	sched.idleTime.Store(0)

	if work.userForced {
		memstats.numforcedgc++
	}

	// Bump GC cycle count and wake goroutines waiting on sweep.
	lock(&work.sweepWaiters.lock)
	memstats.numgc++
	injectglist(&work.sweepWaiters.list)
	unlock(&work.sweepWaiters.lock)

	// Increment the scavenge generation now.
	//
	// This moment represents peak heap in use because we're
	// about to start sweeping.
	mheap_.pages.scav.index.nextGen()

	// Release the CPU limiter.
	gcCPULimiter.finishGCTransition(now)

	// Finish the current heap profiling cycle and start a new
	// heap profiling cycle. We do this before starting the world
	// so events don't leak into the wrong cycle.
	mProf_NextCycle()

	// There may be stale spans in mcaches that need to be swept.
	// Those aren't tracked in any sweep lists, so we need to
	// count them against sweep completion until we ensure all
	// those spans have been forced out.
	//
	// If gcSweep fully swept the heap (for example if the sweep
	// is not concurrent due to a GODEBUG setting), then we expect
	// the sweepLocker to be invalid, since sweeping is done.
	//
	// N.B. Below we might duplicate some work from gcSweep; this is
	// fine as all that work is idempotent within a GC cycle, and
	// we're still holding worldsema so a new cycle can't start.
	sl := sweep.active.begin()
	if !stwSwept && !sl.valid {
		throw("failed to set sweep barrier")
	} else if stwSwept && sl.valid {
		throw("non-concurrent sweep failed to drain all sweep queues")
	}

	if work.goroutineLeak.enabled {
		// Restore the elem and c fields of all sudogs to their original values.
		gcRestoreSyncObjects()
	}

	var goroutineLeakDone bool
	systemstack(func() {
		// Pull the GC out of goroutine leak detection mode.
		work.goroutineLeak.enabled = false
		goroutineLeakDone = work.goroutineLeak.done
		work.goroutineLeak.done = false

		// The memstats updated above must be updated with the world
		// stopped to ensure consistency of some values, such as
		// sched.idleTime and sched.totaltime. memstats also include
		// the pause time (work,pauseNS), forcing computation of the
		// total pause time before the pause actually ends.
		//
		// Here we reuse the same now for start the world so that the
		// time added to /sched/pauses/total/gc:seconds will be
		// consistent with the value in memstats.
		startTheWorldWithSema(now, stw)
	})

	// Flush the heap profile so we can start a new cycle next GC.
	// This is relatively expensive, so we don't do it with the
	// world stopped.
	mProf_Flush()

	// Prepare workbufs for freeing by the sweeper. We do this
	// asynchronously because it can take non-trivial time.
	prepareFreeWorkbufs()

	// Free stack spans. This must be done between GC cycles.
	systemstack(freeStackSpans)

	// Ensure all mcaches are flushed. Each P will flush its own
	// mcache before allocating, but idle Ps may not. Since this
	// is necessary to sweep all spans, we need to ensure all
	// mcaches are flushed before we start the next GC cycle.
	//
	// While we're here, flush the page cache for idle Ps to avoid
	// having pages get stuck on them. These pages are hidden from
	// the scavenger, so in small idle heaps a significant amount
	// of additional memory might be held onto.
	//
	// Also, flush the pinner cache, to avoid leaking that memory
	// indefinitely.
	if debug.gctrace > 1 {
		clear(memstats.lastScanStats[:])
	}
	forEachP(waitReasonFlushProcCaches, func(pp *p) {
		pp.mcache.prepareForSweep()
		if pp.status == _Pidle {
			systemstack(func() {
				lock(&mheap_.lock)
				pp.pcache.flush(&mheap_.pages)
				unlock(&mheap_.lock)
			})
		}
		if debug.gctrace > 1 {
			pp.gcw.flushScanStats(&memstats.lastScanStats)
		}
		pp.pinnerCache = nil
	})
	if sl.valid {
		// Now that we've swept stale spans in mcaches, they don't
		// count against unswept spans.
		//
		// Note: this sweepLocker may not be valid if sweeping had
		// already completed during the STW. See the corresponding
		// begin() call that produced sl.
		sweep.active.end(sl)
	}

	// Print gctrace before dropping worldsema. As soon as we drop
	// worldsema another cycle could start and smash the stats
	// we're trying to print.
	if debug.gctrace > 0 {
		util := int(memstats.gc_cpu_fraction * 100)

		var sbuf [24]byte
		printlock()
		print("gc ", memstats.numgc,
			" @", string(itoaDiv(sbuf[:], uint64(work.tSweepTerm-runtimeInitTime)/1e6, 3)), "s ",
			util, "%")
		if goroutineLeakDone {
			print(" (checking for goroutine leaks)")
		}
		print(": ")
		prev := work.tSweepTerm
		for i, ns := range []int64{work.tMark, work.tMarkTerm, work.tEnd} {
			if i != 0 {
				print("+")
			}
			print(string(fmtNSAsMS(sbuf[:], uint64(ns-prev))))
			prev = ns
		}
		print(" ms clock, ")
		for i, ns := range []int64{
			int64(work.stwprocs) * (work.tMark - work.tSweepTerm),
			gcController.assistTime.Load(),
			gcController.dedicatedMarkTime.Load() + gcController.fractionalMarkTime.Load(),
			gcController.idleMarkTime.Load(),
			int64(work.stwprocs) * (work.tEnd - work.tMarkTerm),
		} {
			if i == 2 || i == 3 {
				// Separate mark time components with /.
				print("/")
			} else if i != 0 {
				print("+")
			}
			print(string(fmtNSAsMS(sbuf[:], uint64(ns))))
		}
		print(" ms cpu, ",
			work.heap0>>20, "->", work.heap1>>20, "->", work.heap2>>20, " MB, ",
			gcController.lastHeapGoal>>20, " MB goal, ",
			gcController.lastStackScan.Load()>>20, " MB stacks, ",
			gcController.globalsScan.Load()>>20, " MB globals, ",
			work.maxprocs, " P")
		if work.userForced {
			print(" (forced)")
		}
		print("\n")

		if debug.gctrace > 1 {
			dumpScanStats()
		}
		printunlock()
	}

	// Print finalizer/cleanup queue length. Like gctrace, do this before the next GC starts.
	// The fact that the next GC might start is not that problematic here, but acts as a convenient
	// lock on printing this information (so it cannot overlap with itself from the next GC cycle).
	if debug.checkfinalizers > 0 {
		fq, fe := finReadQueueStats()
		fn := max(int64(fq)-int64(fe), 0)

		cq, ce := gcCleanups.readQueueStats()
		cn := max(int64(cq)-int64(ce), 0)

		println("checkfinalizers: queue:", fn, "finalizers +", cn, "cleanups")
	}

	// Set any arena chunks that were deferred to fault.
	lock(&userArenaState.lock)
	faultList := userArenaState.fault
	userArenaState.fault = nil
	unlock(&userArenaState.lock)
	for _, lc := range faultList {
		lc.mspan.setUserArenaChunkToFault()
	}

	// Enable huge pages on some metadata if we cross a heap threshold.
	if gcController.heapGoal() > minHeapForMetadataHugePages {
		systemstack(func() {
			mheap_.enableMetadataHugePages()
		})
	}

	semrelease(&worldsema)
	semrelease(&gcsema)
	// Careful: another GC cycle may start now.

	releasem(mp)
	mp = nil

	// now that gc is done, kick off finalizer thread if needed
	if !concurrentSweep {
		// give the queued finalizers, if any, a chance to run
		Gosched()
	}
}

// gcBgMarkStartWorkers prepares background mark worker goroutines. These
// goroutines will not run until the mark phase, but they must be started while
// the work is not stopped and from a regular G stack. The caller must hold
// worldsema.
func gcBgMarkStartWorkers() {
	// Background marking is performed by per-P G's. Ensure that each P has
	// a background GC G.
	//
	// Worker Gs don't exit if gomaxprocs is reduced. If it is raised
	// again, we can reuse the old workers; no need to create new workers.
	if gcBgMarkWorkerCount >= gomaxprocs {
		return
	}

	// Increment mp.locks when allocating. We are called within gcStart,
	// and thus must not trigger another gcStart via an allocation. gcStart
	// bails when allocating with locks held, so simulate that for these
	// allocations.
	//
	// TODO(prattmic): cleanup gcStart to use a more explicit "in gcStart"
	// check for bailing.
	mp := acquirem()
	ready := make(chan struct{}, 1)
	releasem(mp)

	for gcBgMarkWorkerCount < gomaxprocs {
		mp := acquirem() // See above, we allocate a closure here.
		go gcBgMarkWorker(ready)
		releasem(mp)

		// N.B. we intentionally wait on each goroutine individually
		// rather than starting all in a batch and then waiting once
		// afterwards. By running one goroutine at a time, we can take
		// advantage of runnext to bounce back and forth between
		// workers and this goroutine. In an overloaded application,
		// this can reduce GC start latency by prioritizing these
		// goroutines rather than waiting on the end of the run queue.
		<-ready
		// The worker is now guaranteed to be added to the pool before
		// its P's next findRunnableGCWorker.

		gcBgMarkWorkerCount++
	}
}

// gcBgMarkPrepare sets up state for background marking.
// Mutator assists must not yet be enabled.
func gcBgMarkPrepare() {
	// Background marking will stop when the work queues are empty
	// and there are no more workers (note that, since this is
	// concurrent, this may be a transient state, but mark
	// termination will clean it up). Between background workers
	// and assists, we don't really know how many workers there
	// will be, so we pretend to have an arbitrarily large number
	// of workers, almost all of which are "waiting". While a
	// worker is working it decrements nwait. If nproc == nwait,
	// there are no workers.
	work.nproc = ^uint32(0)
	work.nwait = ^uint32(0)
}

// gcBgMarkWorkerNode is an entry in the gcBgMarkWorkerPool. It points to a single
// gcBgMarkWorker goroutine.
type gcBgMarkWorkerNode struct {
	// Unused workers are managed in a lock-free stack. This field must be first.
	node lfnode

	// The g of this worker.
	gp guintptr

	// Release this m on park. This is used to communicate with the unlock
	// function, which cannot access the G's stack. It is unused outside of
	// gcBgMarkWorker().
	m muintptr
}
type gcBgMarkWorkerNodePadded struct {
	gcBgMarkWorkerNode
	pad [tagAlign - unsafe.Sizeof(gcBgMarkWorkerNode{}) - gcBgMarkWorkerNodeRedZoneSize]byte
}

const gcBgMarkWorkerNodeRedZoneSize = (16 << 2) * asanenabledBit // redZoneSize(512)

func gcBgMarkWorker(ready chan struct{}) {
	gp := getg()

	// We pass node to a gopark unlock function, so it can't be on
	// the stack (see gopark). Prevent deadlock from recursively
	// starting GC by disabling preemption.
	gp.m.preemptoff = "GC worker init"
	// TODO: This is technically not allowed in the heap. See comment in tagptr.go.
	//
	// It is kept alive simply by virtue of being used in the infinite loop
	// below. gcBgMarkWorkerPool keeps pointers to nodes that are not
	// GC-visible, so this must be kept alive indefinitely (even if
	// GOMAXPROCS decreases).
	node := &new(gcBgMarkWorkerNodePadded).gcBgMarkWorkerNode
	gp.m.preemptoff = ""

	node.gp.set(gp)

	node.m.set(acquirem())

	ready <- struct{}{}
	// After this point, the background mark worker is generally scheduled
	// cooperatively by gcController.findRunnableGCWorker. While performing
	// work on the P, preemption is disabled because we are working on
	// P-local work buffers. When the preempt flag is set, this puts itself
	// into _Gwaiting to be woken up by gcController.findRunnableGCWorker
	// at the appropriate time.
	//
	// When preemption is enabled (e.g., while in gcMarkDone), this worker
	// may be preempted and schedule as a _Grunnable G from a runq. That is
	// fine; it will eventually gopark again for further scheduling via
	// findRunnableGCWorker.
	//
	// Since we disable preemption before notifying ready, we guarantee that
	// this G will be in the worker pool for the next findRunnableGCWorker.
	// This isn't strictly necessary, but it reduces latency between
	// _GCmark starting and the workers starting.

	for {
		// Go to sleep until woken by
		// gcController.findRunnableGCWorker.
		gopark(func(g *g, nodep unsafe.Pointer) bool {
			node := (*gcBgMarkWorkerNode)(nodep)

			if mp := node.m.ptr(); mp != nil {
				// The worker G is no longer running; release
				// the M.
				//
				// N.B. it is _safe_ to release the M as soon
				// as we are no longer performing P-local mark
				// work.
				//
				// However, since we cooperatively stop work
				// when gp.preempt is set, if we releasem in
				// the loop then the following call to gopark
				// would immediately preempt the G. This is
				// also safe, but inefficient: the G must
				// schedule again only to enter gopark and park
				// again. Thus, we defer the release until
				// after parking the G.
				releasem(mp)
			}

			// Release this G to the pool.
			gcBgMarkWorkerPool.push(&node.node)
			// Note that at this point, the G may immediately be
			// rescheduled and may be running.
			return true
		}, unsafe.Pointer(node), waitReasonGCWorkerIdle, traceBlockSystemGoroutine, 0)

		// Preemption must not occur here, or another G might see
		// p.gcMarkWorkerMode.

		// Disable preemption so we can use the gcw. If the
		// scheduler wants to preempt us, we'll stop draining,
		// dispose the gcw, and then preempt.
		node.m.set(acquirem())
		pp := gp.m.p.ptr() // P can't change with preemption disabled.

		if gcBlackenEnabled == 0 {
			println("worker mode", pp.gcMarkWorkerMode)
			throw("gcBgMarkWorker: blackening not enabled")
		}

		if pp.gcMarkWorkerMode == gcMarkWorkerNotWorker {
			throw("gcBgMarkWorker: mode not set")
		}

		startTime := nanotime()
		pp.gcMarkWorkerStartTime = startTime
		var trackLimiterEvent bool
		if pp.gcMarkWorkerMode == gcMarkWorkerIdleMode {
			trackLimiterEvent = pp.limiterEvent.start(limiterEventIdleMarkWork, startTime)
		}

		gcBeginWork()

		systemstack(func() {
			// Mark our goroutine preemptible so its stack can be scanned or observed
			// by the execution tracer. This, for example, lets two mark workers scan
			// each other (otherwise, they would deadlock).
			//
			// casGToWaitingForSuspendG marks the goroutine as ineligible for a
			// stack shrink, effectively pinning the stack in memory for the duration.
			//
			// N.B. The execution tracer is not aware of this status transition and
			// handles it specially based on the wait reason.
			casGToWaitingForSuspendG(gp, _Grunning, waitReasonGCWorkerActive)
			switch pp.gcMarkWorkerMode {
			default:
				throw("gcBgMarkWorker: unexpected gcMarkWorkerMode")
			case gcMarkWorkerDedicatedMode:
				gcDrainMarkWorkerDedicated(&pp.gcw, true)
				if gp.preempt {
					// We were preempted. This is
					// a useful signal to kick
					// everything out of the run
					// queue so it can run
					// somewhere else.
					if drainQ := runqdrain(pp); !drainQ.empty() {
						lock(&sched.lock)
						globrunqputbatch(&drainQ)
						unlock(&sched.lock)
					}
				}
				// Go back to draining, this time
				// without preemption.
				gcDrainMarkWorkerDedicated(&pp.gcw, false)
			case gcMarkWorkerFractionalMode:
				gcDrainMarkWorkerFractional(&pp.gcw)
			case gcMarkWorkerIdleMode:
				gcDrainMarkWorkerIdle(&pp.gcw)
			}
			casgstatus(gp, _Gwaiting, _Grunning)
		})

		// Account for time and mark us as stopped.
		now := nanotime()
		duration := now - startTime
		gcController.markWorkerStop(pp.gcMarkWorkerMode, duration)
		if trackLimiterEvent {
			pp.limiterEvent.stop(limiterEventIdleMarkWork, now)
		}
		if pp.gcMarkWorkerMode == gcMarkWorkerFractionalMode {
			pp.gcFractionalMarkTime.Add(duration)
		}

		// We'll releasem after this point and thus this P may run
		// something else. We must clear the worker mode to avoid
		// attributing the mode to a different (non-worker) G in
		// tracev2.GoStart.
		pp.gcMarkWorkerMode = gcMarkWorkerNotWorker

		// If this worker reached a background mark completion
		// point, signal the main GC goroutine.
		if gcEndWork() {
			// We don't need the P-local buffers here, allow
			// preemption because we may schedule like a regular
			// goroutine in gcMarkDone (block on locks, etc).
			releasem(node.m.ptr())
			node.m.set(nil)

			gcMarkDone()
		}
	}
}

// gcShouldScheduleWorker reports whether executing a mark worker
// on p is potentially useful. p may be nil.
func gcShouldScheduleWorker(p *p) bool {
	if p != nil && !p.gcw.empty() {
		return true
	}
	return gcMarkWorkAvailable()
}

// gcIsMarkDone reports whether the mark phase is (probably) done.
func gcIsMarkDone() bool {
	return work.nwait == work.nproc && !gcMarkWorkAvailable()
}

// gcBeginWork signals to the garbage collector that a new worker is
// about to process GC work.
func gcBeginWork() {
	decnwait := atomic.Xadd(&work.nwait, -1)
	if decnwait == work.nproc {
		println("runtime: work.nwait=", decnwait, "work.nproc=", work.nproc)
		throw("work.nwait was > work.nproc")
	}
}

// gcEndWork signals to the garbage collector that a new worker has just finished
// its work. It reports whether it was the last worker and there's no more work
// to do. If it returns true, the caller must call gcMarkDone.
func gcEndWork() (last bool) {
	incnwait := atomic.Xadd(&work.nwait, +1)
	if incnwait > work.nproc {
		println("runtime: work.nwait=", incnwait, "work.nproc=", work.nproc)
		throw("work.nwait > work.nproc")
	}
	return incnwait == work.nproc && !gcMarkWorkAvailable()
}

// gcMark runs the mark (or, for concurrent GC, mark termination)
// All gcWork caches must be empty.
// STW is in effect at this point.
func gcMark(startTime int64) {
	if gcphase != _GCmarktermination {
		throw("in gcMark expecting to see gcphase as _GCmarktermination")
	}
	work.tstart = startTime

	// Check that there's no marking work remaining.
	if next, jobs := work.markrootNext.Load(), work.markrootJobs.Load(); work.full != 0 || next < jobs {
		print("runtime: full=", hex(work.full), " next=", next, " jobs=", jobs, " nDataRoots=", work.nDataRoots, " nBSSRoots=", work.nBSSRoots, " nSpanRoots=", work.nSpanRoots, " nStackRoots=", work.nStackRoots, "\n")
		panic("non-empty mark queue after concurrent mark")
	}

	if debug.gccheckmark > 0 {
		// This is expensive when there's a large number of
		// Gs, so only do it if checkmark is also enabled.
		gcMarkRootCheck()
	}

	// Drop allg snapshot. allgs may have grown, in which case
	// this is the only reference to the old backing store and
	// there's no need to keep it around.
	work.stackRoots = nil

	// Clear out buffers and double-check that all gcWork caches
	// are empty. This should be ensured by gcMarkDone before we
	// enter mark termination.
	//
	// TODO: We could clear out buffers just before mark if this
	// has a non-negligible impact on STW time.
	for _, p := range allp {
		// The write barrier may have buffered pointers since
		// the gcMarkDone barrier. However, since the barrier
		// ensured all reachable objects were marked, all of
		// these must be pointers to black objects. Hence we
		// can just discard the write barrier buffer.
		if debug.gccheckmark > 0 {
			// For debugging, flush the buffer and make
			// sure it really was all marked.
			wbBufFlush1(p)
		} else {
			p.wbBuf.reset()
		}

		gcw := &p.gcw
		if !gcw.empty() {
			printlock()
			print("runtime: P ", p.id, " flushedWork ", gcw.flushedWork)
			if gcw.wbuf1 == nil {
				print(" wbuf1=<nil>")
			} else {
				print(" wbuf1.n=", gcw.wbuf1.nobj)
			}
			if gcw.wbuf2 == nil {
				print(" wbuf2=<nil>")
			} else {
				print(" wbuf2.n=", gcw.wbuf2.nobj)
			}
			print("\n")
			throw("P has cached GC work at end of mark termination")
		}
		// There may still be cached empty buffers, which we
		// need to flush since we're going to free them. Also,
		// there may be non-zero stats because we allocated
		// black after the gcMarkDone barrier.
		gcw.dispose()
	}

	// Flush scanAlloc from each mcache since we're about to modify
	// heapScan directly. If we were to flush this later, then scanAlloc
	// might have incorrect information.
	//
	// Note that it's not important to retain this information; we know
	// exactly what heapScan is at this point via scanWork.
	for _, p := range allp {
		c := p.mcache
		if c == nil {
			continue
		}
		c.scanAlloc = 0
	}

	// Reset controller state.
	gcController.resetLive(work.bytesMarked)
}

// gcSweep must be called on the system stack because it acquires the heap
// lock. See mheap for details.
//
// Returns true if the heap was fully swept by this function.
//
// The world must be stopped.
//
//go:systemstack
func gcSweep(mode gcMode) bool {
	assertWorldStopped()

	if gcphase != _GCoff {
		throw("gcSweep being done but phase is not GCoff")
	}

	lock(&mheap_.lock)
	mheap_.sweepgen += 2
	sweep.active.reset()
	mheap_.pagesSwept.Store(0)
	mheap_.sweepArenas = mheap_.heapArenas
	mheap_.reclaimIndex.Store(0)
	mheap_.reclaimCredit.Store(0)
	unlock(&mheap_.lock)

	sweep.centralIndex.clear()

	if !concurrentSweep || mode == gcForceBlockMode {
		// Special case synchronous sweep.
		// Record that no proportional sweeping has to happen.
		lock(&mheap_.lock)
		mheap_.sweepPagesPerByte = 0
		unlock(&mheap_.lock)
		// Flush all mcaches.
		for _, pp := range allp {
			pp.mcache.prepareForSweep()
		}
		// Sweep all spans eagerly.
		for sweepone() != ^uintptr(0) {
		}
		// Free workbufs and span rings eagerly.
		prepareFreeWorkbufs()
		for freeSomeWbufs(false) {
		}
		freeDeadSpanSPMCs()
		// All "free" events for this mark/sweep cycle have
		// now happened, so we can make this profile cycle
		// available immediately.
		mProf_NextCycle()
		mProf_Flush()
		return true
	}

	// Background sweep.
	lock(&sweep.lock)
	if sweep.parked {
		sweep.parked = false
		ready(sweep.g, 0, true)
	}
	unlock(&sweep.lock)
	return false
}

// gcResetMarkState resets global state prior to marking (concurrent
// or STW) and resets the stack scan state of all Gs.
//
// This is safe to do without the world stopped because any Gs created
// during or after this will start out in the reset state.
//
// gcResetMarkState must be called on the system stack because it acquires
// the heap lock. See mheap for details.
//
//go:systemstack
func gcResetMarkState() {
	// This may be called during a concurrent phase, so lock to make sure
	// allgs doesn't change.
	forEachG(func(gp *g) {
		gp.gcscandone = false // set to true in gcphasework
		gp.gcAssistBytes = 0
	})

	// Clear page marks. This is just 1MB per 64GB of heap, so the
	// time here is pretty trivial.
	lock(&mheap_.lock)
	arenas := mheap_.heapArenas
	unlock(&mheap_.lock)
	for _, ai := range arenas {
		ha := mheap_.arenas[ai.l1()][ai.l2()]
		clear(ha.pageMarks[:])
	}

	work.bytesMarked = 0
	work.initialHeapLive = gcController.heapLive.Load()
}

// Hooks for other packages

var poolcleanup func()
var boringCaches []unsafe.Pointer // for crypto/internal/boring

// sync_runtime_registerPoolCleanup should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
//   - github.com/bytedance/gopkg
//   - github.com/songzhibin97/gkit
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup
func sync_runtime_registerPoolCleanup(f func()) {
	poolcleanup = f
}

//go:linkname boring_registerCache crypto/internal/boring/bcache.registerCache
func boring_registerCache(p unsafe.Pointer) {
	boringCaches = append(boringCaches, p)
}

func clearpools() {
	// clear sync.Pools
	if poolcleanup != nil {
		poolcleanup()
	}

	// clear boringcrypto caches
	for _, p := range boringCaches {
		atomicstorep(p, nil)
	}

	// Clear central sudog cache.
	// Leave per-P caches alone, they have strictly bounded size.
	// Disconnect cached list before dropping it on the floor,
	// so that a dangling ref to one entry does not pin all of them.
	lock(&sched.sudoglock)
	var sg, sgnext *sudog
	for sg = sched.sudogcache; sg != nil; sg = sgnext {
		sgnext = sg.next
		sg.next = nil
	}
	sched.sudogcache = nil
	unlock(&sched.sudoglock)

	// Clear central defer pool.
	// Leave per-P pools alone, they have strictly bounded size.
	lock(&sched.deferlock)
	// disconnect cached list before dropping it on the floor,
	// so that a dangling ref to one entry does not pin all of them.
	var d, dlink *_defer
	for d = sched.deferpool; d != nil; d = dlink {
		dlink = d.link
		d.link = nil
	}
	sched.deferpool = nil
	unlock(&sched.deferlock)
}

// Timing

// itoaDiv formats val/(10**dec) into buf.
func itoaDiv(buf []byte, val uint64, dec int) []byte {
	i := len(buf) - 1
	idec := i - dec
	for val >= 10 || i >= idec {
		buf[i] = byte(val%10 + '0')
		i--
		if i == idec {
			buf[i] = '.'
			i--
		}
		val /= 10
	}
	buf[i] = byte(val + '0')
	return buf[i:]
}

// fmtNSAsMS nicely formats ns nanoseconds as milliseconds.
func fmtNSAsMS(buf []byte, ns uint64) []byte {
	if ns >= 10e6 {
		// Format as whole milliseconds.
		return itoaDiv(buf, ns/1e6, 0)
	}
	// Format two digits of precision, with at most three decimal places.
	x := ns / 1e3
	if x == 0 {
		buf[0] = '0'
		return buf[:1]
	}
	dec := 3
	for x >= 100 {
		x /= 10
		dec--
	}
	return itoaDiv(buf, x, dec)
}

// Helpers for testing GC.

// gcTestMoveStackOnNextCall causes the stack to be moved on a call
// immediately following the call to this. It may not work correctly
// if any other work appears after this call (such as returning).
// Typically the following call should be marked go:noinline so it
// performs a stack check.
//
// In rare cases this may not cause the stack to move, specifically if
// there's a preemption between this call and the next.
func gcTestMoveStackOnNextCall() {
	gp := getg()
	gp.stackguard0 = stackForceMove
}

// gcTestIsReachable performs a GC and returns a bit set where bit i
// is set if ptrs[i] is reachable.
func gcTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
	// This takes the pointers as unsafe.Pointers in order to keep
	// them live long enough for us to attach specials. After
	// that, we drop our references to them.

	if len(ptrs) > 64 {
		panic("too many pointers for uint64 mask")
	}

	// Block GC while we attach specials and drop our references
	// to ptrs. Otherwise, if a GC is in progress, it could mark
	// them reachable via this function before we have a chance to
	// drop them.
	semacquire(&gcsema)

	// Create reachability specials for ptrs.
	specials := make([]*specialReachable, len(ptrs))
	for i, p := range ptrs {
		lock(&mheap_.speciallock)
		s := (*specialReachable)(mheap_.specialReachableAlloc.alloc())
		unlock(&mheap_.speciallock)
		s.special.kind = _KindSpecialReachable
		if !addspecial(p, &s.special, false) {
			throw("already have a reachable special (duplicate pointer?)")
		}
		specials[i] = s
		// Make sure we don't retain ptrs.
		ptrs[i] = nil
	}

	semrelease(&gcsema)

	// Force a full GC and sweep.
	GC()

	// Process specials.
	for i, s := range specials {
		if !s.done {
			printlock()
			println("runtime: object", i, "was not swept")
			throw("IsReachable failed")
		}
		if s.reachable {
			mask |= 1 << i
		}
		lock(&mheap_.speciallock)
		mheap_.specialReachableAlloc.free(unsafe.Pointer(s))
		unlock(&mheap_.speciallock)
	}

	return mask
}

// gcTestPointerClass returns the category of what p points to, one of:
// "heap", "stack", "data", "bss", "other". This is useful for checking
// that a test is doing what it's intended to do.
//
// This is nosplit simply to avoid extra pointer shuffling that may
// complicate a test.
//
//go:nosplit
func gcTestPointerClass(p unsafe.Pointer) string {
	p2 := uintptr(noescape(p))
	gp := getg()
	if gp.stack.lo <= p2 && p2 < gp.stack.hi {
		return "stack"
	}
	if base, _, _ := findObject(p2, 0, 0); base != 0 {
		return "heap"
	}
	for _, datap := range activeModules() {
		if datap.data <= p2 && p2 < datap.edata || datap.noptrdata <= p2 && p2 < datap.enoptrdata {
			return "data"
		}
		if datap.bss <= p2 && p2 < datap.ebss || datap.noptrbss <= p2 && p2 <= datap.enoptrbss {
			return "bss"
		}
	}
	KeepAlive(p)
	return "other"
}
