1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Garbage collector: sweeping
6
7// The sweeper consists of two different algorithms:
8//
9// * The object reclaimer finds and frees unmarked slots in spans. It
10//   can free a whole span if none of the objects are marked, but that
11//   isn't its goal. This can be driven either synchronously by
12//   mcentral.cacheSpan for mcentral spans, or asynchronously by
13//   sweepone, which looks at all the mcentral lists.
14//
15// * The span reclaimer looks for spans that contain no marked objects
16//   and frees whole spans. This is a separate algorithm because
17//   freeing whole spans is the hardest task for the object reclaimer,
18//   but is critical when allocating new spans. The entry point for
19//   this is mheap_.reclaim and it's driven by a sequential scan of
20//   the page marks bitmap in the heap arenas.
21//
22// Both algorithms ultimately call mspan.sweep, which sweeps a single
23// heap span.
24
25package runtime
26
27import (
28	"internal/abi"
29	"internal/runtime/atomic"
30	"unsafe"
31)
32
33var sweep sweepdata
34
35// State of background sweep.
36type sweepdata struct {
37	lock   mutex
38	g      *g
39	parked bool
40
41	// active tracks outstanding sweepers and the sweep
42	// termination condition.
43	active activeSweep
44
45	// centralIndex is the current unswept span class.
46	// It represents an index into the mcentral span
47	// sets. Accessed and updated via its load and
48	// update methods. Not protected by a lock.
49	//
50	// Reset at mark termination.
51	// Used by mheap.nextSpanForSweep.
52	centralIndex sweepClass
53}
54
55// sweepClass is a spanClass and one bit to represent whether we're currently
56// sweeping partial or full spans.
57type sweepClass uint32
58
59const (
60	numSweepClasses            = numSpanClasses * 2
61	sweepClassDone  sweepClass = sweepClass(^uint32(0))
62)
63
64func (s *sweepClass) load() sweepClass {
65	return sweepClass(atomic.Load((*uint32)(s)))
66}
67
68func (s *sweepClass) update(sNew sweepClass) {
69	// Only update *s if its current value is less than sNew,
70	// since *s increases monotonically.
71	sOld := s.load()
72	for sOld < sNew && !atomic.Cas((*uint32)(s), uint32(sOld), uint32(sNew)) {
73		sOld = s.load()
74	}
75	// TODO(mknyszek): This isn't the only place we have
76	// an atomic monotonically increasing counter. It would
77	// be nice to have an "atomic max" which is just implemented
78	// as the above on most architectures. Some architectures
79	// like RISC-V however have native support for an atomic max.
80}
81
82func (s *sweepClass) clear() {
83	atomic.Store((*uint32)(s), 0)
84}
85
86// split returns the underlying span class as well as
87// whether we're interested in the full or partial
88// unswept lists for that class, indicated as a boolean
89// (true means "full").
90func (s sweepClass) split() (spc spanClass, full bool) {
91	return spanClass(s >> 1), s&1 == 0
92}
93
94// nextSpanForSweep finds and pops the next span for sweeping from the
95// central sweep buffers. It returns ownership of the span to the caller.
96// Returns nil if no such span exists.
97func (h *mheap) nextSpanForSweep() *mspan {
98	sg := h.sweepgen
99	for sc := sweep.centralIndex.load(); sc < numSweepClasses; sc++ {
100		spc, full := sc.split()
101		c := &h.central[spc].mcentral
102		var s *mspan
103		if full {
104			s = c.fullUnswept(sg).pop()
105		} else {
106			s = c.partialUnswept(sg).pop()
107		}
108		if s != nil {
109			// Write down that we found something so future sweepers
110			// can start from here.
111			sweep.centralIndex.update(sc)
112			return s
113		}
114	}
115	// Write down that we found nothing.
116	sweep.centralIndex.update(sweepClassDone)
117	return nil
118}
119
120const sweepDrainedMask = 1 << 31
121
122// activeSweep is a type that captures whether sweeping
123// is done, and whether there are any outstanding sweepers.
124//
125// Every potential sweeper must call begin() before they look
126// for work, and end() after they've finished sweeping.
127type activeSweep struct {
128	// state is divided into two parts.
129	//
130	// The top bit (masked by sweepDrainedMask) is a boolean
131	// value indicating whether all the sweep work has been
132	// drained from the queue.
133	//
134	// The rest of the bits are a counter, indicating the
135	// number of outstanding concurrent sweepers.
136	state atomic.Uint32
137}
138
139// begin registers a new sweeper. Returns a sweepLocker
140// for acquiring spans for sweeping. Any outstanding sweeper blocks
141// sweep termination.
142//
143// If the sweepLocker is invalid, the caller can be sure that all
144// outstanding sweep work has been drained, so there is nothing left
145// to sweep. Note that there may be sweepers currently running, so
146// this does not indicate that all sweeping has completed.
147//
148// Even if the sweepLocker is invalid, its sweepGen is always valid.
149func (a *activeSweep) begin() sweepLocker {
150	for {
151		state := a.state.Load()
152		if state&sweepDrainedMask != 0 {
153			return sweepLocker{mheap_.sweepgen, false}
154		}
155		if a.state.CompareAndSwap(state, state+1) {
156			return sweepLocker{mheap_.sweepgen, true}
157		}
158	}
159}
160
161// end deregisters a sweeper. Must be called once for each time
162// begin is called if the sweepLocker is valid.
163func (a *activeSweep) end(sl sweepLocker) {
164	if sl.sweepGen != mheap_.sweepgen {
165		throw("sweeper left outstanding across sweep generations")
166	}
167	for {
168		state := a.state.Load()
169		if (state&^sweepDrainedMask)-1 >= sweepDrainedMask {
170			throw("mismatched begin/end of activeSweep")
171		}
172		if a.state.CompareAndSwap(state, state-1) {
173			if state != sweepDrainedMask {
174				return
175			}
176			if debug.gcpacertrace > 0 {
177				live := gcController.heapLive.Load()
178				print("pacer: sweep done at heap size ", live>>20, "MB; allocated ", (live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept.Load(), " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
179			}
180			return
181		}
182	}
183}
184
185// markDrained marks the active sweep cycle as having drained
186// all remaining work. This is safe to be called concurrently
187// with all other methods of activeSweep, though may race.
188//
189// Returns true if this call was the one that actually performed
190// the mark.
191func (a *activeSweep) markDrained() bool {
192	for {
193		state := a.state.Load()
194		if state&sweepDrainedMask != 0 {
195			return false
196		}
197		if a.state.CompareAndSwap(state, state|sweepDrainedMask) {
198			return true
199		}
200	}
201}
202
203// sweepers returns the current number of active sweepers.
204func (a *activeSweep) sweepers() uint32 {
205	return a.state.Load() &^ sweepDrainedMask
206}
207
208// isDone returns true if all sweep work has been drained and no more
209// outstanding sweepers exist. That is, when the sweep phase is
210// completely done.
211func (a *activeSweep) isDone() bool {
212	return a.state.Load() == sweepDrainedMask
213}
214
215// reset sets up the activeSweep for the next sweep cycle.
216//
217// The world must be stopped.
218func (a *activeSweep) reset() {
219	assertWorldStopped()
220	a.state.Store(0)
221}
222
223// finishsweep_m ensures that all spans are swept.
224//
225// The world must be stopped. This ensures there are no sweeps in
226// progress.
227//
228//go:nowritebarrier
229func finishsweep_m() {
230	assertWorldStopped()
231
232	// Sweeping must be complete before marking commences, so
233	// sweep any unswept spans. If this is a concurrent GC, there
234	// shouldn't be any spans left to sweep, so this should finish
235	// instantly. If GC was forced before the concurrent sweep
236	// finished, there may be spans to sweep.
237	for sweepone() != ^uintptr(0) {
238	}
239
240	// Make sure there aren't any outstanding sweepers left.
241	// At this point, with the world stopped, it means one of two
242	// things. Either we were able to preempt a sweeper, or that
243	// a sweeper didn't call sweep.active.end when it should have.
244	// Both cases indicate a bug, so throw.
245	if sweep.active.sweepers() != 0 {
246		throw("active sweepers found at start of mark phase")
247	}
248
249	// Reset all the unswept buffers, which should be empty.
250	// Do this in sweep termination as opposed to mark termination
251	// so that we can catch unswept spans and reclaim blocks as
252	// soon as possible.
253	sg := mheap_.sweepgen
254	for i := range mheap_.central {
255		c := &mheap_.central[i].mcentral
256		c.partialUnswept(sg).reset()
257		c.fullUnswept(sg).reset()
258	}
259
260	// Sweeping is done, so there won't be any new memory to
261	// scavenge for a bit.
262	//
263	// If the scavenger isn't already awake, wake it up. There's
264	// definitely work for it to do at this point.
265	scavenger.wake()
266
267	nextMarkBitArenaEpoch()
268}
269
270func bgsweep(c chan int) {
271	sweep.g = getg()
272
273	lockInit(&sweep.lock, lockRankSweep)
274	lock(&sweep.lock)
275	sweep.parked = true
276	c <- 1
277	goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceBlockGCSweep, 1)
278
279	for {
280		// bgsweep attempts to be a "low priority" goroutine by intentionally
281		// yielding time. It's OK if it doesn't run, because goroutines allocating
282		// memory will sweep and ensure that all spans are swept before the next
283		// GC cycle. We really only want to run when we're idle.
284		//
285		// However, calling Gosched after each span swept produces a tremendous
286		// amount of tracing events, sometimes up to 50% of events in a trace. It's
287		// also inefficient to call into the scheduler so much because sweeping a
288		// single span is in general a very fast operation, taking as little as 30 ns
289		// on modern hardware. (See #54767.)
290		//
291		// As a result, bgsweep sweeps in batches, and only calls into the scheduler
292		// at the end of every batch. Furthermore, it only yields its time if there
293		// isn't spare idle time available on other cores. If there's available idle
294		// time, helping to sweep can reduce allocation latencies by getting ahead of
295		// the proportional sweeper and having spans ready to go for allocation.
296		const sweepBatchSize = 10
297		nSwept := 0
298		for sweepone() != ^uintptr(0) {
299			nSwept++
300			if nSwept%sweepBatchSize == 0 {
301				goschedIfBusy()
302			}
303		}
304		for freeSomeWbufs(true) {
305			// N.B. freeSomeWbufs is already batched internally.
306			goschedIfBusy()
307		}
308		lock(&sweep.lock)
309		if !isSweepDone() {
310			// This can happen if a GC runs between
311			// gosweepone returning ^0 above
312			// and the lock being acquired.
313			unlock(&sweep.lock)
314			continue
315		}
316		sweep.parked = true
317		goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceBlockGCSweep, 1)
318	}
319}
320
321// sweepLocker acquires sweep ownership of spans.
322type sweepLocker struct {
323	// sweepGen is the sweep generation of the heap.
324	sweepGen uint32
325	valid    bool
326}
327
328// sweepLocked represents sweep ownership of a span.
329type sweepLocked struct {
330	*mspan
331}
332
333// tryAcquire attempts to acquire sweep ownership of span s. If it
334// successfully acquires ownership, it blocks sweep completion.
335func (l *sweepLocker) tryAcquire(s *mspan) (sweepLocked, bool) {
336	if !l.valid {
337		throw("use of invalid sweepLocker")
338	}
339	// Check before attempting to CAS.
340	if atomic.Load(&s.sweepgen) != l.sweepGen-2 {
341		return sweepLocked{}, false
342	}
343	// Attempt to acquire sweep ownership of s.
344	if !atomic.Cas(&s.sweepgen, l.sweepGen-2, l.sweepGen-1) {
345		return sweepLocked{}, false
346	}
347	return sweepLocked{s}, true
348}
349
350// sweepone sweeps some unswept heap span and returns the number of pages returned
351// to the heap, or ^uintptr(0) if there was nothing to sweep.
352func sweepone() uintptr {
353	gp := getg()
354
355	// Increment locks to ensure that the goroutine is not preempted
356	// in the middle of sweep thus leaving the span in an inconsistent state for next GC
357	gp.m.locks++
358
359	// TODO(austin): sweepone is almost always called in a loop;
360	// lift the sweepLocker into its callers.
361	sl := sweep.active.begin()
362	if !sl.valid {
363		gp.m.locks--
364		return ^uintptr(0)
365	}
366
367	// Find a span to sweep.
368	npages := ^uintptr(0)
369	var noMoreWork bool
370	for {
371		s := mheap_.nextSpanForSweep()
372		if s == nil {
373			noMoreWork = sweep.active.markDrained()
374			break
375		}
376		if state := s.state.get(); state != mSpanInUse {
377			// This can happen if direct sweeping already
378			// swept this span, but in that case the sweep
379			// generation should always be up-to-date.
380			if !(s.sweepgen == sl.sweepGen || s.sweepgen == sl.sweepGen+3) {
381				print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sl.sweepGen, "\n")
382				throw("non in-use span in unswept list")
383			}
384			continue
385		}
386		if s, ok := sl.tryAcquire(s); ok {
387			// Sweep the span we found.
388			npages = s.npages
389			if s.sweep(false) {
390				// Whole span was freed. Count it toward the
391				// page reclaimer credit since these pages can
392				// now be used for span allocation.
393				mheap_.reclaimCredit.Add(npages)
394			} else {
395				// Span is still in-use, so this returned no
396				// pages to the heap and the span needs to
397				// move to the swept in-use list.
398				npages = 0
399			}
400			break
401		}
402	}
403	sweep.active.end(sl)
404
405	if noMoreWork {
406		// The sweep list is empty. There may still be
407		// concurrent sweeps running, but we're at least very
408		// close to done sweeping.
409
410		// Move the scavenge gen forward (signaling
411		// that there's new work to do) and wake the scavenger.
412		//
413		// The scavenger is signaled by the last sweeper because once
414		// sweeping is done, we will definitely have useful work for
415		// the scavenger to do, since the scavenger only runs over the
416		// heap once per GC cycle. This update is not done during sweep
417		// termination because in some cases there may be a long delay
418		// between sweep done and sweep termination (e.g. not enough
419		// allocations to trigger a GC) which would be nice to fill in
420		// with scavenging work.
421		if debug.scavtrace > 0 {
422			systemstack(func() {
423				lock(&mheap_.lock)
424
425				// Get released stats.
426				releasedBg := mheap_.pages.scav.releasedBg.Load()
427				releasedEager := mheap_.pages.scav.releasedEager.Load()
428
429				// Print the line.
430				printScavTrace(releasedBg, releasedEager, false)
431
432				// Update the stats.
433				mheap_.pages.scav.releasedBg.Add(-releasedBg)
434				mheap_.pages.scav.releasedEager.Add(-releasedEager)
435				unlock(&mheap_.lock)
436			})
437		}
438		scavenger.ready()
439	}
440
441	gp.m.locks--
442	return npages
443}
444
445// isSweepDone reports whether all spans are swept.
446//
447// Note that this condition may transition from false to true at any
448// time as the sweeper runs. It may transition from true to false if a
449// GC runs; to prevent that the caller must be non-preemptible or must
450// somehow block GC progress.
451func isSweepDone() bool {
452	return sweep.active.isDone()
453}
454
455// Returns only when span s has been swept.
456//
457//go:nowritebarrier
458func (s *mspan) ensureSwept() {
459	// Caller must disable preemption.
460	// Otherwise when this function returns the span can become unswept again
461	// (if GC is triggered on another goroutine).
462	gp := getg()
463	if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
464		throw("mspan.ensureSwept: m is not locked")
465	}
466
467	// If this operation fails, then that means that there are
468	// no more spans to be swept. In this case, either s has already
469	// been swept, or is about to be acquired for sweeping and swept.
470	sl := sweep.active.begin()
471	if sl.valid {
472		// The caller must be sure that the span is a mSpanInUse span.
473		if s, ok := sl.tryAcquire(s); ok {
474			s.sweep(false)
475			sweep.active.end(sl)
476			return
477		}
478		sweep.active.end(sl)
479	}
480
481	// Unfortunately we can't sweep the span ourselves. Somebody else
482	// got to it first. We don't have efficient means to wait, but that's
483	// OK, it will be swept fairly soon.
484	for {
485		spangen := atomic.Load(&s.sweepgen)
486		if spangen == sl.sweepGen || spangen == sl.sweepGen+3 {
487			break
488		}
489		osyield()
490	}
491}
492
493// sweep frees or collects finalizers for blocks not marked in the mark phase.
494// It clears the mark bits in preparation for the next GC round.
495// Returns true if the span was returned to heap.
496// If preserve=true, don't return it to heap nor relink in mcentral lists;
497// caller takes care of it.
498func (sl *sweepLocked) sweep(preserve bool) bool {
499	// It's critical that we enter this function with preemption disabled,
500	// GC must not start while we are in the middle of this function.
501	gp := getg()
502	if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
503		throw("mspan.sweep: m is not locked")
504	}
505
506	s := sl.mspan
507	if !preserve {
508		// We'll release ownership of this span. Nil it out to
509		// prevent the caller from accidentally using it.
510		sl.mspan = nil
511	}
512
513	sweepgen := mheap_.sweepgen
514	if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
515		print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
516		throw("mspan.sweep: bad span state")
517	}
518
519	trace := traceAcquire()
520	if trace.ok() {
521		trace.GCSweepSpan(s.npages * _PageSize)
522		traceRelease(trace)
523	}
524
525	mheap_.pagesSwept.Add(int64(s.npages))
526
527	spc := s.spanclass
528	size := s.elemsize
529
530	// The allocBits indicate which unmarked objects don't need to be
531	// processed since they were free at the end of the last GC cycle
532	// and were not allocated since then.
533	// If the allocBits index is >= s.freeindex and the bit
534	// is not marked then the object remains unallocated
535	// since the last GC.
536	// This situation is analogous to being on a freelist.
537
538	// Unlink & free special records for any objects we're about to free.
539	// Two complications here:
540	// 1. An object can have both finalizer and profile special records.
541	//    In such case we need to queue finalizer for execution,
542	//    mark the object as live and preserve the profile special.
543	// 2. A tiny object can have several finalizers setup for different offsets.
544	//    If such object is not marked, we need to queue all finalizers at once.
545	// Both 1 and 2 are possible at the same time.
546	hadSpecials := s.specials != nil
547	siter := newSpecialsIter(s)
548	for siter.valid() {
549		// A finalizer can be set for an inner byte of an object, find object beginning.
550		objIndex := uintptr(siter.s.offset) / size
551		p := s.base() + objIndex*size
552		mbits := s.markBitsForIndex(objIndex)
553		if !mbits.isMarked() {
554			// This object is not marked and has at least one special record.
555			// Pass 1: see if it has a finalizer.
556			hasFinAndRevived := false
557			endOffset := p - s.base() + size
558			for tmp := siter.s; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next {
559				if tmp.kind == _KindSpecialFinalizer {
560					// Stop freeing of object if it has a finalizer.
561					mbits.setMarkedNonAtomic()
562					hasFinAndRevived = true
563					break
564				}
565			}
566			if hasFinAndRevived {
567				// Pass 2: queue all finalizers and clear any weak handles. Weak handles are cleared
568				// before finalization as specified by the internal/weak package. See the documentation
569				// for that package for more details.
570				for siter.valid() && uintptr(siter.s.offset) < endOffset {
571					// Find the exact byte for which the special was setup
572					// (as opposed to object beginning).
573					special := siter.s
574					p := s.base() + uintptr(special.offset)
575					if special.kind == _KindSpecialFinalizer || special.kind == _KindSpecialWeakHandle {
576						siter.unlinkAndNext()
577						freeSpecial(special, unsafe.Pointer(p), size)
578					} else {
579						// All other specials only apply when an object is freed,
580						// so just keep the special record.
581						siter.next()
582					}
583				}
584			} else {
585				// Pass 2: the object is truly dead, free (and handle) all specials.
586				for siter.valid() && uintptr(siter.s.offset) < endOffset {
587					// Find the exact byte for which the special was setup
588					// (as opposed to object beginning).
589					special := siter.s
590					p := s.base() + uintptr(special.offset)
591					siter.unlinkAndNext()
592					freeSpecial(special, unsafe.Pointer(p), size)
593				}
594			}
595		} else {
596			// object is still live
597			if siter.s.kind == _KindSpecialReachable {
598				special := siter.unlinkAndNext()
599				(*specialReachable)(unsafe.Pointer(special)).reachable = true
600				freeSpecial(special, unsafe.Pointer(p), size)
601			} else {
602				// keep special record
603				siter.next()
604			}
605		}
606	}
607	if hadSpecials && s.specials == nil {
608		spanHasNoSpecials(s)
609	}
610
611	if traceAllocFreeEnabled() || debug.clobberfree != 0 || raceenabled || msanenabled || asanenabled {
612		// Find all newly freed objects.
613		mbits := s.markBitsForBase()
614		abits := s.allocBitsForIndex(0)
615		for i := uintptr(0); i < uintptr(s.nelems); i++ {
616			if !mbits.isMarked() && (abits.index < uintptr(s.freeindex) || abits.isMarked()) {
617				x := s.base() + i*s.elemsize
618				if traceAllocFreeEnabled() {
619					trace := traceAcquire()
620					if trace.ok() {
621						trace.HeapObjectFree(x)
622						traceRelease(trace)
623					}
624				}
625				if debug.clobberfree != 0 {
626					clobberfree(unsafe.Pointer(x), size)
627				}
628				// User arenas are handled on explicit free.
629				if raceenabled && !s.isUserArenaChunk {
630					racefree(unsafe.Pointer(x), size)
631				}
632				if msanenabled && !s.isUserArenaChunk {
633					msanfree(unsafe.Pointer(x), size)
634				}
635				if asanenabled && !s.isUserArenaChunk {
636					asanpoison(unsafe.Pointer(x), size)
637				}
638			}
639			mbits.advance()
640			abits.advance()
641		}
642	}
643
644	// Check for zombie objects.
645	if s.freeindex < s.nelems {
646		// Everything < freeindex is allocated and hence
647		// cannot be zombies.
648		//
649		// Check the first bitmap byte, where we have to be
650		// careful with freeindex.
651		obj := uintptr(s.freeindex)
652		if (*s.gcmarkBits.bytep(obj / 8)&^*s.allocBits.bytep(obj / 8))>>(obj%8) != 0 {
653			s.reportZombies()
654		}
655		// Check remaining bytes.
656		for i := obj/8 + 1; i < divRoundUp(uintptr(s.nelems), 8); i++ {
657			if *s.gcmarkBits.bytep(i)&^*s.allocBits.bytep(i) != 0 {
658				s.reportZombies()
659			}
660		}
661	}
662
663	// Count the number of free objects in this span.
664	nalloc := uint16(s.countAlloc())
665	nfreed := s.allocCount - nalloc
666	if nalloc > s.allocCount {
667		// The zombie check above should have caught this in
668		// more detail.
669		print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n")
670		throw("sweep increased allocation count")
671	}
672
673	s.allocCount = nalloc
674	s.freeindex = 0 // reset allocation index to start of span.
675	s.freeIndexForScan = 0
676	if traceEnabled() {
677		getg().m.p.ptr().trace.reclaimed += uintptr(nfreed) * s.elemsize
678	}
679
680	// gcmarkBits becomes the allocBits.
681	// get a fresh cleared gcmarkBits in preparation for next GC
682	s.allocBits = s.gcmarkBits
683	s.gcmarkBits = newMarkBits(uintptr(s.nelems))
684
685	// refresh pinnerBits if they exists
686	if s.pinnerBits != nil {
687		s.refreshPinnerBits()
688	}
689
690	// Initialize alloc bits cache.
691	s.refillAllocCache(0)
692
693	// The span must be in our exclusive ownership until we update sweepgen,
694	// check for potential races.
695	if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
696		print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
697		throw("mspan.sweep: bad span state after sweep")
698	}
699	if s.sweepgen == sweepgen+1 || s.sweepgen == sweepgen+3 {
700		throw("swept cached span")
701	}
702
703	// We need to set s.sweepgen = h.sweepgen only when all blocks are swept,
704	// because of the potential for a concurrent free/SetFinalizer.
705	//
706	// But we need to set it before we make the span available for allocation
707	// (return it to heap or mcentral), because allocation code assumes that a
708	// span is already swept if available for allocation.
709	//
710	// Serialization point.
711	// At this point the mark bits are cleared and allocation ready
712	// to go so release the span.
713	atomic.Store(&s.sweepgen, sweepgen)
714
715	if s.isUserArenaChunk {
716		if preserve {
717			// This is a case that should never be handled by a sweeper that
718			// preserves the span for reuse.
719			throw("sweep: tried to preserve a user arena span")
720		}
721		if nalloc > 0 {
722			// There still exist pointers into the span or the span hasn't been
723			// freed yet. It's not ready to be reused. Put it back on the
724			// full swept list for the next cycle.
725			mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
726			return false
727		}
728
729		// It's only at this point that the sweeper doesn't actually need to look
730		// at this arena anymore, so subtract from pagesInUse now.
731		mheap_.pagesInUse.Add(-s.npages)
732		s.state.set(mSpanDead)
733
734		// The arena is ready to be recycled. Remove it from the quarantine list
735		// and place it on the ready list. Don't add it back to any sweep lists.
736		systemstack(func() {
737			// It's the arena code's responsibility to get the chunk on the quarantine
738			// list by the time all references to the chunk are gone.
739			if s.list != &mheap_.userArena.quarantineList {
740				throw("user arena span is on the wrong list")
741			}
742			lock(&mheap_.lock)
743			mheap_.userArena.quarantineList.remove(s)
744			mheap_.userArena.readyList.insert(s)
745			unlock(&mheap_.lock)
746		})
747		return false
748	}
749
750	if spc.sizeclass() != 0 {
751		// Handle spans for small objects.
752		if nfreed > 0 {
753			// Only mark the span as needing zeroing if we've freed any
754			// objects, because a fresh span that had been allocated into,
755			// wasn't totally filled, but then swept, still has all of its
756			// free slots zeroed.
757			s.needzero = 1
758			stats := memstats.heapStats.acquire()
759			atomic.Xadd64(&stats.smallFreeCount[spc.sizeclass()], int64(nfreed))
760			memstats.heapStats.release()
761
762			// Count the frees in the inconsistent, internal stats.
763			gcController.totalFree.Add(int64(nfreed) * int64(s.elemsize))
764		}
765		if !preserve {
766			// The caller may not have removed this span from whatever
767			// unswept set its on but taken ownership of the span for
768			// sweeping by updating sweepgen. If this span still is in
769			// an unswept set, then the mcentral will pop it off the
770			// set, check its sweepgen, and ignore it.
771			if nalloc == 0 {
772				// Free totally free span directly back to the heap.
773				mheap_.freeSpan(s)
774				return true
775			}
776			// Return span back to the right mcentral list.
777			if nalloc == s.nelems {
778				mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
779			} else {
780				mheap_.central[spc].mcentral.partialSwept(sweepgen).push(s)
781			}
782		}
783	} else if !preserve {
784		// Handle spans for large objects.
785		if nfreed != 0 {
786			// Free large object span to heap.
787
788			// Count the free in the consistent, external stats.
789			//
790			// Do this before freeSpan, which might update heapStats' inHeap
791			// value. If it does so, then metrics that subtract object footprint
792			// from inHeap might overflow. See #67019.
793			stats := memstats.heapStats.acquire()
794			atomic.Xadd64(&stats.largeFreeCount, 1)
795			atomic.Xadd64(&stats.largeFree, int64(size))
796			memstats.heapStats.release()
797
798			// Count the free in the inconsistent, internal stats.
799			gcController.totalFree.Add(int64(size))
800
801			// NOTE(rsc,dvyukov): The original implementation of efence
802			// in CL 22060046 used sysFree instead of sysFault, so that
803			// the operating system would eventually give the memory
804			// back to us again, so that an efence program could run
805			// longer without running out of memory. Unfortunately,
806			// calling sysFree here without any kind of adjustment of the
807			// heap data structures means that when the memory does
808			// come back to us, we have the wrong metadata for it, either in
809			// the mspan structures or in the garbage collection bitmap.
810			// Using sysFault here means that the program will run out of
811			// memory fairly quickly in efence mode, but at least it won't
812			// have mysterious crashes due to confused memory reuse.
813			// It should be possible to switch back to sysFree if we also
814			// implement and then call some kind of mheap.deleteSpan.
815			if debug.efence > 0 {
816				s.limit = 0 // prevent mlookup from finding this span
817				sysFault(unsafe.Pointer(s.base()), size)
818			} else {
819				mheap_.freeSpan(s)
820			}
821			if s.largeType != nil && s.largeType.TFlag&abi.TFlagUnrolledBitmap != 0 {
822				// The unrolled GCProg bitmap is allocated separately.
823				// Free the space for the unrolled bitmap.
824				systemstack(func() {
825					s := spanOf(uintptr(unsafe.Pointer(s.largeType)))
826					mheap_.freeManual(s, spanAllocPtrScalarBits)
827				})
828				// Make sure to zero this pointer without putting the old
829				// value in a write buffer, as the old value might be an
830				// invalid pointer. See arena.go:(*mheap).allocUserArenaChunk.
831				*(*uintptr)(unsafe.Pointer(&s.largeType)) = 0
832			}
833			return true
834		}
835
836		// Add a large span directly onto the full+swept list.
837		mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
838	}
839	return false
840}
841
842// reportZombies reports any marked but free objects in s and throws.
843//
844// This generally means one of the following:
845//
846// 1. User code converted a pointer to a uintptr and then back
847// unsafely, and a GC ran while the uintptr was the only reference to
848// an object.
849//
850// 2. User code (or a compiler bug) constructed a bad pointer that
851// points to a free slot, often a past-the-end pointer.
852//
853// 3. The GC two cycles ago missed a pointer and freed a live object,
854// but it was still live in the last cycle, so this GC cycle found a
855// pointer to that object and marked it.
856func (s *mspan) reportZombies() {
857	printlock()
858	print("runtime: marked free object in span ", s, ", elemsize=", s.elemsize, " freeindex=", s.freeindex, " (bad use of unsafe.Pointer? try -d=checkptr)\n")
859	mbits := s.markBitsForBase()
860	abits := s.allocBitsForIndex(0)
861	for i := uintptr(0); i < uintptr(s.nelems); i++ {
862		addr := s.base() + i*s.elemsize
863		print(hex(addr))
864		alloc := i < uintptr(s.freeindex) || abits.isMarked()
865		if alloc {
866			print(" alloc")
867		} else {
868			print(" free ")
869		}
870		if mbits.isMarked() {
871			print(" marked  ")
872		} else {
873			print(" unmarked")
874		}
875		zombie := mbits.isMarked() && !alloc
876		if zombie {
877			print(" zombie")
878		}
879		print("\n")
880		if zombie {
881			length := s.elemsize
882			if length > 1024 {
883				length = 1024
884			}
885			hexdumpWords(addr, addr+length, nil)
886		}
887		mbits.advance()
888		abits.advance()
889	}
890	throw("found pointer to free object")
891}
892
893// deductSweepCredit deducts sweep credit for allocating a span of
894// size spanBytes. This must be performed *before* the span is
895// allocated to ensure the system has enough credit. If necessary, it
896// performs sweeping to prevent going in to debt. If the caller will
897// also sweep pages (e.g., for a large allocation), it can pass a
898// non-zero callerSweepPages to leave that many pages unswept.
899//
900// deductSweepCredit makes a worst-case assumption that all spanBytes
901// bytes of the ultimately allocated span will be available for object
902// allocation.
903//
904// deductSweepCredit is the core of the "proportional sweep" system.
905// It uses statistics gathered by the garbage collector to perform
906// enough sweeping so that all pages are swept during the concurrent
907// sweep phase between GC cycles.
908//
909// mheap_ must NOT be locked.
910func deductSweepCredit(spanBytes uintptr, callerSweepPages uintptr) {
911	if mheap_.sweepPagesPerByte == 0 {
912		// Proportional sweep is done or disabled.
913		return
914	}
915
916	trace := traceAcquire()
917	if trace.ok() {
918		trace.GCSweepStart()
919		traceRelease(trace)
920	}
921
922	// Fix debt if necessary.
923retry:
924	sweptBasis := mheap_.pagesSweptBasis.Load()
925	live := gcController.heapLive.Load()
926	liveBasis := mheap_.sweepHeapLiveBasis
927	newHeapLive := spanBytes
928	if liveBasis < live {
929		// Only do this subtraction when we don't overflow. Otherwise, pagesTarget
930		// might be computed as something really huge, causing us to get stuck
931		// sweeping here until the next mark phase.
932		//
933		// Overflow can happen here if gcPaceSweeper is called concurrently with
934		// sweeping (i.e. not during a STW, like it usually is) because this code
935		// is intentionally racy. A concurrent call to gcPaceSweeper can happen
936		// if a GC tuning parameter is modified and we read an older value of
937		// heapLive than what was used to set the basis.
938		//
939		// This state should be transient, so it's fine to just let newHeapLive
940		// be a relatively small number. We'll probably just skip this attempt to
941		// sweep.
942		//
943		// See issue #57523.
944		newHeapLive += uintptr(live - liveBasis)
945	}
946	pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
947	for pagesTarget > int64(mheap_.pagesSwept.Load()-sweptBasis) {
948		if sweepone() == ^uintptr(0) {
949			mheap_.sweepPagesPerByte = 0
950			break
951		}
952		if mheap_.pagesSweptBasis.Load() != sweptBasis {
953			// Sweep pacing changed. Recompute debt.
954			goto retry
955		}
956	}
957
958	trace = traceAcquire()
959	if trace.ok() {
960		trace.GCSweepDone()
961		traceRelease(trace)
962	}
963}
964
965// clobberfree sets the memory content at x to bad content, for debugging
966// purposes.
967func clobberfree(x unsafe.Pointer, size uintptr) {
968	// size (span.elemsize) is always a multiple of 4.
969	for i := uintptr(0); i < size; i += 4 {
970		*(*uint32)(add(x, i)) = 0xdeadbeef
971	}
972}
973
974// gcPaceSweeper updates the sweeper's pacing parameters.
975//
976// Must be called whenever the GC's pacing is updated.
977//
978// The world must be stopped, or mheap_.lock must be held.
979func gcPaceSweeper(trigger uint64) {
980	assertWorldStoppedOrLockHeld(&mheap_.lock)
981
982	// Update sweep pacing.
983	if isSweepDone() {
984		mheap_.sweepPagesPerByte = 0
985	} else {
986		// Concurrent sweep needs to sweep all of the in-use
987		// pages by the time the allocated heap reaches the GC
988		// trigger. Compute the ratio of in-use pages to sweep
989		// per byte allocated, accounting for the fact that
990		// some might already be swept.
991		heapLiveBasis := gcController.heapLive.Load()
992		heapDistance := int64(trigger) - int64(heapLiveBasis)
993		// Add a little margin so rounding errors and
994		// concurrent sweep are less likely to leave pages
995		// unswept when GC starts.
996		heapDistance -= 1024 * 1024
997		if heapDistance < _PageSize {
998			// Avoid setting the sweep ratio extremely high
999			heapDistance = _PageSize
1000		}
1001		pagesSwept := mheap_.pagesSwept.Load()
1002		pagesInUse := mheap_.pagesInUse.Load()
1003		sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
1004		if sweepDistancePages <= 0 {
1005			mheap_.sweepPagesPerByte = 0
1006		} else {
1007			mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
1008			mheap_.sweepHeapLiveBasis = heapLiveBasis
1009			// Write pagesSweptBasis last, since this
1010			// signals concurrent sweeps to recompute
1011			// their debt.
1012			mheap_.pagesSweptBasis.Store(pagesSwept)
1013		}
1014	}
1015}
1016