mirror of
https://github.com/golang/go
synced 2024-11-18 11:14:39 -07:00
runtime: eliminate unnecessary ragged barrier
The ragged barrier after entering the concurrent mark phase is vestigial. This used to be the point where we enabled write barriers, so it was necessary to synchronize all Ps to ensure write barriers were enabled before any marking occurred. However, we've long since switched to enabling write barriers during the concurrent scan phase, so the start-the-world at the beginning of the concurrent scan phase ensures that all Ps have enabled the write barrier. Hence, we can eliminate the old "install write barrier" phase. Fixes #11971. Change-Id: I8cdcb84b5525cef19927d51ea11ba0a4db991ea8 Reviewed-on: https://go-review.googlesource.com/16044 Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
0c69f1303f
commit
28f458ce5b
@ -943,7 +943,7 @@ func backgroundgc() {
|
|||||||
func gc(mode gcMode) {
|
func gc(mode gcMode) {
|
||||||
// Timing/utilization tracking
|
// Timing/utilization tracking
|
||||||
var stwprocs, maxprocs int32
|
var stwprocs, maxprocs int32
|
||||||
var tSweepTerm, tScan, tInstallWB, tMark, tMarkTerm int64
|
var tSweepTerm, tScan, tMark, tMarkTerm int64
|
||||||
|
|
||||||
// debug.gctrace variables
|
// debug.gctrace variables
|
||||||
var heap0, heap1, heap2, heapGoal uint64
|
var heap0, heap1, heap2, heapGoal uint64
|
||||||
@ -996,31 +996,30 @@ func gc(mode gcMode) {
|
|||||||
heapGoal = gcController.heapGoal
|
heapGoal = gcController.heapGoal
|
||||||
|
|
||||||
systemstack(func() {
|
systemstack(func() {
|
||||||
// Enter scan phase. This enables write
|
// Enter scan phase and enable write barriers.
|
||||||
// barriers to track changes to stack frames
|
|
||||||
// above the stack barrier.
|
|
||||||
//
|
//
|
||||||
// TODO: This has evolved to the point where
|
// Because the world is stopped, all Ps will
|
||||||
// we carefully ensure invariants we no longer
|
// observe that write barriers are enabled by
|
||||||
// depend on. Either:
|
// the time we start the world and begin
|
||||||
|
// scanning.
|
||||||
//
|
//
|
||||||
// 1) Enable full write barriers for the scan,
|
// It's necessary to enable write barriers
|
||||||
// but eliminate the ragged barrier below
|
// during the scan phase for several reasons:
|
||||||
// (since the start the world ensures all Ps
|
|
||||||
// have observed the write barrier enable) and
|
|
||||||
// consider draining during the scan.
|
|
||||||
//
|
//
|
||||||
// 2) Only enable write barriers for writes to
|
// They must be enabled for writes to higher
|
||||||
// the stack at this point, and then enable
|
// stack frames before we scan stacks and
|
||||||
// write barriers for heap writes when we
|
// install stack barriers because this is how
|
||||||
// enter the mark phase. This means we cannot
|
// we track writes to inactive stack frames.
|
||||||
// drain in the scan phase and must perform a
|
// (Alternatively, we could not install stack
|
||||||
// ragged barrier to ensure all Ps have
|
// barriers over frame boundaries with
|
||||||
// enabled heap write barriers before we drain
|
// up-pointers).
|
||||||
// or enable assists.
|
|
||||||
//
|
//
|
||||||
// 3) Don't install stack barriers over frame
|
// They must be enabled before assists are
|
||||||
// boundaries where there are up-pointers.
|
// enabled because they must be enabled before
|
||||||
|
// any non-leaf heap objects are marked. Since
|
||||||
|
// allocations are blocked until assists can
|
||||||
|
// happen, we want enable assists as early as
|
||||||
|
// possible.
|
||||||
setGCPhase(_GCscan)
|
setGCPhase(_GCscan)
|
||||||
|
|
||||||
// markrootSpans uses work.spans, so make sure
|
// markrootSpans uses work.spans, so make sure
|
||||||
@ -1045,12 +1044,7 @@ func gc(mode gcMode) {
|
|||||||
gcscan_m()
|
gcscan_m()
|
||||||
|
|
||||||
// Enter mark phase.
|
// Enter mark phase.
|
||||||
tInstallWB = nanotime()
|
|
||||||
setGCPhase(_GCmark)
|
setGCPhase(_GCmark)
|
||||||
// Ensure all Ps have observed the phase
|
|
||||||
// change and have write barriers enabled
|
|
||||||
// before any blackening occurs.
|
|
||||||
forEachP(func(*p) {})
|
|
||||||
})
|
})
|
||||||
// Concurrent mark.
|
// Concurrent mark.
|
||||||
tMark = nanotime()
|
tMark = nanotime()
|
||||||
@ -1106,7 +1100,7 @@ func gc(mode gcMode) {
|
|||||||
gcController.endCycle()
|
gcController.endCycle()
|
||||||
} else {
|
} else {
|
||||||
t := nanotime()
|
t := nanotime()
|
||||||
tScan, tInstallWB, tMark, tMarkTerm = t, t, t, t
|
tScan, tMark, tMarkTerm = t, t, t
|
||||||
heapGoal = heap0
|
heapGoal = heap0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1201,13 +1195,12 @@ func gc(mode gcMode) {
|
|||||||
|
|
||||||
// Update work.totaltime.
|
// Update work.totaltime.
|
||||||
sweepTermCpu := int64(stwprocs) * (tScan - tSweepTerm)
|
sweepTermCpu := int64(stwprocs) * (tScan - tSweepTerm)
|
||||||
scanCpu := tInstallWB - tScan
|
scanCpu := tMark - tScan
|
||||||
installWBCpu := int64(0)
|
|
||||||
// We report idle marking time below, but omit it from the
|
// We report idle marking time below, but omit it from the
|
||||||
// overall utilization here since it's "free".
|
// overall utilization here since it's "free".
|
||||||
markCpu := gcController.assistTime + gcController.dedicatedMarkTime + gcController.fractionalMarkTime
|
markCpu := gcController.assistTime + gcController.dedicatedMarkTime + gcController.fractionalMarkTime
|
||||||
markTermCpu := int64(stwprocs) * (now - tMarkTerm)
|
markTermCpu := int64(stwprocs) * (now - tMarkTerm)
|
||||||
cycleCpu := sweepTermCpu + scanCpu + installWBCpu + markCpu + markTermCpu
|
cycleCpu := sweepTermCpu + scanCpu + markCpu + markTermCpu
|
||||||
work.totaltime += cycleCpu
|
work.totaltime += cycleCpu
|
||||||
|
|
||||||
// Compute overall GC CPU utilization.
|
// Compute overall GC CPU utilization.
|
||||||
@ -1226,6 +1219,10 @@ func gc(mode gcMode) {
|
|||||||
tEnd := now
|
tEnd := now
|
||||||
util := int(memstats.gc_cpu_fraction * 100)
|
util := int(memstats.gc_cpu_fraction * 100)
|
||||||
|
|
||||||
|
// Install WB phase is no longer used.
|
||||||
|
tInstallWB := tMark
|
||||||
|
installWBCpu := int64(0)
|
||||||
|
|
||||||
var sbuf [24]byte
|
var sbuf [24]byte
|
||||||
printlock()
|
printlock()
|
||||||
print("gc ", memstats.numgc,
|
print("gc ", memstats.numgc,
|
||||||
|
Loading…
Reference in New Issue
Block a user