diff options
| author | Rick Hudson <rlh@golang.org> | 2016-02-11 13:57:58 -0500 |
|---|---|---|
| committer | Rick Hudson <rlh@golang.org> | 2016-04-27 21:54:47 +0000 |
| commit | 3479b065d43f2990ac12e7b00ddff6f63a876ca9 (patch) | |
| tree | 491ad3b3ea77e4e4a9202ebaaa933296206007da /src/runtime/mgcmark.go | |
| parent | dc65a82eff0a3af5a26f6c6d31c53bdac9b31168 (diff) | |
| download | go-3479b065d43f2990ac12e7b00ddff6f63a876ca9.tar.xz | |
[dev.garbage] runtime: allocate directly from GC mark bits
Instead of building a freelist from the mark bits generated
by the GC this CL allocates directly from the mark bits.
The approach moves the mark bits from the pointer/no pointer
heap structures into their own per span data structures. The
mark/allocation vectors consist of a single mark bit per
object. Two vectors are maintained, one for allocation and
one for the GC's mark phase. During the GC cycle's sweep
phase the interpretation of the vectors is swapped. The
mark vector becomes the allocation vector and the old
allocation vector is cleared and becomes the mark vector that
the next GC cycle will use.
Marked entries in the allocation vector indicate that the
object is not free. Each allocation vector maintains a boundary
between areas of the span already allocated from and areas
not yet allocated from. As objects are allocated this boundary
is moved until it reaches the end of the span. At this point
further allocations will be done from another span.
Since we no longer sweep a span inspecting each freed object
the responsibility for maintaining pointer/scalar bits in
the heapBitMap containing is now the responsibility of the
the routines doing the actual allocation.
This CL is functionally complete and ready for performance
tuning.
Change-Id: I336e0fc21eef1066e0b68c7067cc71b9f3d50e04
Reviewed-on: https://go-review.googlesource.com/19470
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgcmark.go')
| -rw-r--r-- | src/runtime/mgcmark.go | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 66d61bae1e..fe8a56460b 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -1044,9 +1044,9 @@ func greyobject(obj, base, off uintptr, hbits heapBits, span *mspan, gcw *gcWork if obj&(sys.PtrSize-1) != 0 { throw("greyobject: obj not pointer-aligned") } - + mbits := span.markBitsForAddr(obj) if useCheckmark { - if !hbits.isMarked() { + if !mbits.isMarked() { printlock() print("runtime:greyobject: checkmarks finds unexpected unmarked object obj=", hex(obj), "\n") print("runtime: found obj at *(", hex(base), "+", hex(off), ")\n") @@ -1068,10 +1068,10 @@ func greyobject(obj, base, off uintptr, hbits heapBits, span *mspan, gcw *gcWork } } else { // If marked we have nothing to do. - if hbits.isMarked() { + if mbits.isMarked() { return } - hbits.setMarked() + mbits.setMarked() // If this is a noscan object, fast-track it to black // instead of greying it. @@ -1138,7 +1138,7 @@ func gcmarknewobject_m(obj, size uintptr) { if useCheckmark && !gcBlackenPromptly { // The world should be stopped so this should not happen. throw("gcmarknewobject called while doing checkmark") } - heapBitsForAddr(obj).setMarked() + markBitsForAddr(obj).setMarked() atomic.Xadd64(&work.bytesMarked, int64(size)) } |
