From 98da2d1f91a8f4e6bdaecd8a98fc77cbac211c80 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Sun, 29 Jan 2017 22:47:27 -0500 Subject: [PATCH] runtime: remove wbufptr Since workbuf is now marked go:notinheap, the write barrier-preventing wrapper type wbufptr is no longer necessary. Remove it. Change-Id: I3e5b5803a1547d65de1c1a9c22458a38e08549b7 Reviewed-on: https://go-review.googlesource.com/35971 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/mgcwork.go | 69 +++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go index 5eb05a767c..ef2453039f 100644 --- a/src/runtime/mgcwork.go +++ b/src/runtime/mgcwork.go @@ -25,21 +25,6 @@ const ( // grey objects, thus blackening them, and then scans them, // potentially producing new pointers to grey objects. -// A wbufptr holds a workbuf*, but protects it from write barriers. -// workbufs never live on the heap, so write barriers are unnecessary. -// Write barriers on workbuf pointers may also be dangerous in the GC. -// -// TODO: Since workbuf is now go:notinheap, this isn't necessary. -type wbufptr uintptr - -func wbufptrOf(w *workbuf) wbufptr { - return wbufptr(unsafe.Pointer(w)) -} - -func (wp wbufptr) ptr() *workbuf { - return (*workbuf)(unsafe.Pointer(wp)) -} - // A gcWork provides the interface to produce and consume work for the // garbage collector. // @@ -75,7 +60,7 @@ type gcWork struct { // next. // // Invariant: Both wbuf1 and wbuf2 are nil or neither are. - wbuf1, wbuf2 wbufptr + wbuf1, wbuf2 *workbuf // Bytes marked (blackened) on this gcWork. This is aggregated // into work.bytesMarked by dispose. @@ -87,12 +72,12 @@ type gcWork struct { } func (w *gcWork) init() { - w.wbuf1 = wbufptrOf(getempty()) + w.wbuf1 = getempty() wbuf2 := trygetfull() if wbuf2 == nil { wbuf2 = getempty() } - w.wbuf2 = wbufptrOf(wbuf2) + w.wbuf2 = wbuf2 } // put enqueues a pointer for the garbage collector to trace. @@ -100,18 +85,18 @@ func (w *gcWork) init() { //go:nowritebarrier func (w *gcWork) put(obj uintptr) { flushed := false - wbuf := w.wbuf1.ptr() + wbuf := w.wbuf1 if wbuf == nil { w.init() - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 // wbuf is empty at this point. } else if wbuf.nobj == len(wbuf.obj) { w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 if wbuf.nobj == len(wbuf.obj) { putfull(wbuf) wbuf = getempty() - w.wbuf1 = wbufptrOf(wbuf) + w.wbuf1 = wbuf flushed = true } } @@ -132,7 +117,7 @@ func (w *gcWork) put(obj uintptr) { // otherwise it returns false and the caller needs to call put. //go:nowritebarrier func (w *gcWork) putFast(obj uintptr) bool { - wbuf := w.wbuf1.ptr() + wbuf := w.wbuf1 if wbuf == nil { return false } else if wbuf.nobj == len(wbuf.obj) { @@ -151,15 +136,15 @@ func (w *gcWork) putFast(obj uintptr) bool { // other gcWork instances or other caches. //go:nowritebarrier func (w *gcWork) tryGet() uintptr { - wbuf := w.wbuf1.ptr() + wbuf := w.wbuf1 if wbuf == nil { w.init() - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 // wbuf is empty at this point. } if wbuf.nobj == 0 { w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 if wbuf.nobj == 0 { owbuf := wbuf wbuf = trygetfull() @@ -167,7 +152,7 @@ func (w *gcWork) tryGet() uintptr { return 0 } putempty(owbuf) - w.wbuf1 = wbufptrOf(wbuf) + w.wbuf1 = wbuf } } @@ -180,7 +165,7 @@ func (w *gcWork) tryGet() uintptr { // the caller is expected to call tryGet(). //go:nowritebarrier func (w *gcWork) tryGetFast() uintptr { - wbuf := w.wbuf1.ptr() + wbuf := w.wbuf1 if wbuf == nil { return 0 } @@ -197,15 +182,15 @@ func (w *gcWork) tryGetFast() uintptr { // been retrieved. get returns 0 if there are no pointers remaining. //go:nowritebarrier func (w *gcWork) get() uintptr { - wbuf := w.wbuf1.ptr() + wbuf := w.wbuf1 if wbuf == nil { w.init() - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 // wbuf is empty at this point. } if wbuf.nobj == 0 { w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 - wbuf = w.wbuf1.ptr() + wbuf = w.wbuf1 if wbuf.nobj == 0 { owbuf := wbuf wbuf = getfull() @@ -213,7 +198,7 @@ func (w *gcWork) get() uintptr { return 0 } putempty(owbuf) - w.wbuf1 = wbufptrOf(wbuf) + w.wbuf1 = wbuf } } @@ -231,21 +216,21 @@ func (w *gcWork) get() uintptr { // //go:nowritebarrier func (w *gcWork) dispose() { - if wbuf := w.wbuf1.ptr(); wbuf != nil { + if wbuf := w.wbuf1; wbuf != nil { if wbuf.nobj == 0 { putempty(wbuf) } else { putfull(wbuf) } - w.wbuf1 = 0 + w.wbuf1 = nil - wbuf = w.wbuf2.ptr() + wbuf = w.wbuf2 if wbuf.nobj == 0 { putempty(wbuf) } else { putfull(wbuf) } - w.wbuf2 = 0 + w.wbuf2 = nil } if w.bytesMarked != 0 { // dispose happens relatively infrequently. If this @@ -265,14 +250,14 @@ func (w *gcWork) dispose() { // global queue. //go:nowritebarrier func (w *gcWork) balance() { - if w.wbuf1 == 0 { + if w.wbuf1 == nil { return } - if wbuf := w.wbuf2.ptr(); wbuf.nobj != 0 { + if wbuf := w.wbuf2; wbuf.nobj != 0 { putfull(wbuf) - w.wbuf2 = wbufptrOf(getempty()) - } else if wbuf := w.wbuf1.ptr(); wbuf.nobj > 4 { - w.wbuf1 = wbufptrOf(handoff(wbuf)) + w.wbuf2 = getempty() + } else if wbuf := w.wbuf1; wbuf.nobj > 4 { + w.wbuf1 = handoff(wbuf) } else { return } @@ -285,7 +270,7 @@ func (w *gcWork) balance() { // empty returns true if w has no mark work available. //go:nowritebarrier func (w *gcWork) empty() bool { - return w.wbuf1 == 0 || (w.wbuf1.ptr().nobj == 0 && w.wbuf2.ptr().nobj == 0) + return w.wbuf1 == nil || (w.wbuf1.nobj == 0 && w.wbuf2.nobj == 0) } // Internally, the GC work pool is kept in arrays in work buffers. -- 2.48.1