diff options
| author | Alexander Musman <alexander.musman@gmail.com> | 2026-02-01 00:04:15 +0300 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2026-02-11 15:37:20 -0800 |
| commit | 683aa8893a5e2e99ef48fa4502b507a0fe92acc8 (patch) | |
| tree | fb3792dfc505616001328b7c943cefb9d81bd964 /src/runtime/mgcmark.go | |
| parent | 456d0fe4092cb794a02027e178486bc31f05a8e0 (diff) | |
| download | go-683aa8893a5e2e99ef48fa4502b507a0fe92acc8.tar.xz | |
runtime: conservatively scan extended register state
Conservatively scan the extended register state when GC scans
asynchronously preempted goroutines. This ensures that any pointers
that appear only in vector registers at preemption time are kept alive.
Using vector registers for small memory moves may load pointers into
these registers. If async preemption occurs mid-move, with no write
barrier (e.g., heap-to-stack copies) and the source register clobbered
or source memory modified by a racing goroutine, the pointer may exist
only in the vector register. Without scanning this state, GC could miss
live pointers.
This addresses concerns raised in CL 738261 and enables safe use of
vector registers for operations that may involve pointers.
Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41
Reviewed-on: https://go-review.googlesource.com/c/go/+/740681
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgcmark.go')
| -rw-r--r-- | src/runtime/mgcmark.go | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 714b9a51df..f58b98bd7f 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -967,6 +967,11 @@ func scanstack(gp *g, gcw *gcWork) int64 { scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), goarch.PtrSize, &oneptrmask[0], gcw, &state) } + // Scan conservatively the extended register state. + if gp.asyncSafePoint { + xRegScan(gp, gcw, &state) + } + // Scan the stack. Accumulate a list of stack objects. var u unwinder for u.init(gp, 0); u.valid(); u.next() { |
