// 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 runtimeimport ()// 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.typecheckmarksMapstruct { _ sys.NotInHeapb [heapArenaBytes / goarch.PtrSize / 8]uint8}// If useCheckmark is true, marking of an object uses the checkmark// bits instead of the standard mark bits.varuseCheckmark = false// startCheckmarks prepares for the checkmarks phase.//// The world must be stopped.func () {assertWorldStopped()// Clear all checkmarks.for , := rangemheap_.allArenas { := mheap_.arenas[.l1()][.l2()] := .checkmarksif == nil {// Allocate bitmap on first use. = (*checkmarksMap)(persistentalloc(unsafe.Sizeof(*), 0, &memstats.gcMiscSys))if == nil {throw("out of memory allocating checkmarks bitmap") } .checkmarks = } else {// Otherwise clear the existing bitmap.for := range .b { .b[] = 0 } } }// Enable checkmarking.useCheckmark = true}// endCheckmarks ends the checkmarks phase.func () {ifgcMarkWorkAvailable(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) objectgcDumpObject("base", , )// Dump the objectgcDumpObject("obj", , ^uintptr(0))getg().m.traceback = 2throw("checkmark found unmarked object") } := arenaIndex() := mheap_.arenas[.l1()][.l2()] := ( / heapArenaBytes / 8) % uintptr(len(.checkmarks.b)) := byte(1 << (( / heapArenaBytes) % 8)) := &.checkmarks.b[]ifatomic.Load8()& != 0 {// Already checkmarked.returntrue }atomic.Or8(, )returnfalse}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.