Commit 98da2d1f authored by Austin Clements's avatar Austin Clements

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 <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent 8eb14e9d
...@@ -25,21 +25,6 @@ const ( ...@@ -25,21 +25,6 @@ const (
// grey objects, thus blackening them, and then scans them, // grey objects, thus blackening them, and then scans them,
// potentially producing new pointers to grey objects. // 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 // A gcWork provides the interface to produce and consume work for the
// garbage collector. // garbage collector.
// //
...@@ -75,7 +60,7 @@ type gcWork struct { ...@@ -75,7 +60,7 @@ type gcWork struct {
// next. // next.
// //
// Invariant: Both wbuf1 and wbuf2 are nil or neither are. // 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 // Bytes marked (blackened) on this gcWork. This is aggregated
// into work.bytesMarked by dispose. // into work.bytesMarked by dispose.
...@@ -87,12 +72,12 @@ type gcWork struct { ...@@ -87,12 +72,12 @@ type gcWork struct {
} }
func (w *gcWork) init() { func (w *gcWork) init() {
w.wbuf1 = wbufptrOf(getempty()) w.wbuf1 = getempty()
wbuf2 := trygetfull() wbuf2 := trygetfull()
if wbuf2 == nil { if wbuf2 == nil {
wbuf2 = getempty() wbuf2 = getempty()
} }
w.wbuf2 = wbufptrOf(wbuf2) w.wbuf2 = wbuf2
} }
// put enqueues a pointer for the garbage collector to trace. // put enqueues a pointer for the garbage collector to trace.
...@@ -100,18 +85,18 @@ func (w *gcWork) init() { ...@@ -100,18 +85,18 @@ func (w *gcWork) init() {
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) put(obj uintptr) { func (w *gcWork) put(obj uintptr) {
flushed := false flushed := false
wbuf := w.wbuf1.ptr() wbuf := w.wbuf1
if wbuf == nil { if wbuf == nil {
w.init() w.init()
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
// wbuf is empty at this point. // wbuf is empty at this point.
} else if wbuf.nobj == len(wbuf.obj) { } else if wbuf.nobj == len(wbuf.obj) {
w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
if wbuf.nobj == len(wbuf.obj) { if wbuf.nobj == len(wbuf.obj) {
putfull(wbuf) putfull(wbuf)
wbuf = getempty() wbuf = getempty()
w.wbuf1 = wbufptrOf(wbuf) w.wbuf1 = wbuf
flushed = true flushed = true
} }
} }
...@@ -132,7 +117,7 @@ func (w *gcWork) put(obj uintptr) { ...@@ -132,7 +117,7 @@ func (w *gcWork) put(obj uintptr) {
// otherwise it returns false and the caller needs to call put. // otherwise it returns false and the caller needs to call put.
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) putFast(obj uintptr) bool { func (w *gcWork) putFast(obj uintptr) bool {
wbuf := w.wbuf1.ptr() wbuf := w.wbuf1
if wbuf == nil { if wbuf == nil {
return false return false
} else if wbuf.nobj == len(wbuf.obj) { } else if wbuf.nobj == len(wbuf.obj) {
...@@ -151,15 +136,15 @@ func (w *gcWork) putFast(obj uintptr) bool { ...@@ -151,15 +136,15 @@ func (w *gcWork) putFast(obj uintptr) bool {
// other gcWork instances or other caches. // other gcWork instances or other caches.
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) tryGet() uintptr { func (w *gcWork) tryGet() uintptr {
wbuf := w.wbuf1.ptr() wbuf := w.wbuf1
if wbuf == nil { if wbuf == nil {
w.init() w.init()
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
// wbuf is empty at this point. // wbuf is empty at this point.
} }
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
owbuf := wbuf owbuf := wbuf
wbuf = trygetfull() wbuf = trygetfull()
...@@ -167,7 +152,7 @@ func (w *gcWork) tryGet() uintptr { ...@@ -167,7 +152,7 @@ func (w *gcWork) tryGet() uintptr {
return 0 return 0
} }
putempty(owbuf) putempty(owbuf)
w.wbuf1 = wbufptrOf(wbuf) w.wbuf1 = wbuf
} }
} }
...@@ -180,7 +165,7 @@ func (w *gcWork) tryGet() uintptr { ...@@ -180,7 +165,7 @@ func (w *gcWork) tryGet() uintptr {
// the caller is expected to call tryGet(). // the caller is expected to call tryGet().
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) tryGetFast() uintptr { func (w *gcWork) tryGetFast() uintptr {
wbuf := w.wbuf1.ptr() wbuf := w.wbuf1
if wbuf == nil { if wbuf == nil {
return 0 return 0
} }
...@@ -197,15 +182,15 @@ func (w *gcWork) tryGetFast() uintptr { ...@@ -197,15 +182,15 @@ func (w *gcWork) tryGetFast() uintptr {
// been retrieved. get returns 0 if there are no pointers remaining. // been retrieved. get returns 0 if there are no pointers remaining.
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) get() uintptr { func (w *gcWork) get() uintptr {
wbuf := w.wbuf1.ptr() wbuf := w.wbuf1
if wbuf == nil { if wbuf == nil {
w.init() w.init()
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
// wbuf is empty at this point. // wbuf is empty at this point.
} }
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1 w.wbuf1, w.wbuf2 = w.wbuf2, w.wbuf1
wbuf = w.wbuf1.ptr() wbuf = w.wbuf1
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
owbuf := wbuf owbuf := wbuf
wbuf = getfull() wbuf = getfull()
...@@ -213,7 +198,7 @@ func (w *gcWork) get() uintptr { ...@@ -213,7 +198,7 @@ func (w *gcWork) get() uintptr {
return 0 return 0
} }
putempty(owbuf) putempty(owbuf)
w.wbuf1 = wbufptrOf(wbuf) w.wbuf1 = wbuf
} }
} }
...@@ -231,21 +216,21 @@ func (w *gcWork) get() uintptr { ...@@ -231,21 +216,21 @@ func (w *gcWork) get() uintptr {
// //
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) dispose() { func (w *gcWork) dispose() {
if wbuf := w.wbuf1.ptr(); wbuf != nil { if wbuf := w.wbuf1; wbuf != nil {
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
putempty(wbuf) putempty(wbuf)
} else { } else {
putfull(wbuf) putfull(wbuf)
} }
w.wbuf1 = 0 w.wbuf1 = nil
wbuf = w.wbuf2.ptr() wbuf = w.wbuf2
if wbuf.nobj == 0 { if wbuf.nobj == 0 {
putempty(wbuf) putempty(wbuf)
} else { } else {
putfull(wbuf) putfull(wbuf)
} }
w.wbuf2 = 0 w.wbuf2 = nil
} }
if w.bytesMarked != 0 { if w.bytesMarked != 0 {
// dispose happens relatively infrequently. If this // dispose happens relatively infrequently. If this
...@@ -265,14 +250,14 @@ func (w *gcWork) dispose() { ...@@ -265,14 +250,14 @@ func (w *gcWork) dispose() {
// global queue. // global queue.
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) balance() { func (w *gcWork) balance() {
if w.wbuf1 == 0 { if w.wbuf1 == nil {
return return
} }
if wbuf := w.wbuf2.ptr(); wbuf.nobj != 0 { if wbuf := w.wbuf2; wbuf.nobj != 0 {
putfull(wbuf) putfull(wbuf)
w.wbuf2 = wbufptrOf(getempty()) w.wbuf2 = getempty()
} else if wbuf := w.wbuf1.ptr(); wbuf.nobj > 4 { } else if wbuf := w.wbuf1; wbuf.nobj > 4 {
w.wbuf1 = wbufptrOf(handoff(wbuf)) w.wbuf1 = handoff(wbuf)
} else { } else {
return return
} }
...@@ -285,7 +270,7 @@ func (w *gcWork) balance() { ...@@ -285,7 +270,7 @@ func (w *gcWork) balance() {
// empty returns true if w has no mark work available. // empty returns true if w has no mark work available.
//go:nowritebarrier //go:nowritebarrier
func (w *gcWork) empty() bool { 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. // Internally, the GC work pool is kept in arrays in work buffers.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment