aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcsweep.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-02-20 20:03:39 +0000
committerMichael Knyszek <mknyszek@google.com>2020-04-21 22:50:51 +0000
commiteacdf76b93174484ffc526d9c45f4836f0738dee (patch)
treeb3085c3f927b1c9be2a286a5433d6ed5a1c5d74b /src/runtime/mgcsweep.go
parent2a2423bd05da85dc7d0f8e7d12531623b69036a0 (diff)
downloadgo-eacdf76b93174484ffc526d9c45f4836f0738dee.tar.gz
go-eacdf76b93174484ffc526d9c45f4836f0738dee.zip
runtime: add bitmap-based markrootSpans implementation
Currently markrootSpans, the scanning routine which scans span specials (particularly finalizers) as roots, uses sweepSpans to shard work and find spans to mark. However, as part of a future CL to change span ownership and how mcentral works, we want to avoid having markrootSpans use the sweep bufs to find specials, so in this change we introduce a new mechanism. Much like for the page reclaimer, we set up a per-page bitmap where the first page for a span is marked if the span contains any specials, and unmarked if it has no specials. This bitmap is updated by addspecial, removespecial, and during sweeping. markrootSpans then shards this bitmap into mark work and markers iterate over the bitmap looking for spans with specials to mark. Unlike the page reclaimer, we don't need to use the pageInUse bits because having a special implies that a span is in-use. While in terms of computational complexity this design is technically worse, because it needs to iterate over the mapped heap, in practice this iteration is very fast (we can skip over large swathes of the heap very quickly) and we only look at spans that have any specials at all, rather than having to touch each span. This new implementation of markrootSpans is behind a feature flag called go115NewMarkrootSpans. Updates #37487. Change-Id: I8ea07b6c11059f6d412fe419e0ab512d989377b8 Reviewed-on: https://go-review.googlesource.com/c/go/+/221178 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgcsweep.go')
-rw-r--r--src/runtime/mgcsweep.go4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index c075f66b12..c63db24b33 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -246,6 +246,7 @@ func (s *mspan) sweep(preserve bool) bool {
// 2. A tiny object can have several finalizers setup for different offsets.
// If such object is not marked, we need to queue all finalizers at once.
// Both 1 and 2 are possible at the same time.
+ hadSpecials := s.specials != nil
specialp := &s.specials
special := *specialp
for special != nil {
@@ -290,6 +291,9 @@ func (s *mspan) sweep(preserve bool) bool {
special = *specialp
}
}
+ if go115NewMarkrootSpans && hadSpecials && s.specials == nil {
+ spanHasNoSpecials(s)
+ }
if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled {
// Find all newly freed objects. This doesn't have to