Copyright 2020 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.
GC checkmarks In a concurrent garbage collector, one worries about failing to mark a live object due to mutations without write barriers or bugs in the collector implementation. As a sanity check, the GC has a 'checkmark' mode that retraverses the object graph with the world stopped, to make sure that everything that should be marked is marked.

package runtime

import (
	
	
	
)
A checkmarksMap stores the GC marks in "checkmarks" mode. It is a per-arena bitmap with a bit for every word in the arena. The mark is stored on the bit corresponding to the first word of the marked allocation.go:notinheap
If useCheckmark is true, marking of an object uses the checkmark bits instead of the standard mark bits.
startCheckmarks prepares for the checkmarks phase. The world must be stopped.
Clear all checkmarks.
	for ,  := range mheap_.allArenas {
		 := mheap_.arenas[.l1()][.l2()]
		 := .checkmarks

Allocate bitmap on first use.
			 = (*checkmarksMap)(persistentalloc(unsafe.Sizeof(*), 0, &memstats.gcMiscSys))
			if  == nil {
				throw("out of memory allocating checkmarks bitmap")
			}
			.checkmarks = 
Otherwise clear the existing bitmap.
			for  := range  {
				[] = 0
			}
		}
Enable checkmarking.
endCheckmarks ends the checkmarks phase.
func () {
	if gcMarkWorkAvailable(nil) {
		throw("GC work not flushed")
	}
	useCheckmark = false
}
setCheckmark throws if marking object is a checkmarks violation, and otherwise sets obj's checkmark. It returns true if obj was already checkmarked.
func (, ,  uintptr,  markBits) bool {
	if !.isMarked() {
		printlock()
		print("runtime: checkmarks found unexpected unmarked object obj=", hex(), "\n")
		print("runtime: found obj at *(", hex(), "+", hex(), ")\n")
Dump the source (base) object
		gcDumpObject("base", , )
Dump the object
		gcDumpObject("obj", , ^uintptr(0))

		getg().m.traceback = 2
		throw("checkmark found unmarked object")
	}

	 := arenaIndex()
	 := mheap_.arenas[.l1()][.l2()]
	 := ( / heapArenaBytes / 8) % uintptr(len(.checkmarks))
	 := byte(1 << (( / heapArenaBytes) % 8))
	 := &.checkmarks[]

Already checkmarked.
		return true
	}

	atomic.Or8(, )
	return false