diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go index 35bc12db22..7bc4278195 100644 --- a/src/runtime/mgcwork.go +++ b/src/runtime/mgcwork.go @@ -11,8 +11,7 @@ import ( ) const ( - _Debugwbufs = false // if true check wbufs consistency - _WorkbufSize = 2048 // in bytes; larger values result in less contention + _WorkbufSize = 2048 // in bytes; larger values result in less contention ) // Garbage collector work pool abstraction. @@ -86,10 +85,10 @@ type gcWork struct { } func (w *gcWork) init() { - w.wbuf1 = wbufptrOf(getempty(101)) - wbuf2 := trygetfull(102) + w.wbuf1 = wbufptrOf(getempty()) + wbuf2 := trygetfull() if wbuf2 == nil { - wbuf2 = getempty(103) + wbuf2 = getempty() } w.wbuf2 = wbufptrOf(wbuf2) } @@ -107,8 +106,8 @@ func (w *gcWork) put(obj uintptr) { w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 wbuf = w.wbuf1.ptr() if wbuf.nobj == len(wbuf.obj) { - putfull(wbuf, 132) - wbuf = getempty(133) + putfull(wbuf) + wbuf = getempty() w.wbuf1 = wbufptrOf(wbuf) } } @@ -135,11 +134,11 @@ func (w *gcWork) tryGet() uintptr { wbuf = w.wbuf1.ptr() if wbuf.nobj == 0 { owbuf := wbuf - wbuf = trygetfull(167) + wbuf = trygetfull() if wbuf == nil { return 0 } - putempty(owbuf, 166) + putempty(owbuf) w.wbuf1 = wbufptrOf(wbuf) } } @@ -164,11 +163,11 @@ func (w *gcWork) get() uintptr { wbuf = w.wbuf1.ptr() if wbuf.nobj == 0 { owbuf := wbuf - wbuf = getfull(185) + wbuf = getfull() if wbuf == nil { return 0 } - putempty(owbuf, 184) + putempty(owbuf) w.wbuf1 = wbufptrOf(wbuf) } } @@ -189,17 +188,17 @@ func (w *gcWork) get() uintptr { func (w *gcWork) dispose() { if wbuf := w.wbuf1.ptr(); wbuf != nil { if wbuf.nobj == 0 { - putempty(wbuf, 212) + putempty(wbuf) } else { - putfull(wbuf, 214) + putfull(wbuf) } w.wbuf1 = 0 wbuf = w.wbuf2.ptr() if wbuf.nobj == 0 { - putempty(wbuf, 218) + putempty(wbuf) } else { - putfull(wbuf, 220) + putfull(wbuf) } w.wbuf2 = 0 } @@ -225,8 +224,8 @@ func (w *gcWork) balance() { return } if wbuf := w.wbuf2.ptr(); wbuf.nobj != 0 { - putfull(wbuf, 246) - w.wbuf2 = wbufptrOf(getempty(247)) + putfull(wbuf) + w.wbuf2 = wbufptrOf(getempty()) } else if wbuf := w.wbuf1.ptr(); wbuf.nobj > 4 { w.wbuf1 = wbufptrOf(handoff(wbuf)) } @@ -243,10 +242,8 @@ func (w *gcWork) empty() bool { // avoid contending on the global work buffer lists. type workbufhdr struct { - node lfnode // must be first - nobj int - inuse bool // This workbuf is in use by some goroutine and is not on the work.empty/full queues. - log [4]int // line numbers forming a history of ownership changes to workbuf + node lfnode // must be first + nobj int } type workbuf struct { @@ -259,69 +256,23 @@ type workbuf struct { // workbufs. // If the GC asks for some work these are the only routines that // make wbufs available to the GC. -// Each of the gets and puts also take an distinct integer that is used -// to record a brief history of changes to ownership of the workbuf. -// The convention is to use a unique line number but any encoding -// is permissible. For example if you want to pass in 2 bits of information -// you could simple add lineno1*100000+lineno2. - -// logget records the past few values of entry to aid in debugging. -// logget checks the buffer b is not currently in use. -func (b *workbuf) logget(entry int) { - if !_Debugwbufs { - return - } - if b.inuse { - println("runtime: logget fails log entry=", entry, - "b.log[0]=", b.log[0], "b.log[1]=", b.log[1], - "b.log[2]=", b.log[2], "b.log[3]=", b.log[3]) - throw("logget: get not legal") - } - b.inuse = true - copy(b.log[1:], b.log[:]) - b.log[0] = entry -} - -// logput records the past few values of entry to aid in debugging. -// logput checks the buffer b is currently in use. -func (b *workbuf) logput(entry int) { - if !_Debugwbufs { - return - } - if !b.inuse { - println("runtime: logput fails log entry=", entry, - "b.log[0]=", b.log[0], "b.log[1]=", b.log[1], - "b.log[2]=", b.log[2], "b.log[3]=", b.log[3]) - throw("logput: put not legal") - } - b.inuse = false - copy(b.log[1:], b.log[:]) - b.log[0] = entry -} func (b *workbuf) checknonempty() { if b.nobj == 0 { - println("runtime: nonempty check fails", - "b.log[0]=", b.log[0], "b.log[1]=", b.log[1], - "b.log[2]=", b.log[2], "b.log[3]=", b.log[3]) throw("workbuf is empty") } } func (b *workbuf) checkempty() { if b.nobj != 0 { - println("runtime: empty check fails", - "b.log[0]=", b.log[0], "b.log[1]=", b.log[1], - "b.log[2]=", b.log[2], "b.log[3]=", b.log[3]) throw("workbuf is not empty") } } // getempty pops an empty work buffer off the work.empty list, // allocating new buffers if none are available. -// entry is used to record a brief history of ownership. //go:nowritebarrier -func getempty(entry int) *workbuf { +func getempty() *workbuf { var b *workbuf if work.empty != 0 { b = (*workbuf)(lfstackpop(&work.empty)) @@ -332,16 +283,14 @@ func getempty(entry int) *workbuf { if b == nil { b = (*workbuf)(persistentalloc(unsafe.Sizeof(*b), sys.CacheLineSize, &memstats.gc_sys)) } - b.logget(entry) return b } // putempty puts a workbuf onto the work.empty list. // Upon entry this go routine owns b. The lfstackpush relinquishes ownership. //go:nowritebarrier -func putempty(b *workbuf, entry int) { +func putempty(b *workbuf) { b.checkempty() - b.logput(entry) lfstackpush(&work.empty, &b.node) } @@ -349,9 +298,8 @@ func putempty(b *workbuf, entry int) { // putfull accepts partially full buffers so the GC can avoid competing // with the mutators for ownership of partially full buffers. //go:nowritebarrier -func putfull(b *workbuf, entry int) { +func putfull(b *workbuf) { b.checknonempty() - b.logput(entry) lfstackpush(&work.full, &b.node) // We just made more work available. Let the GC controller @@ -364,10 +312,9 @@ func putfull(b *workbuf, entry int) { // trygetfull tries to get a full or partially empty workbuffer. // If one is not immediately available return nil //go:nowritebarrier -func trygetfull(entry int) *workbuf { +func trygetfull() *workbuf { b := (*workbuf)(lfstackpop(&work.full)) if b != nil { - b.logget(entry) b.checknonempty() return b } @@ -386,10 +333,9 @@ func trygetfull(entry int) *workbuf { // This is in fact the termination condition for the STW mark // phase. //go:nowritebarrier -func getfull(entry int) *workbuf { +func getfull() *workbuf { b := (*workbuf)(lfstackpop(&work.full)) if b != nil { - b.logget(entry) b.checknonempty() return b } @@ -408,7 +354,6 @@ func getfull(entry int) *workbuf { } b = (*workbuf)(lfstackpop(&work.full)) if b != nil { - b.logget(entry) b.checknonempty() return b } @@ -438,7 +383,7 @@ func getfull(entry int) *workbuf { //go:nowritebarrier func handoff(b *workbuf) *workbuf { // Make new buffer with half of b's pointers. - b1 := getempty(915) + b1 := getempty() n := b.nobj / 2 b.nobj -= n b1.nobj = n @@ -448,6 +393,6 @@ func handoff(b *workbuf) *workbuf { _g_.m.gcstats.nhandoffcnt += uint64(n) // Put b on full list - let first half of b get stolen. - putfull(b, 942) + putfull(b) return b1 }