Commit f5e67e53 authored by Austin Clements's avatar Austin Clements

runtime: allow GC drain whenever write barrier is enabled

Currently we hand-code a set of phases when draining is allowed.
However, this set of phases is conservative. The critical invariant is
simply that the write barrier must be enabled if we're draining.

Shortly we're going to enable mutator assists during the scan phase,
which means we may drain during the scan phase. In preparation, this
commit generalizes these assertions to check the fundamental condition
that the write barrier is enabled, rather than checking that we're in
any particular phase.

Change-Id: I0e1bec1ca823d4a697a0831ec4c50f5dd3f2a893
Reviewed-on: https://go-review.googlesource.com/12673Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 64a32ffe
...@@ -644,8 +644,8 @@ func setNextBarrierPC(pc uintptr) { ...@@ -644,8 +644,8 @@ func setNextBarrierPC(pc uintptr) {
// credit exceeds flushScanCredit. // credit exceeds flushScanCredit.
//go:nowritebarrier //go:nowritebarrier
func gcDrain(gcw *gcWork, flushScanCredit int64) { func gcDrain(gcw *gcWork, flushScanCredit int64) {
if gcphase != _GCmark && gcphase != _GCmarktermination { if !writeBarrierEnabled {
throw("scanblock phase incorrect") throw("gcDrain phase incorrect")
} }
var lastScanFlush, nextScanFlush int64 var lastScanFlush, nextScanFlush int64
...@@ -696,7 +696,7 @@ func gcDrain(gcw *gcWork, flushScanCredit int64) { ...@@ -696,7 +696,7 @@ func gcDrain(gcw *gcWork, flushScanCredit int64) {
// get work, even though there may be more work in the system. // get work, even though there may be more work in the system.
//go:nowritebarrier //go:nowritebarrier
func gcDrainUntilPreempt(gcw *gcWork, flushScanCredit int64) { func gcDrainUntilPreempt(gcw *gcWork, flushScanCredit int64) {
if gcphase != _GCmark { if !writeBarrierEnabled {
println("gcphase =", gcphase) println("gcphase =", gcphase)
throw("gcDrainUntilPreempt phase incorrect") throw("gcDrainUntilPreempt phase incorrect")
} }
...@@ -750,6 +750,9 @@ func gcDrainUntilPreempt(gcw *gcWork, flushScanCredit int64) { ...@@ -750,6 +750,9 @@ func gcDrainUntilPreempt(gcw *gcWork, flushScanCredit int64) {
// scanning is always done in whole object increments. // scanning is always done in whole object increments.
//go:nowritebarrier //go:nowritebarrier
func gcDrainN(gcw *gcWork, scanWork int64) { func gcDrainN(gcw *gcWork, scanWork int64) {
if !writeBarrierEnabled {
throw("gcDrainN phase incorrect")
}
targetScanWork := gcw.scanWork + scanWork targetScanWork := gcw.scanWork + scanWork
for gcw.scanWork < targetScanWork { for gcw.scanWork < targetScanWork {
// This might be a good place to add prefetch code... // This might be a good place to add prefetch code...
......
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