blob: 5664390eae38c1766c49688d0ed5904f7d9ffaca [file] [log] [blame]
Russ Cox484f8012015-02-19 13:38:46 -05001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Garbage collector: marking and scanning
6
7package runtime
8
Michael Matloob67faca72015-11-02 14:09:24 -05009import (
10 "runtime/internal/atomic"
Michael Matloob432cb662015-11-11 12:39:30 -050011 "runtime/internal/sys"
Michael Matloob67faca72015-11-02 14:09:24 -050012 "unsafe"
13)
Russ Cox484f8012015-02-19 13:38:46 -050014
Austin Clementsd3df04c2015-10-16 16:52:26 -040015const (
16 fixedRootFinalizers = iota
Austin Clementse8337492016-03-11 17:00:46 -050017 fixedRootFreeGStacks
Austin Clementsd3df04c2015-10-16 16:52:26 -040018 fixedRootCount
19
20 // rootBlockBytes is the number of bytes to scan per data or
21 // BSS root.
22 rootBlockBytes = 256 << 10
23
24 // rootBlockSpans is the number of spans to scan per span
25 // root.
26 rootBlockSpans = 8 * 1024 // 64MB worth of spans
Austin Clementscf4f1d02016-05-27 21:04:40 -040027
28 // maxObletBytes is the maximum bytes of an object to scan at
29 // once. Larger objects will be split up into "oblets" of at
30 // most this size. Since we can scan 1–2 MB/ms, 128 KB bounds
31 // scan preemption at ~100 µs.
32 //
33 // This must be > _MaxSmallSize so that the object base is the
34 // span base.
35 maxObletBytes = 128 << 10
Austin Clements49ea92072016-10-30 20:20:17 -040036
Austin Clements28e1a8e2017-10-04 16:15:35 -040037 // drainCheckThreshold specifies how many units of work to do
38 // between self-preemption checks in gcDrain. Assuming a scan
Austin Clements49ea92072016-10-30 20:20:17 -040039 // rate of 1 MB/ms, this is ~100 µs. Lower values have higher
40 // overhead in the scan loop (the scheduler check may perform
41 // a syscall, so its overhead is nontrivial). Higher values
42 // make the system less responsive to incoming work.
Austin Clements28e1a8e2017-10-04 16:15:35 -040043 drainCheckThreshold = 100000
Austin Clementsd3df04c2015-10-16 16:52:26 -040044)
45
Austin Clements82d14d72015-10-19 13:46:32 -040046// gcMarkRootPrepare queues root scanning jobs (stacks, globals, and
47// some miscellany) and initializes scanning-related state.
Austin Clementsd3df04c2015-10-16 16:52:26 -040048//
49// The caller must have call gcCopySpans().
50//
Austin Clements2a889b92016-03-04 11:58:26 -050051// The world must be stopped.
52//
Austin Clementsd3df04c2015-10-16 16:52:26 -040053//go:nowritebarrier
Austin Clements82d14d72015-10-19 13:46:32 -040054func gcMarkRootPrepare() {
Austin Clementsa475a382016-10-25 13:56:37 -040055 if gcphase == _GCmarktermination {
56 work.nFlushCacheRoots = int(gomaxprocs)
57 } else {
58 work.nFlushCacheRoots = 0
59 }
60
Austin Clementsd3df04c2015-10-16 16:52:26 -040061 // Compute how many data and BSS root blocks there are.
62 nBlocks := func(bytes uintptr) int {
63 return int((bytes + rootBlockBytes - 1) / rootBlockBytes)
64 }
65
66 work.nDataRoots = 0
Austin Clementsd3df04c2015-10-16 16:52:26 -040067 work.nBSSRoots = 0
Austin Clementsb49b71a2016-03-18 11:27:59 -040068
69 // Only scan globals once per cycle; preferably concurrently.
70 if !work.markrootDone {
David Crawshaw54ec7b02016-10-30 20:30:38 -040071 for _, datap := range activeModules() {
Austin Clementsb49b71a2016-03-18 11:27:59 -040072 nDataRoots := nBlocks(datap.edata - datap.data)
73 if nDataRoots > work.nDataRoots {
74 work.nDataRoots = nDataRoots
75 }
76 }
77
David Crawshaw54ec7b02016-10-30 20:30:38 -040078 for _, datap := range activeModules() {
Austin Clementsb49b71a2016-03-18 11:27:59 -040079 nBSSRoots := nBlocks(datap.ebss - datap.bss)
80 if nBSSRoots > work.nBSSRoots {
81 work.nBSSRoots = nBSSRoots
82 }
Austin Clementsd3df04c2015-10-16 16:52:26 -040083 }
84 }
85
Austin Clementsefb0c552016-03-11 13:54:55 -050086 if !work.markrootDone {
87 // On the first markroot, we need to scan span roots.
88 // In concurrent GC, this happens during concurrent
89 // mark and we depend on addfinalizer to ensure the
90 // above invariants for objects that get finalizers
91 // after concurrent mark. In STW GC, this will happen
92 // during mark termination.
Austin Clementsc95a8e42016-10-05 18:32:21 -040093 //
94 // We're only interested in scanning the in-use spans,
95 // which will all be swept at this point. More spans
96 // may be added to this list during concurrent GC, but
97 // we only care about spans that were allocated before
98 // this mark phase.
99 work.nSpanRoots = mheap_.sweepSpans[mheap_.sweepgen/2%2].numBlocks()
Austin Clementsd3df04c2015-10-16 16:52:26 -0400100
Austin Clements2a889b92016-03-04 11:58:26 -0500101 // On the first markroot, we need to scan all Gs. Gs
102 // may be created after this point, but it's okay that
103 // we ignore them because they begin life without any
104 // roots, so there's nothing to scan, and any roots
105 // they create during the concurrent phase will be
106 // scanned during mark termination. During mark
107 // termination, allglen isn't changing, so we'll scan
108 // all Gs.
109 work.nStackRoots = int(atomic.Loaduintptr(&allglen))
Austin Clementsefb0c552016-03-11 13:54:55 -0500110 } else {
111 // We've already scanned span roots and kept the scan
112 // up-to-date during concurrent mark.
113 work.nSpanRoots = 0
Austin Clements2a889b92016-03-04 11:58:26 -0500114
Austin Clementsc5ebcd22017-02-09 11:50:26 -0500115 // The hybrid barrier ensures that stacks can't
116 // contain pointers to unmarked objects, so on the
117 // second markroot, there's no need to scan stacks.
Austin Clements2a889b92016-03-04 11:58:26 -0500118 work.nStackRoots = 0
Austin Clementsc5ebcd22017-02-09 11:50:26 -0500119
120 if debug.gcrescanstacks > 0 {
121 // Scan stacks anyway for debugging.
122 work.nStackRoots = int(atomic.Loaduintptr(&allglen))
123 }
Austin Clementsefb0c552016-03-11 13:54:55 -0500124 }
Austin Clementsd3df04c2015-10-16 16:52:26 -0400125
Austin Clements82d14d72015-10-19 13:46:32 -0400126 work.markrootNext = 0
Austin Clementsc5ebcd22017-02-09 11:50:26 -0500127 work.markrootJobs = uint32(fixedRootCount + work.nFlushCacheRoots + work.nDataRoots + work.nBSSRoots + work.nSpanRoots + work.nStackRoots)
Austin Clementsd3df04c2015-10-16 16:52:26 -0400128}
129
Austin Clements82d14d72015-10-19 13:46:32 -0400130// gcMarkRootCheck checks that all roots have been scanned. It is
131// purely for debugging.
132func gcMarkRootCheck() {
133 if work.markrootNext < work.markrootJobs {
134 print(work.markrootNext, " of ", work.markrootJobs, " markroot jobs done\n")
135 throw("left over markroot jobs")
136 }
Russ Cox484f8012015-02-19 13:38:46 -0500137
138 lock(&allglock)
Austin Clements2a889b92016-03-04 11:58:26 -0500139 // Check that stacks have been scanned.
Austin Clements05dc6b22016-11-17 10:48:40 -0500140 var gp *g
Austin Clementsbd640c82016-10-23 11:07:49 -0400141 if gcphase == _GCmarktermination && debug.gcrescanstacks > 0 {
Austin Clements2a889b92016-03-04 11:58:26 -0500142 for i := 0; i < len(allgs); i++ {
Austin Clements05dc6b22016-11-17 10:48:40 -0500143 gp = allgs[i]
Austin Clements2a889b92016-03-04 11:58:26 -0500144 if !(gp.gcscandone && gp.gcscanvalid) && readgstatus(gp) != _Gdead {
Austin Clements05dc6b22016-11-17 10:48:40 -0500145 goto fail
Austin Clements2a889b92016-03-04 11:58:26 -0500146 }
147 }
148 } else {
149 for i := 0; i < work.nStackRoots; i++ {
Austin Clements05dc6b22016-11-17 10:48:40 -0500150 gp = allgs[i]
Austin Clements2a889b92016-03-04 11:58:26 -0500151 if !gp.gcscandone {
Austin Clements05dc6b22016-11-17 10:48:40 -0500152 goto fail
Austin Clements2a889b92016-03-04 11:58:26 -0500153 }
Russ Cox484f8012015-02-19 13:38:46 -0500154 }
155 }
156 unlock(&allglock)
Austin Clements05dc6b22016-11-17 10:48:40 -0500157 return
158
159fail:
160 println("gp", gp, "goid", gp.goid,
161 "status", readgstatus(gp),
162 "gcscandone", gp.gcscandone,
163 "gcscanvalid", gp.gcscanvalid)
164 unlock(&allglock) // Avoid self-deadlock with traceback.
165 throw("scan missed a g")
Russ Cox484f8012015-02-19 13:38:46 -0500166}
167
168// ptrmask for an allocation containing a single pointer.
Russ Cox4d0f3a12015-04-27 22:45:57 -0400169var oneptrmask = [...]uint8{1}
Russ Cox484f8012015-02-19 13:38:46 -0500170
Austin Clements82d14d72015-10-19 13:46:32 -0400171// markroot scans the i'th root.
172//
173// Preemption must be disabled (because this uses a gcWork).
174//
Austin Clements2a889b92016-03-04 11:58:26 -0500175// nowritebarrier is only advisory here.
176//
Russ Cox484f8012015-02-19 13:38:46 -0500177//go:nowritebarrier
Austin Clements7b229002015-11-23 18:44:03 -0500178func markroot(gcw *gcWork, i uint32) {
Austin Clements2a889b92016-03-04 11:58:26 -0500179 // TODO(austin): This is a bit ridiculous. Compute and store
180 // the bases in gcMarkRootPrepare instead of the counts.
Austin Clementsa475a382016-10-25 13:56:37 -0400181 baseFlushCache := uint32(fixedRootCount)
182 baseData := baseFlushCache + uint32(work.nFlushCacheRoots)
Austin Clementsd3df04c2015-10-16 16:52:26 -0400183 baseBSS := baseData + uint32(work.nDataRoots)
184 baseSpans := baseBSS + uint32(work.nBSSRoots)
185 baseStacks := baseSpans + uint32(work.nSpanRoots)
Austin Clementsc5ebcd22017-02-09 11:50:26 -0500186 end := baseStacks + uint32(work.nStackRoots)
Austin Clementsd3df04c2015-10-16 16:52:26 -0400187
Keith Randallcd5b1442015-03-11 12:58:47 -0700188 // Note: if you add a case here, please also update heapdump.go:dumproots.
Austin Clementsd3df04c2015-10-16 16:52:26 -0400189 switch {
Austin Clementsa475a382016-10-25 13:56:37 -0400190 case baseFlushCache <= i && i < baseData:
191 flushmcache(int(i - baseFlushCache))
192
Austin Clementsd3df04c2015-10-16 16:52:26 -0400193 case baseData <= i && i < baseBSS:
David Crawshaw54ec7b02016-10-30 20:30:38 -0400194 for _, datap := range activeModules() {
Austin Clements7b229002015-11-23 18:44:03 -0500195 markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-baseData))
Michael Hudson-Doylefae4a122015-03-29 21:59:00 +0000196 }
Russ Cox484f8012015-02-19 13:38:46 -0500197
Austin Clementsd3df04c2015-10-16 16:52:26 -0400198 case baseBSS <= i && i < baseSpans:
David Crawshaw54ec7b02016-10-30 20:30:38 -0400199 for _, datap := range activeModules() {
Austin Clements7b229002015-11-23 18:44:03 -0500200 markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-baseBSS))
Michael Hudson-Doylefae4a122015-03-29 21:59:00 +0000201 }
Russ Cox484f8012015-02-19 13:38:46 -0500202
Austin Clementsd3df04c2015-10-16 16:52:26 -0400203 case i == fixedRootFinalizers:
Austin Clementsf1ba75f2017-01-31 11:46:36 -0500204 // Only do this once per GC cycle since we don't call
205 // queuefinalizer during marking.
206 if work.markrootDone {
207 break
208 }
Russ Cox484f8012015-02-19 13:38:46 -0500209 for fb := allfin; fb != nil; fb = fb.alllink {
Austin Clementsd3836ab2016-10-14 13:39:07 -0400210 cnt := uintptr(atomic.Load(&fb.cnt))
211 scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), cnt*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], gcw)
Russ Cox484f8012015-02-19 13:38:46 -0500212 }
213
Austin Clementse8337492016-03-11 17:00:46 -0500214 case i == fixedRootFreeGStacks:
215 // Only do this once per GC cycle; preferably
216 // concurrently.
217 if !work.markrootDone {
Austin Clements6a86dbe2016-05-27 12:21:14 -0400218 // Switch to the system stack so we can call
219 // stackfree.
220 systemstack(markrootFreeGStacks)
Austin Clementse8337492016-03-11 17:00:46 -0500221 }
222
Austin Clementsd3df04c2015-10-16 16:52:26 -0400223 case baseSpans <= i && i < baseStacks:
224 // mark MSpan.specials
Austin Clements7b229002015-11-23 18:44:03 -0500225 markrootSpans(gcw, int(i-baseSpans))
Austin Clements572f08a2015-08-04 10:45:29 -0400226
Austin Clementsd3df04c2015-10-16 16:52:26 -0400227 default:
Russ Cox484f8012015-02-19 13:38:46 -0500228 // the rest is scanning goroutine stacks
Austin Clements2a889b92016-03-04 11:58:26 -0500229 var gp *g
Austin Clementsc5ebcd22017-02-09 11:50:26 -0500230 if baseStacks <= i && i < end {
Austin Clements2a889b92016-03-04 11:58:26 -0500231 gp = allgs[i-baseStacks]
Austin Clements2a889b92016-03-04 11:58:26 -0500232 } else {
Russ Cox484f8012015-02-19 13:38:46 -0500233 throw("markroot: bad index")
234 }
Russ Cox484f8012015-02-19 13:38:46 -0500235
236 // remember when we've first observed the G blocked
237 // needed only to output in traceback
238 status := readgstatus(gp) // We are not in a scan state
239 if (status == _Gwaiting || status == _Gsyscall) && gp.waitsince == 0 {
240 gp.waitsince = work.tstart
241 }
242
Austin Clements82d14d72015-10-19 13:46:32 -0400243 // scang must be done on the system stack in case
244 // we're trying to scan our own stack.
245 systemstack(func() {
246 // If this is a self-scan, put the user G in
247 // _Gwaiting to prevent self-deadlock. It may
Austin Clementsd6625ca2016-10-24 14:20:07 -0400248 // already be in _Gwaiting if this is a mark
249 // worker or we're in mark termination.
Austin Clements82d14d72015-10-19 13:46:32 -0400250 userG := getg().m.curg
251 selfScan := gp == userG && readgstatus(userG) == _Grunning
252 if selfScan {
253 casgstatus(userG, _Grunning, _Gwaiting)
254 userG.waitreason = "garbage collection scan"
255 }
256
257 // TODO: scang blocks until gp's stack has
258 // been scanned, which may take a while for
259 // running goroutines. Consider doing this in
260 // two phases where the first is non-blocking:
261 // we scan the stacks we can and ask running
262 // goroutines to scan themselves; and the
263 // second blocks.
Austin Clements3be48b42016-05-23 22:14:53 -0400264 scang(gp, gcw)
Austin Clements82d14d72015-10-19 13:46:32 -0400265
266 if selfScan {
267 casgstatus(userG, _Gwaiting, _Grunning)
268 }
269 })
Russ Cox484f8012015-02-19 13:38:46 -0500270 }
Russ Cox484f8012015-02-19 13:38:46 -0500271}
272
Austin Clementsd3df04c2015-10-16 16:52:26 -0400273// markrootBlock scans the shard'th shard of the block of memory [b0,
274// b0+n0), with the given pointer mask.
275//
276//go:nowritebarrier
277func markrootBlock(b0, n0 uintptr, ptrmask0 *uint8, gcw *gcWork, shard int) {
Michael Matloob432cb662015-11-11 12:39:30 -0500278 if rootBlockBytes%(8*sys.PtrSize) != 0 {
Austin Clementsd3df04c2015-10-16 16:52:26 -0400279 // This is necessary to pick byte offsets in ptrmask0.
280 throw("rootBlockBytes must be a multiple of 8*ptrSize")
281 }
282
283 b := b0 + uintptr(shard)*rootBlockBytes
284 if b >= b0+n0 {
285 return
286 }
Michael Matloob432cb662015-11-11 12:39:30 -0500287 ptrmask := (*uint8)(add(unsafe.Pointer(ptrmask0), uintptr(shard)*(rootBlockBytes/(8*sys.PtrSize))))
Austin Clementsd3df04c2015-10-16 16:52:26 -0400288 n := uintptr(rootBlockBytes)
289 if b+n > b0+n0 {
290 n = b0 + n0 - b
291 }
292
293 // Scan this shard.
294 scanblock(b, n, ptrmask, gcw)
295}
296
Austin Clementse8337492016-03-11 17:00:46 -0500297// markrootFreeGStacks frees stacks of dead Gs.
298//
299// This does not free stacks of dead Gs cached on Ps, but having a few
300// cached stacks around isn't a problem.
301//
302//TODO go:nowritebarrier
303func markrootFreeGStacks() {
304 // Take list of dead Gs with stacks.
305 lock(&sched.gflock)
306 list := sched.gfreeStack
307 sched.gfreeStack = nil
308 unlock(&sched.gflock)
309 if list == nil {
310 return
311 }
312
313 // Free stacks.
314 tail := list
315 for gp := list; gp != nil; gp = gp.schedlink.ptr() {
316 shrinkstack(gp)
317 tail = gp
318 }
319
320 // Put Gs back on the free list.
321 lock(&sched.gflock)
322 tail.schedlink.set(sched.gfreeNoStack)
323 sched.gfreeNoStack = list
324 unlock(&sched.gflock)
325}
326
Austin Clementsd3df04c2015-10-16 16:52:26 -0400327// markrootSpans marks roots for one shard of work.spans.
Austin Clements572f08a2015-08-04 10:45:29 -0400328//
329//go:nowritebarrier
330func markrootSpans(gcw *gcWork, shard int) {
Austin Clements608c1b02015-09-24 14:39:27 -0400331 // Objects with finalizers have two GC-related invariants:
332 //
333 // 1) Everything reachable from the object must be marked.
334 // This ensures that when we pass the object to its finalizer,
335 // everything the finalizer can reach will be retained.
336 //
337 // 2) Finalizer specials (which are not in the garbage
338 // collected heap) are roots. In practice, this means the fn
339 // field must be scanned.
340 //
341 // TODO(austin): There are several ideas for making this more
342 // efficient in issue #11485.
343
Austin Clementsc14d25c2016-02-15 18:24:06 -0500344 if work.markrootDone {
Austin Clementsefb0c552016-03-11 13:54:55 -0500345 throw("markrootSpans during second markroot")
Austin Clements608c1b02015-09-24 14:39:27 -0400346 }
347
Austin Clements572f08a2015-08-04 10:45:29 -0400348 sg := mheap_.sweepgen
Austin Clementsc95a8e42016-10-05 18:32:21 -0400349 spans := mheap_.sweepSpans[mheap_.sweepgen/2%2].block(shard)
Austin Clements608c1b02015-09-24 14:39:27 -0400350 // Note that work.spans may not include spans that were
351 // allocated between entering the scan phase and now. This is
352 // okay because any objects with finalizers in those spans
353 // must have been allocated and given finalizers after we
354 // entered the scan phase, so addfinalizer will have ensured
355 // the above invariants for them.
Austin Clementsc95a8e42016-10-05 18:32:21 -0400356 for _, s := range spans {
Austin Clements572f08a2015-08-04 10:45:29 -0400357 if s.state != mSpanInUse {
358 continue
359 }
360 if !useCheckmark && s.sweepgen != sg {
361 // sweepgen was updated (+2) during non-checkmark GC pass
362 print("sweep ", s.sweepgen, " ", sg, "\n")
363 throw("gc: unswept span")
364 }
Austin Clements608c1b02015-09-24 14:39:27 -0400365
366 // Speculatively check if there are any specials
367 // without acquiring the span lock. This may race with
368 // adding the first special to a span, but in that
369 // case addfinalizer will observe that the GC is
370 // active (which is globally synchronized) and ensure
371 // the above invariants. We may also ensure the
372 // invariants, but it's okay to scan an object twice.
373 if s.specials == nil {
374 continue
375 }
376
377 // Lock the specials to prevent a special from being
378 // removed from the list while we're traversing it.
379 lock(&s.speciallock)
380
Austin Clements572f08a2015-08-04 10:45:29 -0400381 for sp := s.specials; sp != nil; sp = sp.next {
382 if sp.kind != _KindSpecialFinalizer {
383 continue
384 }
385 // don't mark finalized object, but scan it so we
386 // retain everything it points to.
387 spf := (*specialfinalizer)(unsafe.Pointer(sp))
388 // A finalizer can be set for an inner byte of an object, find object beginning.
Rick Hudsonf8d0d4f2016-03-14 12:02:02 -0400389 p := s.base() + uintptr(spf.special.offset)/s.elemsize*s.elemsize
Austin Clements608c1b02015-09-24 14:39:27 -0400390
391 // Mark everything that can be reached from
392 // the object (but *not* the object itself or
393 // we'll never collect it).
394 scanobject(p, gcw)
395
396 // The special itself is a root.
Michael Matloob432cb662015-11-11 12:39:30 -0500397 scanblock(uintptr(unsafe.Pointer(&spf.fn)), sys.PtrSize, &oneptrmask[0], gcw)
Austin Clements572f08a2015-08-04 10:45:29 -0400398 }
Austin Clements608c1b02015-09-24 14:39:27 -0400399
400 unlock(&s.speciallock)
Austin Clements572f08a2015-08-04 10:45:29 -0400401 }
402}
403
Austin Clements65aa2da2015-10-04 20:56:11 -0700404// gcAssistAlloc performs GC work to make gp's assist debt positive.
405// gp must be the calling user gorountine.
Austin Clements4b2fde92015-03-16 14:22:00 -0400406//
Austin Clements65aa2da2015-10-04 20:56:11 -0700407// This must be called with preemption enabled.
Austin Clements65aa2da2015-10-04 20:56:11 -0700408func gcAssistAlloc(gp *g) {
Austin Clements4f188c22015-07-22 15:14:54 -0400409 // Don't assist in non-preemptible contexts. These are
410 // generally fragile and won't allow the assist to block.
411 if getg() == gp.m.g0 {
412 return
413 }
414 if mp := getg().m; mp.locks > 0 || mp.preemptoff != "" {
415 return
416 }
417
Austin Clementsffd56872017-07-19 14:18:08 -0400418 traced := false
Austin Clements984753b2016-10-10 12:18:00 -0400419retry:
Austin Clements89c341c2015-10-04 20:16:57 -0700420 // Compute the amount of scan work we need to do to make the
Rhys Hiltnerccca9c92016-07-22 16:36:30 -0700421 // balance positive. When the required amount of work is low,
422 // we over-assist to build up credit for future allocations
423 // and amortize the cost of assisting.
424 debtBytes := -gp.gcAssistBytes
Austin Clements89c341c2015-10-04 20:16:57 -0700425 scanWork := int64(gcController.assistWorkPerByte * float64(debtBytes))
Rhys Hiltnerccca9c92016-07-22 16:36:30 -0700426 if scanWork < gcOverAssistWork {
427 scanWork = gcOverAssistWork
428 debtBytes = int64(gcController.assistBytesPerWork * float64(scanWork))
429 }
Austin Clements4b2fde92015-03-16 14:22:00 -0400430
431 // Steal as much credit as we can from the background GC's
432 // scan credit. This is racy and may drop the background
433 // credit below 0 if two mutators steal at the same time. This
434 // will just cause steals to fail until credit is accumulated
435 // again, so in the long run it doesn't really matter, but we
436 // do have to handle the negative credit case.
Michael Matloob67faca72015-11-02 14:09:24 -0500437 bgScanCredit := atomic.Loadint64(&gcController.bgScanCredit)
Austin Clements4b2fde92015-03-16 14:22:00 -0400438 stolen := int64(0)
439 if bgScanCredit > 0 {
440 if bgScanCredit < scanWork {
441 stolen = bgScanCredit
Austin Clements89c341c2015-10-04 20:16:57 -0700442 gp.gcAssistBytes += 1 + int64(gcController.assistBytesPerWork*float64(stolen))
Austin Clements4b2fde92015-03-16 14:22:00 -0400443 } else {
444 stolen = scanWork
Austin Clements89c341c2015-10-04 20:16:57 -0700445 gp.gcAssistBytes += debtBytes
Austin Clements4b2fde92015-03-16 14:22:00 -0400446 }
Michael Matloob67faca72015-11-02 14:09:24 -0500447 atomic.Xaddint64(&gcController.bgScanCredit, -stolen)
Austin Clements4b2fde92015-03-16 14:22:00 -0400448
449 scanWork -= stolen
Austin Clements4b2fde92015-03-16 14:22:00 -0400450
451 if scanWork == 0 {
Austin Clements89c341c2015-10-04 20:16:57 -0700452 // We were able to steal all of the credit we
453 // needed.
Austin Clementsffd56872017-07-19 14:18:08 -0400454 if traced {
Heschi Kreinick2a74b9e2017-01-31 14:09:14 -0500455 traceGCMarkAssistDone()
456 }
Austin Clements4b2fde92015-03-16 14:22:00 -0400457 return
458 }
459 }
460
Austin Clementsffd56872017-07-19 14:18:08 -0400461 if trace.enabled && !traced {
462 traced = true
463 traceGCMarkAssistStart()
464 }
465
Austin Clements4b2fde92015-03-16 14:22:00 -0400466 // Perform assist work
467 systemstack(func() {
Austin Clementsf9e1adb2016-10-30 17:46:49 -0400468 gcAssistAlloc1(gp, scanWork)
469 // The user stack may have moved, so this can't touch
470 // anything on it until it returns from systemstack.
Austin Clements4b2fde92015-03-16 14:22:00 -0400471 })
Austin Clements500c88d2015-07-23 17:55:01 -0400472
Austin Clementsf9e1adb2016-10-30 17:46:49 -0400473 completed := gp.param != nil
474 gp.param = nil
Austin Clements500c88d2015-07-23 17:55:01 -0400475 if completed {
Austin Clementsc99d7f72015-10-26 11:27:37 -0400476 gcMarkDone()
Austin Clements8f34b252015-07-22 16:55:04 -0400477 }
478
Austin Clements15aa6bb2015-10-14 21:31:33 -0400479 if gp.gcAssistBytes < 0 {
Austin Clements8f34b252015-07-22 16:55:04 -0400480 // We were unable steal enough credit or perform
481 // enough work to pay off the assist debt. We need to
482 // do one of these before letting the mutator allocate
Austin Clements15aa6bb2015-10-14 21:31:33 -0400483 // more to prevent over-allocation.
484 //
Austin Clements45652832015-10-15 17:58:17 -0400485 // If this is because we were preempted, reschedule
486 // and try some more.
487 if gp.preempt {
488 Gosched()
489 goto retry
490 }
491
Austin Clements15aa6bb2015-10-14 21:31:33 -0400492 // Add this G to an assist queue and park. When the GC
493 // has more background credit, it will satisfy queued
494 // assists before flushing to the global credit pool.
495 //
496 // Note that this does *not* get woken up when more
497 // work is added to the work list. The theory is that
498 // there wasn't enough work to do anyway, so we might
499 // as well let background marking take care of the
500 // work that is available.
Austin Clements81c431a2016-10-06 15:12:12 -0400501 if !gcParkAssist() {
Austin Clements15aa6bb2015-10-14 21:31:33 -0400502 goto retry
503 }
Austin Clements15aa6bb2015-10-14 21:31:33 -0400504
505 // At this point either background GC has satisfied
506 // this G's assist debt, or the GC cycle is over.
Austin Clements500c88d2015-07-23 17:55:01 -0400507 }
Austin Clementsffd56872017-07-19 14:18:08 -0400508 if traced {
Heschi Kreinick2a74b9e2017-01-31 14:09:14 -0500509 traceGCMarkAssistDone()
510 }
Russ Cox484f8012015-02-19 13:38:46 -0500511}
512
Austin Clementsf9e1adb2016-10-30 17:46:49 -0400513// gcAssistAlloc1 is the part of gcAssistAlloc that runs on the system
514// stack. This is a separate function to make it easier to see that
515// we're not capturing anything from the user stack, since the user
516// stack may move while we're in this function.
517//
518// gcAssistAlloc1 indicates whether this assist completed the mark
519// phase by setting gp.param to non-nil. This can't be communicated on
520// the stack since it may move.
521//
522//go:systemstack
523func gcAssistAlloc1(gp *g, scanWork int64) {
524 // Clear the flag indicating that this assist completed the
525 // mark phase.
526 gp.param = nil
527
528 if atomic.Load(&gcBlackenEnabled) == 0 {
529 // The gcBlackenEnabled check in malloc races with the
530 // store that clears it but an atomic check in every malloc
531 // would be a performance hit.
532 // Instead we recheck it here on the non-preemptable system
533 // stack to determine if we should preform an assist.
534
535 // GC is done, so ignore any remaining debt.
536 gp.gcAssistBytes = 0
537 return
538 }
539 // Track time spent in this assist. Since we're on the
540 // system stack, this is non-preemptible, so we can
541 // just measure start and end time.
542 startTime := nanotime()
543
544 decnwait := atomic.Xadd(&work.nwait, -1)
545 if decnwait == work.nproc {
546 println("runtime: work.nwait =", decnwait, "work.nproc=", work.nproc)
547 throw("nwait > work.nprocs")
548 }
549
Austin Clementsd35dfd42016-10-30 17:59:06 -0400550 // gcDrainN requires the caller to be preemptible.
551 casgstatus(gp, _Grunning, _Gwaiting)
552 gp.waitreason = "GC assist marking"
553
Austin Clementsf9e1adb2016-10-30 17:46:49 -0400554 // drain own cached work first in the hopes that it
555 // will be more cache friendly.
556 gcw := &getg().m.p.ptr().gcw
557 workDone := gcDrainN(gcw, scanWork)
558 // If we are near the end of the mark phase
559 // dispose of the gcw.
560 if gcBlackenPromptly {
561 gcw.dispose()
562 }
563
Austin Clementsd35dfd42016-10-30 17:59:06 -0400564 casgstatus(gp, _Gwaiting, _Grunning)
565
Austin Clementsf9e1adb2016-10-30 17:46:49 -0400566 // Record that we did this much scan work.
567 //
568 // Back out the number of bytes of assist credit that
569 // this scan work counts for. The "1+" is a poor man's
570 // round-up, to ensure this adds credit even if
571 // assistBytesPerWork is very low.
572 gp.gcAssistBytes += 1 + int64(gcController.assistBytesPerWork*float64(workDone))
573
574 // If this is the last worker and we ran out of work,
575 // signal a completion point.
576 incnwait := atomic.Xadd(&work.nwait, +1)
577 if incnwait > work.nproc {
578 println("runtime: work.nwait=", incnwait,
579 "work.nproc=", work.nproc,
580 "gcBlackenPromptly=", gcBlackenPromptly)
581 throw("work.nwait > work.nproc")
582 }
583
584 if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
585 // This has reached a background completion point. Set
586 // gp.param to a non-nil value to indicate this. It
587 // doesn't matter what we set it to (it just has to be
588 // a valid pointer).
589 gp.param = unsafe.Pointer(gp)
590 }
591 duration := nanotime() - startTime
592 _p_ := gp.m.p.ptr()
593 _p_.gcAssistTime += duration
594 if _p_.gcAssistTime > gcAssistTimeSlack {
595 atomic.Xaddint64(&gcController.assistTime, _p_.gcAssistTime)
596 _p_.gcAssistTime = 0
597 }
598}
599
Austin Clements15aa6bb2015-10-14 21:31:33 -0400600// gcWakeAllAssists wakes all currently blocked assists. This is used
Austin Clementsb05f18e2016-01-15 13:28:41 -0500601// at the end of a GC cycle. gcBlackenEnabled must be false to prevent
602// new assists from going to sleep after this point.
Austin Clements15aa6bb2015-10-14 21:31:33 -0400603func gcWakeAllAssists() {
604 lock(&work.assistQueue.lock)
605 injectglist(work.assistQueue.head.ptr())
606 work.assistQueue.head.set(nil)
607 work.assistQueue.tail.set(nil)
608 unlock(&work.assistQueue.lock)
609}
610
Austin Clements81c431a2016-10-06 15:12:12 -0400611// gcParkAssist puts the current goroutine on the assist queue and parks.
612//
613// gcParkAssist returns whether the assist is now satisfied. If it
614// returns false, the caller must retry the assist.
615//
616//go:nowritebarrier
617func gcParkAssist() bool {
618 lock(&work.assistQueue.lock)
619 // If the GC cycle finished while we were getting the lock,
620 // exit the assist. The cycle can't finish while we hold the
621 // lock.
622 if atomic.Load(&gcBlackenEnabled) == 0 {
623 unlock(&work.assistQueue.lock)
624 return true
625 }
626
627 gp := getg()
628 oldHead, oldTail := work.assistQueue.head, work.assistQueue.tail
629 if oldHead == 0 {
630 work.assistQueue.head.set(gp)
631 } else {
632 oldTail.ptr().schedlink.set(gp)
633 }
634 work.assistQueue.tail.set(gp)
635 gp.schedlink.set(nil)
636
637 // Recheck for background credit now that this G is in
638 // the queue, but can still back out. This avoids a
639 // race in case background marking has flushed more
640 // credit since we checked above.
641 if atomic.Loadint64(&gcController.bgScanCredit) > 0 {
642 work.assistQueue.head = oldHead
643 work.assistQueue.tail = oldTail
644 if oldTail != 0 {
645 oldTail.ptr().schedlink.set(nil)
646 }
647 unlock(&work.assistQueue.lock)
648 return false
649 }
650 // Park.
Austin Clements6da83c62016-10-08 18:38:35 -0400651 goparkunlock(&work.assistQueue.lock, "GC assist wait", traceEvGoBlockGC, 2)
Austin Clements81c431a2016-10-06 15:12:12 -0400652 return true
653}
654
Austin Clements15aa6bb2015-10-14 21:31:33 -0400655// gcFlushBgCredit flushes scanWork units of background scan work
656// credit. This first satisfies blocked assists on the
657// work.assistQueue and then flushes any remaining credit to
658// gcController.bgScanCredit.
Austin Clementsab9d5f32015-11-19 11:25:55 -0500659//
660// Write barriers are disallowed because this is used by gcDrain after
661// it has ensured that all work is drained and this must preserve that
662// condition.
663//
664//go:nowritebarrierrec
Austin Clements15aa6bb2015-10-14 21:31:33 -0400665func gcFlushBgCredit(scanWork int64) {
666 if work.assistQueue.head == 0 {
667 // Fast path; there are no blocked assists. There's a
668 // small window here where an assist may add itself to
669 // the blocked queue and park. If that happens, we'll
670 // just get it on the next flush.
Michael Matloob67faca72015-11-02 14:09:24 -0500671 atomic.Xaddint64(&gcController.bgScanCredit, scanWork)
Austin Clements15aa6bb2015-10-14 21:31:33 -0400672 return
673 }
674
675 scanBytes := int64(float64(scanWork) * gcController.assistBytesPerWork)
676
677 lock(&work.assistQueue.lock)
678 gp := work.assistQueue.head.ptr()
679 for gp != nil && scanBytes > 0 {
680 // Note that gp.gcAssistBytes is negative because gp
681 // is in debt. Think carefully about the signs below.
682 if scanBytes+gp.gcAssistBytes >= 0 {
683 // Satisfy this entire assist debt.
684 scanBytes += gp.gcAssistBytes
685 gp.gcAssistBytes = 0
686 xgp := gp
687 gp = gp.schedlink.ptr()
Austin Clements44497eb2016-05-17 18:46:03 -0400688 // It's important that we *not* put xgp in
689 // runnext. Otherwise, it's possible for user
690 // code to exploit the GC worker's high
691 // scheduler priority to get itself always run
692 // before other goroutines and always in the
693 // fresh quantum started by GC.
694 ready(xgp, 0, false)
Austin Clements15aa6bb2015-10-14 21:31:33 -0400695 } else {
696 // Partially satisfy this assist.
697 gp.gcAssistBytes += scanBytes
698 scanBytes = 0
699 // As a heuristic, we move this assist to the
700 // back of the queue so that large assists
701 // can't clog up the assist queue and
702 // substantially delay small assists.
703 xgp := gp
704 gp = gp.schedlink.ptr()
705 if gp == nil {
706 // gp is the only assist in the queue.
707 gp = xgp
708 } else {
709 xgp.schedlink = 0
710 work.assistQueue.tail.ptr().schedlink.set(xgp)
711 work.assistQueue.tail.set(xgp)
712 }
713 break
714 }
715 }
716 work.assistQueue.head.set(gp)
717 if gp == nil {
718 work.assistQueue.tail.set(nil)
719 }
720
721 if scanBytes > 0 {
722 // Convert from scan bytes back to work.
723 scanWork = int64(float64(scanBytes) * gcController.assistWorkPerByte)
Michael Matloob67faca72015-11-02 14:09:24 -0500724 atomic.Xaddint64(&gcController.bgScanCredit, scanWork)
Austin Clements15aa6bb2015-10-14 21:31:33 -0400725 }
726 unlock(&work.assistQueue.lock)
727}
728
Austin Clementsa1f7db82016-05-23 22:05:51 -0400729// scanstack scans gp's stack, greying all pointers found on the stack.
730//
Austin Clementsa1f7db82016-05-23 22:05:51 -0400731// scanstack is marked go:systemstack because it must not be preempted
732// while using a workbuf.
733//
Russ Cox484f8012015-02-19 13:38:46 -0500734//go:nowritebarrier
Austin Clementsa1f7db82016-05-23 22:05:51 -0400735//go:systemstack
Austin Clements3be48b42016-05-23 22:14:53 -0400736func scanstack(gp *g, gcw *gcWork) {
Russ Cox484f8012015-02-19 13:38:46 -0500737 if gp.gcscanvalid {
738 return
739 }
740
741 if readgstatus(gp)&_Gscan == 0 {
742 print("runtime:scanstack: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", hex(readgstatus(gp)), "\n")
743 throw("scanstack - bad status")
744 }
745
746 switch readgstatus(gp) &^ _Gscan {
747 default:
748 print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
749 throw("mark - bad status")
750 case _Gdead:
751 return
752 case _Grunning:
753 print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
754 throw("scanstack: goroutine not stopped")
755 case _Grunnable, _Gsyscall, _Gwaiting:
756 // ok
757 }
758
759 if gp == getg() {
760 throw("can't scan our own stack")
761 }
762 mp := gp.m
763 if mp != nil && mp.helpgc != 0 {
764 throw("can't scan gchelper stack")
765 }
766
Austin Clementsf11e4eb2016-02-15 18:30:48 -0500767 // Shrink the stack if not much of it is being used. During
768 // concurrent GC, we can do this during concurrent mark.
769 if !work.markrootDone {
770 shrinkstack(gp)
771 }
772
Austin Clements3beaf262017-10-22 21:37:05 -0400773 // Scan the saved context register. This is effectively a live
774 // register that gets moved back and forth between the
775 // register and sched.ctxt without a write barrier.
776 if gp.sched.ctxt != nil {
777 scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), sys.PtrSize, &oneptrmask[0], gcw)
778 }
779
Austin Clementsf11e4eb2016-02-15 18:30:48 -0500780 // Scan the stack.
Austin Clementsbeedb1e2015-08-12 23:43:43 -0400781 var cache pcvalueCache
Russ Cox484f8012015-02-19 13:38:46 -0500782 scanframe := func(frame *stkframe, unused unsafe.Pointer) bool {
Austin Clementsbeedb1e2015-08-12 23:43:43 -0400783 scanframeworker(frame, &cache, gcw)
Russ Cox484f8012015-02-19 13:38:46 -0500784 return true
785 }
786 gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, scanframe, nil, 0)
787 tracebackdefers(gp, scanframe, nil)
Russ Cox484f8012015-02-19 13:38:46 -0500788 gp.gcscanvalid = true
789}
790
791// Scan a stack frame: local variables and function arguments/results.
792//go:nowritebarrier
Austin Clementsbeedb1e2015-08-12 23:43:43 -0400793func scanframeworker(frame *stkframe, cache *pcvalueCache, gcw *gcWork) {
Russ Cox484f8012015-02-19 13:38:46 -0500794
795 f := frame.fn
796 targetpc := frame.continpc
797 if targetpc == 0 {
798 // Frame is dead.
799 return
800 }
801 if _DebugGC > 1 {
802 print("scanframe ", funcname(f), "\n")
803 }
804 if targetpc != f.entry {
805 targetpc--
806 }
Austin Clementsbeedb1e2015-08-12 23:43:43 -0400807 pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
Russ Cox484f8012015-02-19 13:38:46 -0500808 if pcdata == -1 {
809 // We do not have a valid pcdata value but there might be a
Brad Fitzpatrick5fea2cc2016-03-01 23:21:55 +0000810 // stackmap for this function. It is likely that we are looking
Russ Cox484f8012015-02-19 13:38:46 -0500811 // at the function prologue, assume so and hope for the best.
812 pcdata = 0
813 }
814
815 // Scan local variables if stack frame has been allocated.
816 size := frame.varp - frame.sp
817 var minsize uintptr
Jeremy Jackinsba09d062016-04-07 15:42:35 +0900818 switch sys.ArchFamily {
819 case sys.ARM64:
Michael Matloob432cb662015-11-11 12:39:30 -0500820 minsize = sys.SpAlign
Aram Hăvărneanu846ee042015-03-08 14:20:20 +0100821 default:
Michael Matloob432cb662015-11-11 12:39:30 -0500822 minsize = sys.MinFrameSize
Russ Cox484f8012015-02-19 13:38:46 -0500823 }
824 if size > minsize {
825 stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
826 if stkmap == nil || stkmap.n <= 0 {
827 print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
828 throw("missing stackmap")
829 }
830
831 // Locals bitmap information, scan just the pointers in locals.
832 if pcdata < 0 || pcdata >= stkmap.n {
833 // don't know where we are
834 print("runtime: pcdata is ", pcdata, " and ", stkmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n")
835 throw("scanframe: bad symbol table")
836 }
837 bv := stackmapdata(stkmap, pcdata)
Michael Matloob432cb662015-11-11 12:39:30 -0500838 size = uintptr(bv.n) * sys.PtrSize
Russ Cox484f8012015-02-19 13:38:46 -0500839 scanblock(frame.varp-size, size, bv.bytedata, gcw)
840 }
841
842 // Scan arguments.
843 if frame.arglen > 0 {
844 var bv bitvector
845 if frame.argmap != nil {
846 bv = *frame.argmap
847 } else {
848 stkmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
849 if stkmap == nil || stkmap.n <= 0 {
850 print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(frame.arglen), "\n")
851 throw("missing stackmap")
852 }
853 if pcdata < 0 || pcdata >= stkmap.n {
854 // don't know where we are
855 print("runtime: pcdata is ", pcdata, " and ", stkmap.n, " args stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n")
856 throw("scanframe: bad symbol table")
857 }
858 bv = stackmapdata(stkmap, pcdata)
859 }
Michael Matloob432cb662015-11-11 12:39:30 -0500860 scanblock(frame.argp, uintptr(bv.n)*sys.PtrSize, bv.bytedata, gcw)
Russ Cox484f8012015-02-19 13:38:46 -0500861 }
862}
863
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400864type gcDrainFlags int
Austin Clements8d03acc2015-03-23 21:07:33 -0400865
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400866const (
867 gcDrainUntilPreempt gcDrainFlags = 1 << iota
Austin Clements62ba5202015-10-26 16:29:25 -0400868 gcDrainNoBlock
Austin Clementsc18b1632015-10-04 22:47:27 -0400869 gcDrainFlushBgCredit
Austin Clements49ea92072016-10-30 20:20:17 -0400870 gcDrainIdle
Austin Clements28e1a8e2017-10-04 16:15:35 -0400871 gcDrainFractional
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400872
Austin Clements62ba5202015-10-26 16:29:25 -0400873 // gcDrainBlock means neither gcDrainUntilPreempt or
874 // gcDrainNoBlock. It is the default, but callers should use
875 // the constant for documentation purposes.
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400876 gcDrainBlock gcDrainFlags = 0
877)
878
Austin Clements82d14d72015-10-19 13:46:32 -0400879// gcDrain scans roots and objects in work buffers, blackening grey
880// objects until all roots and work buffers have been drained.
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400881//
Austin Clements62ba5202015-10-26 16:29:25 -0400882// If flags&gcDrainUntilPreempt != 0, gcDrain returns when g.preempt
883// is set. This implies gcDrainNoBlock.
884//
Austin Clements49ea92072016-10-30 20:20:17 -0400885// If flags&gcDrainIdle != 0, gcDrain returns when there is other work
886// to do. This implies gcDrainNoBlock.
887//
Austin Clements28e1a8e2017-10-04 16:15:35 -0400888// If flags&gcDrainFractional != 0, gcDrain self-preempts when
889// pollFractionalWorkerExit() returns true. This implies
890// gcDrainNoBlock.
891//
Austin Clements62ba5202015-10-26 16:29:25 -0400892// If flags&gcDrainNoBlock != 0, gcDrain returns as soon as it is
893// unable to get more work. Otherwise, it will block until all
894// blocking calls are blocked in gcDrain.
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400895//
Austin Clementsc18b1632015-10-04 22:47:27 -0400896// If flags&gcDrainFlushBgCredit != 0, gcDrain flushes scan work
Austin Clements8e8219d2015-10-04 23:00:01 -0400897// credit to gcController.bgScanCredit every gcCreditSlack units of
Austin Clementsc18b1632015-10-04 22:47:27 -0400898// scan work.
Austin Clements62ba5202015-10-26 16:29:25 -0400899//
Russ Cox484f8012015-02-19 13:38:46 -0500900//go:nowritebarrier
Austin Clementsc18b1632015-10-04 22:47:27 -0400901func gcDrain(gcw *gcWork, flags gcDrainFlags) {
Ian Lance Taylorbe1ef462015-11-13 17:45:22 -0800902 if !writeBarrier.needed {
Austin Clementsf5e67e52015-07-24 12:33:23 -0400903 throw("gcDrain phase incorrect")
Russ Cox484f8012015-02-19 13:38:46 -0500904 }
905
Austin Clementsdd500192016-10-27 21:52:51 -0400906 gp := getg().m.curg
Rick Hudson9439fa12016-01-06 17:07:58 -0500907 preemptible := flags&gcDrainUntilPreempt != 0
Austin Clements28e1a8e2017-10-04 16:15:35 -0400908 blocking := flags&(gcDrainUntilPreempt|gcDrainIdle|gcDrainFractional|gcDrainNoBlock) == 0
Austin Clementsc18b1632015-10-04 22:47:27 -0400909 flushBgCredit := flags&gcDrainFlushBgCredit != 0
Austin Clements49ea92072016-10-30 20:20:17 -0400910 idle := flags&gcDrainIdle != 0
911
912 initScanWork := gcw.scanWork
Austin Clements28e1a8e2017-10-04 16:15:35 -0400913
914 // checkWork is the scan work before performing the next
915 // self-preempt check.
916 checkWork := int64(1<<63 - 1)
917 var check func() bool
918 if flags&(gcDrainIdle|gcDrainFractional) != 0 {
919 checkWork = initScanWork + drainCheckThreshold
920 if idle {
921 check = pollWork
922 } else if flags&gcDrainFractional != 0 {
923 check = pollFractionalWorkerExit
924 }
925 }
Austin Clements8d03acc2015-03-23 21:07:33 -0400926
Austin Clements82d14d72015-10-19 13:46:32 -0400927 // Drain root marking jobs.
928 if work.markrootNext < work.markrootJobs {
Austin Clementsd70b0fe2016-10-28 11:14:07 -0400929 for !(preemptible && gp.preempt) {
Michael Matloob67faca72015-11-02 14:09:24 -0500930 job := atomic.Xadd(&work.markrootNext, +1) - 1
Austin Clements82d14d72015-10-19 13:46:32 -0400931 if job >= work.markrootJobs {
932 break
933 }
Austin Clements7b229002015-11-23 18:44:03 -0500934 markroot(gcw, job)
Austin Clements28e1a8e2017-10-04 16:15:35 -0400935 if check != nil && check() {
Austin Clements49ea92072016-10-30 20:20:17 -0400936 goto done
937 }
Austin Clements82d14d72015-10-19 13:46:32 -0400938 }
939 }
940
Austin Clements82d14d72015-10-19 13:46:32 -0400941 // Drain heap marking jobs.
Rick Hudson9439fa12016-01-06 17:07:58 -0500942 for !(preemptible && gp.preempt) {
943 // Try to keep work available on the global queue. We used to
944 // check if there were waiting workers, but it's better to
945 // just keep work available than to make workers wait. In the
946 // worst case, we'll do O(log(_WorkbufSize)) unnecessary
947 // balances.
948 if work.full == 0 {
Austin Clements8d03acc2015-03-23 21:07:33 -0400949 gcw.balance()
950 }
951
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400952 var b uintptr
953 if blocking {
954 b = gcw.get()
955 } else {
Rick Hudson1354b322016-03-14 12:17:48 -0400956 b = gcw.tryGetFast()
957 if b == 0 {
958 b = gcw.tryGet()
959 }
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400960 }
Austin Clements8d03acc2015-03-23 21:07:33 -0400961 if b == 0 {
Austin Clements9b3cdaf2015-10-04 22:42:43 -0400962 // work barrier reached or tryGet failed.
Austin Clements8d03acc2015-03-23 21:07:33 -0400963 break
964 }
Russ Cox4d0f3a12015-04-27 22:45:57 -0400965 scanobject(b, gcw)
Austin Clements8d03acc2015-03-23 21:07:33 -0400966
967 // Flush background scan work credit to the global
968 // account if we've accumulated enough locally so
969 // mutator assists can draw on it.
Austin Clements8e8219d2015-10-04 23:00:01 -0400970 if gcw.scanWork >= gcCreditSlack {
Michael Matloob67faca72015-11-02 14:09:24 -0500971 atomic.Xaddint64(&gcController.scanWork, gcw.scanWork)
Austin Clements8e8219d2015-10-04 23:00:01 -0400972 if flushBgCredit {
Austin Clements15aa6bb2015-10-14 21:31:33 -0400973 gcFlushBgCredit(gcw.scanWork - initScanWork)
Austin Clements8e8219d2015-10-04 23:00:01 -0400974 initScanWork = 0
975 }
Austin Clements28e1a8e2017-10-04 16:15:35 -0400976 checkWork -= gcw.scanWork
Austin Clements8e8219d2015-10-04 23:00:01 -0400977 gcw.scanWork = 0
Austin Clements49ea92072016-10-30 20:20:17 -0400978
Austin Clements28e1a8e2017-10-04 16:15:35 -0400979 if checkWork <= 0 {
980 checkWork += drainCheckThreshold
981 if check != nil && check() {
Austin Clements49ea92072016-10-30 20:20:17 -0400982 break
983 }
984 }
Austin Clements8d03acc2015-03-23 21:07:33 -0400985 }
986 }
Austin Clements8e8219d2015-10-04 23:00:01 -0400987
Austin Clementsab9d5f32015-11-19 11:25:55 -0500988 // In blocking mode, write barriers are not allowed after this
989 // point because we must preserve the condition that the work
990 // buffers are empty.
991
Austin Clements49ea92072016-10-30 20:20:17 -0400992done:
Austin Clements8e8219d2015-10-04 23:00:01 -0400993 // Flush remaining scan work credit.
994 if gcw.scanWork > 0 {
Michael Matloob67faca72015-11-02 14:09:24 -0500995 atomic.Xaddint64(&gcController.scanWork, gcw.scanWork)
Austin Clements8e8219d2015-10-04 23:00:01 -0400996 if flushBgCredit {
Austin Clements15aa6bb2015-10-14 21:31:33 -0400997 gcFlushBgCredit(gcw.scanWork - initScanWork)
Austin Clements8e8219d2015-10-04 23:00:01 -0400998 }
999 gcw.scanWork = 0
Austin Clements8d03acc2015-03-23 21:07:33 -04001000 }
1001}
1002
Austin Clements028f9722015-03-13 14:01:16 -04001003// gcDrainN blackens grey objects until it has performed roughly
Austin Clements45652832015-10-15 17:58:17 -04001004// scanWork units of scan work or the G is preempted. This is
1005// best-effort, so it may perform less work if it fails to get a work
1006// buffer. Otherwise, it will perform at least n units of work, but
1007// may perform more because scanning is always done in whole object
1008// increments. It returns the amount of scan work performed.
Austin Clementsd35dfd42016-10-30 17:59:06 -04001009//
1010// The caller goroutine must be in a preemptible state (e.g.,
1011// _Gwaiting) to prevent deadlocks during stack scanning. As a
1012// consequence, this must be called on the system stack.
1013//
Russ Cox484f8012015-02-19 13:38:46 -05001014//go:nowritebarrier
Austin Clementsd35dfd42016-10-30 17:59:06 -04001015//go:systemstack
Austin Clements8e8219d2015-10-04 23:00:01 -04001016func gcDrainN(gcw *gcWork, scanWork int64) int64 {
Ian Lance Taylorbe1ef462015-11-13 17:45:22 -08001017 if !writeBarrier.needed {
Austin Clementsf5e67e52015-07-24 12:33:23 -04001018 throw("gcDrainN phase incorrect")
1019 }
Austin Clements8e8219d2015-10-04 23:00:01 -04001020
1021 // There may already be scan work on the gcw, which we don't
1022 // want to claim was done by this call.
1023 workFlushed := -gcw.scanWork
1024
Austin Clements45652832015-10-15 17:58:17 -04001025 gp := getg().m.curg
1026 for !gp.preempt && workFlushed+gcw.scanWork < scanWork {
Rick Hudson9439fa12016-01-06 17:07:58 -05001027 // See gcDrain comment.
1028 if work.full == 0 {
1029 gcw.balance()
1030 }
1031
Russ Cox484f8012015-02-19 13:38:46 -05001032 // This might be a good place to add prefetch code...
1033 // if(wbuf.nobj > 4) {
1034 // PREFETCH(wbuf->obj[wbuf.nobj - 3];
1035 // }
Rick Hudson9439fa12016-01-06 17:07:58 -05001036 //
Rick Hudson1354b322016-03-14 12:17:48 -04001037 b := gcw.tryGetFast()
1038 if b == 0 {
1039 b = gcw.tryGet()
1040 }
1041
Russ Cox484f8012015-02-19 13:38:46 -05001042 if b == 0 {
Austin Clementsd35dfd42016-10-30 17:59:06 -04001043 // Try to do a root job.
1044 //
1045 // TODO: Assists should get credit for this
1046 // work.
1047 if work.markrootNext < work.markrootJobs {
1048 job := atomic.Xadd(&work.markrootNext, +1) - 1
1049 if job < work.markrootJobs {
1050 markroot(gcw, job)
1051 continue
1052 }
1053 }
1054 // No heap or root jobs.
Austin Clements8e8219d2015-10-04 23:00:01 -04001055 break
Russ Cox484f8012015-02-19 13:38:46 -05001056 }
Russ Cox4d0f3a12015-04-27 22:45:57 -04001057 scanobject(b, gcw)
Austin Clements8e8219d2015-10-04 23:00:01 -04001058
1059 // Flush background scan work credit.
1060 if gcw.scanWork >= gcCreditSlack {
Michael Matloob67faca72015-11-02 14:09:24 -05001061 atomic.Xaddint64(&gcController.scanWork, gcw.scanWork)
Austin Clements8e8219d2015-10-04 23:00:01 -04001062 workFlushed += gcw.scanWork
1063 gcw.scanWork = 0
1064 }
Russ Cox484f8012015-02-19 13:38:46 -05001065 }
Austin Clements8e8219d2015-10-04 23:00:01 -04001066
1067 // Unlike gcDrain, there's no need to flush remaining work
1068 // here because this never flushes to bgScanCredit and
1069 // gcw.dispose will flush any remaining work to scanWork.
1070
1071 return workFlushed + gcw.scanWork
Russ Cox484f8012015-02-19 13:38:46 -05001072}
1073
Russ Cox4d0f3a12015-04-27 22:45:57 -04001074// scanblock scans b as scanobject would, but using an explicit
1075// pointer bitmap instead of the heap bitmap.
Austin Clements3be3cbd2015-05-04 16:10:49 -04001076//
1077// This is used to scan non-heap roots, so it does not update
1078// gcw.bytesMarked or gcw.scanWork.
1079//
Russ Cox484f8012015-02-19 13:38:46 -05001080//go:nowritebarrier
Austin Clementscadd4f82015-03-12 13:09:30 -04001081func scanblock(b0, n0 uintptr, ptrmask *uint8, gcw *gcWork) {
Russ Cox484f8012015-02-19 13:38:46 -05001082 // Use local copies of original parameters, so that a stack trace
1083 // due to one of the throws below shows the original block
1084 // base and extent.
1085 b := b0
1086 n := n0
1087
Russ Cox4d0f3a12015-04-27 22:45:57 -04001088 arena_start := mheap_.arena_start
1089 arena_used := mheap_.arena_used
Russ Cox484f8012015-02-19 13:38:46 -05001090
Russ Cox4d0f3a12015-04-27 22:45:57 -04001091 for i := uintptr(0); i < n; {
1092 // Find bits for the next word.
Michael Matloob432cb662015-11-11 12:39:30 -05001093 bits := uint32(*addb(ptrmask, i/(sys.PtrSize*8)))
Russ Cox4d0f3a12015-04-27 22:45:57 -04001094 if bits == 0 {
Michael Matloob432cb662015-11-11 12:39:30 -05001095 i += sys.PtrSize * 8
Russ Cox4d0f3a12015-04-27 22:45:57 -04001096 continue
1097 }
1098 for j := 0; j < 8 && i < n; j++ {
1099 if bits&1 != 0 {
1100 // Same work as in scanobject; see comments there.
1101 obj := *(*uintptr)(unsafe.Pointer(b + i))
Russ Cox4d0f3a12015-04-27 22:45:57 -04001102 if obj != 0 && arena_start <= obj && obj < arena_used {
Rick Hudson2063d5d2016-03-14 12:17:48 -04001103 if obj, hbits, span, objIndex := heapBitsForObject(obj, b, i); obj != 0 {
1104 greyobject(obj, b, i, hbits, span, gcw, objIndex)
Russ Cox4d0f3a12015-04-27 22:45:57 -04001105 }
1106 }
1107 }
1108 bits >>= 1
Michael Matloob432cb662015-11-11 12:39:30 -05001109 i += sys.PtrSize
Russ Cox484f8012015-02-19 13:38:46 -05001110 }
1111 }
1112}
1113
Russ Cox4d0f3a12015-04-27 22:45:57 -04001114// scanobject scans the object starting at b, adding pointers to gcw.
Austin Clementscf4f1d02016-05-27 21:04:40 -04001115// b must point to the beginning of a heap object or an oblet.
1116// scanobject consults the GC bitmap for the pointer mask and the
1117// spans for the size of the object.
1118//
Russ Cox484f8012015-02-19 13:38:46 -05001119//go:nowritebarrier
Russ Cox4d0f3a12015-04-27 22:45:57 -04001120func scanobject(b uintptr, gcw *gcWork) {
Austin Clements2a331ca2015-06-19 12:29:42 -04001121 // Note that arena_used may change concurrently during
1122 // scanobject and hence scanobject may encounter a pointer to
1123 // a newly allocated heap object that is *not* in
1124 // [start,used). It will not mark this object; however, we
1125 // know that it was just installed by a mutator, which means
1126 // that mutator will execute a write barrier and take care of
1127 // marking it. This is even more pronounced on relaxed memory
1128 // architectures since we access arena_used without barriers
1129 // or synchronization, but the same logic applies.
Russ Cox484f8012015-02-19 13:38:46 -05001130 arena_start := mheap_.arena_start
1131 arena_used := mheap_.arena_used
1132
Austin Clementscf4f1d02016-05-27 21:04:40 -04001133 // Find the bits for b and the size of the object at b.
1134 //
1135 // b is either the beginning of an object, in which case this
1136 // is the size of the object to scan, or it points to an
1137 // oblet, in which case we compute the size to scan below.
Russ Cox4d0f3a12015-04-27 22:45:57 -04001138 hbits := heapBitsForAddr(b)
1139 s := spanOfUnchecked(b)
1140 n := s.elemsize
1141 if n == 0 {
1142 throw("scanobject n == 0")
Russ Cox484f8012015-02-19 13:38:46 -05001143 }
Russ Cox4d0f3a12015-04-27 22:45:57 -04001144
Austin Clementscf4f1d02016-05-27 21:04:40 -04001145 if n > maxObletBytes {
1146 // Large object. Break into oblets for better
1147 // parallelism and lower latency.
1148 if b == s.base() {
1149 // It's possible this is a noscan object (not
1150 // from greyobject, but from other code
1151 // paths), in which case we must *not* enqueue
1152 // oblets since their bitmaps will be
1153 // uninitialized.
Austin Clementsc44d0312016-06-02 11:07:41 -04001154 if s.spanclass.noscan() {
Austin Clementscf4f1d02016-05-27 21:04:40 -04001155 // Bypass the whole scan.
1156 gcw.bytesMarked += uint64(n)
1157 return
1158 }
1159
1160 // Enqueue the other oblets to scan later.
1161 // Some oblets may be in b's scalar tail, but
1162 // these will be marked as "no more pointers",
1163 // so we'll drop out immediately when we go to
1164 // scan those.
1165 for oblet := b + maxObletBytes; oblet < s.base()+s.elemsize; oblet += maxObletBytes {
1166 if !gcw.putFast(oblet) {
1167 gcw.put(oblet)
1168 }
1169 }
1170 }
1171
1172 // Compute the size of the oblet. Since this object
1173 // must be a large object, s.base() is the beginning
1174 // of the object.
1175 n = s.base() + s.elemsize - b
1176 if n > maxObletBytes {
1177 n = maxObletBytes
1178 }
1179 }
1180
Austin Clements53c53982015-05-04 15:40:58 -04001181 var i uintptr
Michael Matloob432cb662015-11-11 12:39:30 -05001182 for i = 0; i < n; i += sys.PtrSize {
Russ Cox484f8012015-02-19 13:38:46 -05001183 // Find bits for this word.
Russ Cox4d0f3a12015-04-27 22:45:57 -04001184 if i != 0 {
1185 // Avoid needless hbits.next() on last iteration.
1186 hbits = hbits.next()
1187 }
Josh Bleecher Snyder0e7e4362016-05-01 18:02:41 -07001188 // Load bits once. See CL 22712 and issue 16973 for discussion.
1189 bits := hbits.bits()
Russ Cox0234dfd2015-05-04 10:19:24 -04001190 // During checkmarking, 1-word objects store the checkmark
1191 // in the type bit for the one word. The only one-word objects
1192 // are pointers, or else they'd be merged with other non-pointer
1193 // data into larger allocations.
Josh Bleecher Snyder0e7e4362016-05-01 18:02:41 -07001194 if i != 1*sys.PtrSize && bits&bitScan == 0 {
Russ Coxfeb8a3b2015-05-04 11:30:10 -04001195 break // no more pointers in this object
Russ Cox484f8012015-02-19 13:38:46 -05001196 }
Josh Bleecher Snyder0e7e4362016-05-01 18:02:41 -07001197 if bits&bitPointer == 0 {
Russ Coxfeb8a3b2015-05-04 11:30:10 -04001198 continue // not a pointer
1199 }
Russ Cox4d0f3a12015-04-27 22:45:57 -04001200
Russ Coxfeb8a3b2015-05-04 11:30:10 -04001201 // Work here is duplicated in scanblock and above.
1202 // If you make changes here, make changes there too.
Russ Cox484f8012015-02-19 13:38:46 -05001203 obj := *(*uintptr)(unsafe.Pointer(b + i))
1204
1205 // At this point we have extracted the next potential pointer.
Russ Cox8903b3d2015-05-18 11:40:29 -04001206 // Check if it points into heap and not back at the current object.
1207 if obj != 0 && arena_start <= obj && obj < arena_used && obj-b >= n {
Russ Cox4d0f3a12015-04-27 22:45:57 -04001208 // Mark the object.
Rick Hudson2063d5d2016-03-14 12:17:48 -04001209 if obj, hbits, span, objIndex := heapBitsForObject(obj, b, i); obj != 0 {
1210 greyobject(obj, b, i, hbits, span, gcw, objIndex)
Russ Cox4d0f3a12015-04-27 22:45:57 -04001211 }
Russ Cox484f8012015-02-19 13:38:46 -05001212 }
1213 }
Austin Clements50a66562015-03-12 16:53:57 -04001214 gcw.bytesMarked += uint64(n)
Austin Clements53c53982015-05-04 15:40:58 -04001215 gcw.scanWork += int64(i)
Russ Cox484f8012015-02-19 13:38:46 -05001216}
1217
1218// Shade the object if it isn't already.
1219// The object is not nil and known to be in the heap.
Austin Clements1b4025f2015-04-19 15:22:20 -04001220// Preemption must be disabled.
Russ Cox484f8012015-02-19 13:38:46 -05001221//go:nowritebarrier
1222func shade(b uintptr) {
Rick Hudson2063d5d2016-03-14 12:17:48 -04001223 if obj, hbits, span, objIndex := heapBitsForObject(b, 0, 0); obj != 0 {
Austin Clements1b4025f2015-04-19 15:22:20 -04001224 gcw := &getg().m.p.ptr().gcw
Rick Hudson2063d5d2016-03-14 12:17:48 -04001225 greyobject(obj, 0, 0, hbits, span, gcw, objIndex)
Rick Hudson90a19962015-06-01 18:16:03 -04001226 if gcphase == _GCmarktermination || gcBlackenPromptly {
Austin Clements1b4025f2015-04-19 15:22:20 -04001227 // Ps aren't allowed to cache work during mark
1228 // termination.
Russ Cox484f8012015-02-19 13:38:46 -05001229 gcw.dispose()
Russ Cox484f8012015-02-19 13:38:46 -05001230 }
1231 }
1232}
1233
1234// obj is the start of an object with mark mbits.
Austin Clements33e0f3d2015-04-27 15:42:45 -04001235// If it isn't already marked, mark it and enqueue into gcw.
Russ Cox484f8012015-02-19 13:38:46 -05001236// base and off are for debugging only and could be removed.
Austin Clementse9079a62017-10-26 12:21:16 -04001237//
1238// See also wbBufFlush1, which partially duplicates this logic.
1239//
Austin Clements27df2e32015-11-24 14:03:58 -05001240//go:nowritebarrierrec
Rick Hudson2063d5d2016-03-14 12:17:48 -04001241func greyobject(obj, base, off uintptr, hbits heapBits, span *mspan, gcw *gcWork, objIndex uintptr) {
Russ Cox484f8012015-02-19 13:38:46 -05001242 // obj should be start of allocation, and so must be at least pointer-aligned.
Michael Matloob432cb662015-11-11 12:39:30 -05001243 if obj&(sys.PtrSize-1) != 0 {
Russ Cox484f8012015-02-19 13:38:46 -05001244 throw("greyobject: obj not pointer-aligned")
1245 }
Rick Hudson2063d5d2016-03-14 12:17:48 -04001246 mbits := span.markBitsForIndex(objIndex)
1247
Russ Cox89a091d2015-02-19 16:43:27 -05001248 if useCheckmark {
Rick Hudson3479b062016-02-11 13:57:58 -05001249 if !mbits.isMarked() {
Austin Clements506615d2015-03-12 14:26:04 -04001250 printlock()
Russ Cox484f8012015-02-19 13:38:46 -05001251 print("runtime:greyobject: checkmarks finds unexpected unmarked object obj=", hex(obj), "\n")
1252 print("runtime: found obj at *(", hex(base), "+", hex(off), ")\n")
1253
1254 // Dump the source (base) object
Austin Clements506615d2015-03-12 14:26:04 -04001255 gcDumpObject("base", base, off)
Russ Cox484f8012015-02-19 13:38:46 -05001256
1257 // Dump the object
Austin Clements506615d2015-03-12 14:26:04 -04001258 gcDumpObject("obj", obj, ^uintptr(0))
Russ Cox484f8012015-02-19 13:38:46 -05001259
Austin Clementsb992c262017-03-07 15:20:40 -05001260 getg().m.traceback = 2
Russ Cox484f8012015-02-19 13:38:46 -05001261 throw("checkmark found unmarked object")
1262 }
Russ Cox0234dfd2015-05-04 10:19:24 -04001263 if hbits.isCheckmarked(span.elemsize) {
Russ Cox484f8012015-02-19 13:38:46 -05001264 return
1265 }
Russ Cox0234dfd2015-05-04 10:19:24 -04001266 hbits.setCheckmarked(span.elemsize)
1267 if !hbits.isCheckmarked(span.elemsize) {
Russ Cox484f8012015-02-19 13:38:46 -05001268 throw("setCheckmarked and isCheckmarked disagree")
1269 }
1270 } else {
Austin Clementsd1cc8342016-10-03 16:18:17 -04001271 if debug.gccheckmark > 0 && span.isFree(objIndex) {
1272 print("runtime: marking free object ", hex(obj), " found at *(", hex(base), "+", hex(off), ")\n")
1273 gcDumpObject("base", base, off)
1274 gcDumpObject("obj", obj, ^uintptr(0))
Austin Clementsb992c262017-03-07 15:20:40 -05001275 getg().m.traceback = 2
Austin Clementsd1cc8342016-10-03 16:18:17 -04001276 throw("marking free object")
1277 }
1278
Russ Cox484f8012015-02-19 13:38:46 -05001279 // If marked we have nothing to do.
Rick Hudson3479b062016-02-11 13:57:58 -05001280 if mbits.isMarked() {
Russ Cox484f8012015-02-19 13:38:46 -05001281 return
1282 }
Rick Hudson2063d5d2016-03-14 12:17:48 -04001283 // mbits.setMarked() // Avoid extra call overhead with manual inlining.
1284 atomic.Or8(mbits.bytep, mbits.mask)
Austin Clementsda4874c2015-02-27 12:41:20 -05001285 // If this is a noscan object, fast-track it to black
1286 // instead of greying it.
Austin Clementsc44d0312016-06-02 11:07:41 -04001287 if span.spanclass.noscan() {
Austin Clements50a66562015-03-12 16:53:57 -04001288 gcw.bytesMarked += uint64(span.elemsize)
Austin Clementsda4874c2015-02-27 12:41:20 -05001289 return
1290 }
Russ Cox484f8012015-02-19 13:38:46 -05001291 }
1292
1293 // Queue the obj for scanning. The PREFETCH(obj) logic has been removed but
1294 // seems like a nice optimization that can be added back in.
1295 // There needs to be time between the PREFETCH and the use.
1296 // Previously we put the obj in an 8 element buffer that is drained at a rate
1297 // to give the PREFETCH time to do its work.
1298 // Use of PREFETCHNTA might be more appropriate than PREFETCH
Rick Hudson1354b322016-03-14 12:17:48 -04001299 if !gcw.putFast(obj) {
1300 gcw.put(obj)
1301 }
Russ Cox484f8012015-02-19 13:38:46 -05001302}
1303
Austin Clements506615d2015-03-12 14:26:04 -04001304// gcDumpObject dumps the contents of obj for debugging and marks the
1305// field at byte offset off in obj.
1306func gcDumpObject(label string, obj, off uintptr) {
Austin Clements3ca20212015-04-29 15:15:43 -04001307 if obj < mheap_.arena_start || obj >= mheap_.arena_used {
Austin Clementsb7c55ba2015-09-18 11:55:31 -04001308 print(label, "=", hex(obj), " is not in the Go heap\n")
Austin Clements3ca20212015-04-29 15:15:43 -04001309 return
1310 }
Austin Clements506615d2015-03-12 14:26:04 -04001311 k := obj >> _PageShift
1312 x := k
1313 x -= mheap_.arena_start >> _PageShift
Austin Clements6b0f6682016-10-04 16:03:00 -04001314 s := mheap_.spans[x]
Austin Clements506615d2015-03-12 14:26:04 -04001315 print(label, "=", hex(obj), " k=", hex(k))
1316 if s == nil {
1317 print(" s=nil\n")
1318 return
1319 }
Austin Clements1a033b12016-02-09 17:53:07 -05001320 print(" s.base()=", hex(s.base()), " s.limit=", hex(s.limit), " s.spanclass=", s.spanclass, " s.elemsize=", s.elemsize, " s.state=")
Austin Clements38f1df62016-09-09 10:22:10 -04001321 if 0 <= s.state && int(s.state) < len(mSpanStateNames) {
1322 print(mSpanStateNames[s.state], "\n")
1323 } else {
1324 print("unknown(", s.state, ")\n")
1325 }
1326
Austin Clements97b64d82015-09-18 12:06:24 -04001327 skipped := false
Austin Clements38f1df62016-09-09 10:22:10 -04001328 size := s.elemsize
Austin Clements8fbaa4f2017-03-16 14:16:31 -04001329 if s.state == _MSpanManual && size == 0 {
Austin Clements38f1df62016-09-09 10:22:10 -04001330 // We're printing something from a stack frame. We
1331 // don't know how big it is, so just show up to an
1332 // including off.
1333 size = off + sys.PtrSize
1334 }
1335 for i := uintptr(0); i < size; i += sys.PtrSize {
Austin Clements97b64d82015-09-18 12:06:24 -04001336 // For big objects, just print the beginning (because
1337 // that usually hints at the object's type) and the
1338 // fields around off.
Michael Matloob432cb662015-11-11 12:39:30 -05001339 if !(i < 128*sys.PtrSize || off-16*sys.PtrSize < i && i < off+16*sys.PtrSize) {
Austin Clements97b64d82015-09-18 12:06:24 -04001340 skipped = true
1341 continue
1342 }
1343 if skipped {
1344 print(" ...\n")
1345 skipped = false
1346 }
Matthew Dempskya03bdc32016-02-29 15:01:00 -08001347 print(" *(", label, "+", i, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + i))))
Austin Clements506615d2015-03-12 14:26:04 -04001348 if i == off {
1349 print(" <==")
1350 }
1351 print("\n")
1352 }
Austin Clements97b64d82015-09-18 12:06:24 -04001353 if skipped {
1354 print(" ...\n")
1355 }
Austin Clements506615d2015-03-12 14:26:04 -04001356}
1357
Austin Clements64a26b72016-04-17 11:42:37 -04001358// gcmarknewobject marks a newly allocated object black. obj must
1359// not contain any non-nil pointers.
1360//
1361// This is nosplit so it can manipulate a gcWork without preemption.
1362//
Russ Cox484f8012015-02-19 13:38:46 -05001363//go:nowritebarrier
Austin Clements64a26b72016-04-17 11:42:37 -04001364//go:nosplit
1365func gcmarknewobject(obj, size, scanSize uintptr) {
Rick Hudson90a19962015-06-01 18:16:03 -04001366 if useCheckmark && !gcBlackenPromptly { // The world should be stopped so this should not happen.
Russ Cox484f8012015-02-19 13:38:46 -05001367 throw("gcmarknewobject called while doing checkmark")
1368 }
Rick Hudson3479b062016-02-11 13:57:58 -05001369 markBitsForAddr(obj).setMarked()
Austin Clements479501c2016-04-16 18:27:38 -04001370 gcw := &getg().m.p.ptr().gcw
Austin Clements64a26b72016-04-17 11:42:37 -04001371 gcw.bytesMarked += uint64(size)
Austin Clements479501c2016-04-16 18:27:38 -04001372 gcw.scanWork += int64(scanSize)
Austin Clements9429aab2016-09-11 16:55:34 -04001373 if gcBlackenPromptly {
1374 // There shouldn't be anything in the work queue, but
1375 // we still need to flush stats.
1376 gcw.dispose()
1377 }
Russ Cox484f8012015-02-19 13:38:46 -05001378}
1379
Austin Clements85c22bc2016-09-09 09:34:26 -04001380// gcMarkTinyAllocs greys all active tiny alloc blocks.
1381//
1382// The world must be stopped.
1383func gcMarkTinyAllocs() {
Austin Clements84d2c7e2017-06-13 11:32:17 -04001384 for _, p := range allp {
Austin Clements85c22bc2016-09-09 09:34:26 -04001385 c := p.mcache
1386 if c == nil || c.tiny == 0 {
1387 continue
1388 }
1389 _, hbits, span, objIndex := heapBitsForObject(c.tiny, 0, 0)
1390 gcw := &p.gcw
1391 greyobject(c.tiny, 0, 0, hbits, span, gcw, objIndex)
1392 if gcBlackenPromptly {
1393 gcw.dispose()
1394 }
1395 }
1396}
1397
Russ Cox484f8012015-02-19 13:38:46 -05001398// Checkmarking
1399
1400// To help debug the concurrent GC we remark with the world
1401// stopped ensuring that any object encountered has their normal
1402// mark bit set. To do this we use an orthogonal bit
1403// pattern to indicate the object is marked. The following pattern
Ainar Garipov7f9f70e2015-06-11 16:49:38 +03001404// uses the upper two bits in the object's boundary nibble.
Russ Cox484f8012015-02-19 13:38:46 -05001405// 01: scalar not marked
1406// 10: pointer not marked
1407// 11: pointer marked
1408// 00: scalar marked
1409// Xoring with 01 will flip the pattern from marked to unmarked and vica versa.
1410// The higher bit is 1 for pointers and 0 for scalars, whether the object
1411// is marked or not.
1412// The first nibble no longer holds the typeDead pattern indicating that the
1413// there are no more pointers in the object. This information is held
1414// in the second nibble.
1415
Russ Cox89a091d2015-02-19 16:43:27 -05001416// If useCheckmark is true, marking of an object uses the
1417// checkmark bits (encoding above) instead of the standard
1418// mark bits.
1419var useCheckmark = false
Russ Cox484f8012015-02-19 13:38:46 -05001420
1421//go:nowritebarrier
1422func initCheckmarks() {
Russ Cox89a091d2015-02-19 16:43:27 -05001423 useCheckmark = true
Austin Clements575b1dd2016-10-05 21:22:33 -04001424 for _, s := range mheap_.allspans {
Russ Cox484f8012015-02-19 13:38:46 -05001425 if s.state == _MSpanInUse {
1426 heapBitsForSpan(s.base()).initCheckmarkSpan(s.layout())
1427 }
1428 }
1429}
1430
1431func clearCheckmarks() {
Russ Cox89a091d2015-02-19 16:43:27 -05001432 useCheckmark = false
Austin Clements575b1dd2016-10-05 21:22:33 -04001433 for _, s := range mheap_.allspans {
Russ Cox484f8012015-02-19 13:38:46 -05001434 if s.state == _MSpanInUse {
1435 heapBitsForSpan(s.base()).clearCheckmarkSpan(s.layout())
1436 }
1437 }
1438}