Commit 64a26b79 authored by Austin Clements's avatar Austin Clements

runtime: simplify/optimize allocate-black a bit

Currently allocating black switches to the system stack (which is
probably a historical accident) and atomically updates the global
bytes marked stat. Since we're about to depend on this much more,
optimize it a bit by putting it back on the regular stack and updating
the per-P bytes marked stat, which gets lazily folded into the global
bytes marked stat.

Change-Id: Ibbe16e5382d3fd2256e4381f88af342bf7020b04
Reviewed-on: https://go-review.googlesource.com/22170Reviewed-by: 's avatarRick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 479501c1
...@@ -695,9 +695,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { ...@@ -695,9 +695,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
// This may be racing with GC so do it atomically if there can be // This may be racing with GC so do it atomically if there can be
// a race marking the bit. // a race marking the bit.
if gcphase == _GCmarktermination || gcBlackenPromptly { if gcphase == _GCmarktermination || gcBlackenPromptly {
systemstack(func() { gcmarknewobject(uintptr(x), size, scanSize)
gcmarknewobject_m(uintptr(x), size, scanSize)
})
} }
if raceenabled { if raceenabled {
......
...@@ -1132,15 +1132,20 @@ func gcDumpObject(label string, obj, off uintptr) { ...@@ -1132,15 +1132,20 @@ func gcDumpObject(label string, obj, off uintptr) {
} }
} }
// If gcBlackenPromptly is true we are in the second mark phase phase so we allocate black. // gcmarknewobject marks a newly allocated object black. obj must
// not contain any non-nil pointers.
//
// This is nosplit so it can manipulate a gcWork without preemption.
//
//go:nowritebarrier //go:nowritebarrier
func gcmarknewobject_m(obj, size, scanSize uintptr) { //go:nosplit
func gcmarknewobject(obj, size, scanSize uintptr) {
if useCheckmark && !gcBlackenPromptly { // The world should be stopped so this should not happen. if useCheckmark && !gcBlackenPromptly { // The world should be stopped so this should not happen.
throw("gcmarknewobject called while doing checkmark") throw("gcmarknewobject called while doing checkmark")
} }
heapBitsForAddr(obj).setMarked() heapBitsForAddr(obj).setMarked()
atomic.Xadd64(&work.bytesMarked, int64(size))
gcw := &getg().m.p.ptr().gcw gcw := &getg().m.p.ptr().gcw
gcw.bytesMarked += uint64(size)
gcw.scanWork += int64(scanSize) gcw.scanWork += int64(scanSize)
} }
......
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