mirror of
https://github.com/golang/go.git
synced 2025-11-10 13:41:05 +00:00
runtime: add GODEBUG=gccheckmark=0/1
Previously, gccheckmark could only be enabled or disabled by calling runtime.GCcheckmarkenable/GCcheckmarkdisable. This was a necessary hack because GODEBUG was broken. Now that GODEBUG works again, move control over gccheckmark to a GODEBUG variable and remove these runtime functions. Currently, gccheckmark is enabled by default (and will probably remain so for much of the 1.5 development cycle). Change-Id: I2bc6f30c21b795264edf7dbb6bd7354b050673ab Reviewed-on: https://go-review.googlesource.com/2603 Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
86fdcbedbc
commit
654297cb02
5 changed files with 18 additions and 27 deletions
|
|
@ -247,5 +247,3 @@ pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK = 35
|
||||||
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK ideal-int
|
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK ideal-int
|
||||||
pkg runtime (openbsd-amd64-cgo), const HW_NCPU = 3
|
pkg runtime (openbsd-amd64-cgo), const HW_NCPU = 3
|
||||||
pkg runtime (openbsd-amd64-cgo), const HW_NCPU ideal-int
|
pkg runtime (openbsd-amd64-cgo), const HW_NCPU ideal-int
|
||||||
pkg runtime, func GCcheckmarkdisable()
|
|
||||||
pkg runtime, func GCcheckmarkenable()
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,12 @@ a comma-separated list of name=val pairs. Supported names are:
|
||||||
problem with allocfreetrace=1 in order to understand the type
|
problem with allocfreetrace=1 in order to understand the type
|
||||||
of the badly updated word.
|
of the badly updated word.
|
||||||
|
|
||||||
|
gccheckmark: setting gccheckmark=1 enables verification of the
|
||||||
|
garbage collector's concurrent mark phase by performing a
|
||||||
|
second mark pass while the world is stopped. If the second
|
||||||
|
pass finds a reachable object that was not found by concurrent
|
||||||
|
mark, the garbage collector will panic.
|
||||||
|
|
||||||
The GOMAXPROCS variable limits the number of operating system threads that
|
The GOMAXPROCS variable limits the number of operating system threads that
|
||||||
can execute user-level Go code simultaneously. There is no limit to the number of threads
|
can execute user-level Go code simultaneously. There is no limit to the number of threads
|
||||||
that can be blocked in system calls on behalf of Go code; those do not count against
|
that can be blocked in system calls on behalf of Go code; those do not count against
|
||||||
|
|
|
||||||
|
|
@ -611,14 +611,6 @@ func gcwork(force int32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GCcheckmarkenable() {
|
|
||||||
systemstack(gccheckmarkenable_m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GCcheckmarkdisable() {
|
|
||||||
systemstack(gccheckmarkdisable_m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// gctimes records the time in nanoseconds of each phase of the concurrent GC.
|
// gctimes records the time in nanoseconds of each phase of the concurrent GC.
|
||||||
type gctimes struct {
|
type gctimes struct {
|
||||||
sweepterm int64 // stw
|
sweepterm int64 // stw
|
||||||
|
|
|
||||||
|
|
@ -236,10 +236,7 @@ func have_cgo_allocate() bool {
|
||||||
// When marking an object if the bool checkmark is true one uses the above
|
// When marking an object if the bool checkmark is true one uses the above
|
||||||
// encoding, otherwise one uses the bitMarked bit in the lower two bits
|
// encoding, otherwise one uses the bitMarked bit in the lower two bits
|
||||||
// of the nibble.
|
// of the nibble.
|
||||||
var (
|
var checkmark = false
|
||||||
checkmark = false
|
|
||||||
gccheckmarkenable = true
|
|
||||||
)
|
|
||||||
|
|
||||||
// inheap reports whether b is a pointer into a (potentially dead) heap object.
|
// inheap reports whether b is a pointer into a (potentially dead) heap object.
|
||||||
// It returns false for pointers into stack spans.
|
// It returns false for pointers into stack spans.
|
||||||
|
|
@ -559,7 +556,7 @@ func scanobject(b, n uintptr, ptrmask *uint8, wbuf *workbuf) *workbuf {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if mheap_.shadow_enabled && debug.wbshadow >= 2 && gccheckmarkenable && checkmark {
|
if mheap_.shadow_enabled && debug.wbshadow >= 2 && debug.gccheckmark > 0 && checkmark {
|
||||||
checkwbshadow((*uintptr)(unsafe.Pointer(b + i)))
|
checkwbshadow((*uintptr)(unsafe.Pointer(b + i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1856,7 +1853,7 @@ func clearcheckmarkbits() {
|
||||||
// bitMarked bit that is not set then we throw.
|
// bitMarked bit that is not set then we throw.
|
||||||
//go:nowritebarrier
|
//go:nowritebarrier
|
||||||
func gccheckmark_m(startTime int64, eagersweep bool) {
|
func gccheckmark_m(startTime int64, eagersweep bool) {
|
||||||
if !gccheckmarkenable {
|
if debug.gccheckmark == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1869,16 +1866,6 @@ func gccheckmark_m(startTime int64, eagersweep bool) {
|
||||||
gc_m(startTime, eagersweep) // turns off checkmark + calls clearcheckmarkbits
|
gc_m(startTime, eagersweep) // turns off checkmark + calls clearcheckmarkbits
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:nowritebarrier
|
|
||||||
func gccheckmarkenable_m() {
|
|
||||||
gccheckmarkenable = true
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:nowritebarrier
|
|
||||||
func gccheckmarkdisable_m() {
|
|
||||||
gccheckmarkenable = false
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:nowritebarrier
|
//go:nowritebarrier
|
||||||
func finishsweep_m() {
|
func finishsweep_m() {
|
||||||
// The world is stopped so we should be able to complete the sweeps
|
// The world is stopped so we should be able to complete the sweeps
|
||||||
|
|
@ -1987,6 +1974,9 @@ func gc(start_time int64, eagersweep bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !checkmark {
|
if !checkmark {
|
||||||
|
// TODO(austin) This is a noop beceause we should
|
||||||
|
// already have swept everything to the current
|
||||||
|
// sweepgen.
|
||||||
finishsweep_m() // skip during checkmark debug phase.
|
finishsweep_m() // skip during checkmark debug phase.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2107,7 +2097,7 @@ func gc(start_time int64, eagersweep bool) {
|
||||||
sysFree(unsafe.Pointer(&work.spans[0]), uintptr(len(work.spans))*unsafe.Sizeof(work.spans[0]), &memstats.other_sys)
|
sysFree(unsafe.Pointer(&work.spans[0]), uintptr(len(work.spans))*unsafe.Sizeof(work.spans[0]), &memstats.other_sys)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gccheckmarkenable {
|
if debug.gccheckmark > 0 {
|
||||||
if !checkmark {
|
if !checkmark {
|
||||||
// first half of two-pass; don't set up sweep
|
// first half of two-pass; don't set up sweep
|
||||||
unlock(&mheap_.lock)
|
unlock(&mheap_.lock)
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,7 @@ var debug struct {
|
||||||
scheddetail int32
|
scheddetail int32
|
||||||
schedtrace int32
|
schedtrace int32
|
||||||
wbshadow int32
|
wbshadow int32
|
||||||
|
gccheckmark int32
|
||||||
}
|
}
|
||||||
|
|
||||||
var dbgvars = []dbgVar{
|
var dbgvars = []dbgVar{
|
||||||
|
|
@ -329,9 +330,13 @@ var dbgvars = []dbgVar{
|
||||||
{"scheddetail", &debug.scheddetail},
|
{"scheddetail", &debug.scheddetail},
|
||||||
{"schedtrace", &debug.schedtrace},
|
{"schedtrace", &debug.schedtrace},
|
||||||
{"wbshadow", &debug.wbshadow},
|
{"wbshadow", &debug.wbshadow},
|
||||||
|
{"gccheckmark", &debug.gccheckmark},
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsedebugvars() {
|
func parsedebugvars() {
|
||||||
|
// gccheckmark is enabled by default for the 1.5 dev cycle
|
||||||
|
debug.gccheckmark = 1
|
||||||
|
|
||||||
for p := gogetenv("GODEBUG"); p != ""; {
|
for p := gogetenv("GODEBUG"); p != ""; {
|
||||||
field := ""
|
field := ""
|
||||||
i := index(p, ",")
|
i := index(p, ",")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue