aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcmark.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2024-08-27 21:02:02 +0000
committerGopher Robot <gobot@golang.org>2025-02-03 08:21:09 -0800
commitb25b5f3ff4e671aa4f5897c788137fe91f62cf57 (patch)
treeef37f5db04b45dad5303ba33911a9ff133348705 /src/runtime/mgcmark.go
parent4f11d5879a01e64cb8bd59911bb205ffedd4f265 (diff)
downloadgo-b25b5f3ff4e671aa4f5897c788137fe91f62cf57.tar.xz
runtime: fix GODEBUG=gccheckmark=1 and add smoke test
This change fixes GODEBUG=gccheckmark=1 which seems to have bit-rotted. Because the root jobs weren't being reset, it wasn't doing anything. Then, it turned out that checkmark mode would queue up noscan objects in workbufs, which caused it to fail. Then it turned out checkmark mode was broken with user arenas, since their heap arenas are not registered anywhere. Then, it turned out that checkmark mode could just not run properly if the goroutine's preemption flag was set (since sched.gcwaiting is true during the STW). And lastly, it turned out that async preemption could cause erroneous checkmark failures. This change fixes all these issues and adds a simple smoke test to dist to run the runtime tests under gccheckmark, which exercises all of these issues. Fixes #69074. Fixes #69377. Fixes #69376. Change-Id: Iaa0bb7b9e63ed4ba34d222b47510d6292ce168bc Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest Reviewed-on: https://go-review.googlesource.com/c/go/+/608915 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
Diffstat (limited to 'src/runtime/mgcmark.go')
-rw-r--r--src/runtime/mgcmark.go16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 823b2bd7df..92ef215ee0 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -89,9 +89,9 @@ func gcMarkRootPrepare() {
//
// Break up the work into arenas, and further into chunks.
//
- // Snapshot allArenas as markArenas. This snapshot is safe because allArenas
+ // Snapshot heapArenas as markArenas. This snapshot is safe because heapArenas
// is append-only.
- mheap_.markArenas = mheap_.allArenas[:len(mheap_.allArenas):len(mheap_.allArenas)]
+ mheap_.markArenas = mheap_.heapArenas[:len(mheap_.heapArenas):len(mheap_.heapArenas)]
work.nSpanRoots = len(mheap_.markArenas) * (pagesPerArena / pagesPerSpanRoot)
// Scan stacks.
@@ -1614,13 +1614,13 @@ func greyobject(obj, base, off uintptr, span *mspan, gcw *gcWork, objIndex uintp
if arena.pageMarks[pageIdx]&pageMask == 0 {
atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
}
+ }
- // If this is a noscan object, fast-track it to black
- // instead of greying it.
- if span.spanclass.noscan() {
- gcw.bytesMarked += uint64(span.elemsize)
- return
- }
+ // If this is a noscan object, fast-track it to black
+ // instead of greying it.
+ if span.spanclass.noscan() {
+ gcw.bytesMarked += uint64(span.elemsize)
+ return
}
// We're adding obj to P's local workbuf, so it's likely