[go] runtime: conservatively scan the extended register state on ARM64

4 views
Skip to first unread message

Alexander Musman (Gerrit)

unread,
Jan 31, 2026, 4:49:20 PM (6 days ago) Jan 31
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Alexander Musman has uploaded the change for review

Commit message

runtime: conservatively scan the extended register state on ARM64

Conservatively scan the extended register state on ARM64
when GC scans asynchronously preempted goroutines.
This ensures that any pointers that appear only
in vector registers at preemption time are kept alive.

The extended register state saved during async preemption is currently
assumed to contain only scalar data. However, as suggested in CL 738261,
using ARM64 vector registers (NEON) for small memory moves may cause
pointers to be loaded into these registers.

This can be extended to other architectures to allow using vector
registers for operations that may involve pointers.
Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41

Change diff

diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 714b9a5..3f7579d 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -967,6 +967,11 @@
scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
}

+ // Scan conservatively the extended register state for the archs where it may contain pointers.
+ if GOARCH == "arm64" && 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() {
diff --git a/src/runtime/preempt_noxreg.go b/src/runtime/preempt_noxreg.go
index 977bf0b..ee6f879 100644
--- a/src/runtime/preempt_noxreg.go
+++ b/src/runtime/preempt_noxreg.go
@@ -25,3 +25,5 @@
func xRegRestore(gp *g) {}

func (*xRegPerP) free() {}
+
+func xRegScan(gp *g, gcw *gcWork, state *stackScanState) {}
diff --git a/src/runtime/preempt_xreg.go b/src/runtime/preempt_xreg.go
index cc52c5f..c9eda53 100644
--- a/src/runtime/preempt_xreg.go
+++ b/src/runtime/preempt_xreg.go
@@ -10,8 +10,9 @@
// While asynchronous preemption stores general-purpose (GP) registers on the
// preempted goroutine's own stack, extended register state can be used to save
// non-GP state off the stack. In particular, this is meant for large vector
-// register files. Currently, we assume this contains only scalar data, though
-// we could change this constraint by conservatively scanning this memory.
+// register files. Currently, we assume this contains only scalar data,
+// except for arm64 which conservatively scans this memory to enable small size
+// memoves using non-GP registers.
//
// For an architecture to support extended register state, it must provide a Go
// definition of an xRegState type for storing the state, and its asyncPreempt
@@ -20,6 +21,7 @@
package runtime

import (
+ "internal/abi"
"internal/runtime/sys"
"unsafe"
)
@@ -135,3 +137,33 @@
unlock(&xRegAlloc.lock)
}
}
+
+// xRegScan conservatively scans the extended register state.
+//
+// This is supposed to be called only by scanstack when it handles async preemption.
+func xRegScan(gp *g, gcw *gcWork, state *stackScanState) {
+ // The scan is only needed for the archs where pointers may appear in the extended register state.
+ if GOARCH != "arm64" {
+ return
+ }
+ // Regular async preemption always provides the extended register state.
+ if gp.xRegs.state == nil {
+ var u unwinder
+ for u.init(gp, 0); u.valid(); u.next() {
+ if u.frame.fn.valid() && u.frame.fn.funcID == abi.FuncID_debugCallV2 {
+ return
+ }
+ }
+ println("runtime: gp=", gp, ", goid=", gp.goid)
+ throw("gp.xRegs.state == nil on a scanstack attempt during async preemption")
+ }
+ b := uintptr(unsafe.Pointer(&gp.xRegs.state.regs))
+ n := uintptr(unsafe.Sizeof(gp.xRegs.state.regs))
+ if debugScanConservative {
+ print("begin scan xRegs of goroutine ", gp.goid, " at [", hex(b), ",", hex(b+n), ")\n")
+ }
+ scanConservative(b, n, nil, gcw, state)
+ if debugScanConservative {
+ print("end scan xRegs of goroutine ", gp.goid, "\n")
+ }
+}

Change information

Files:
  • M src/runtime/mgcmark.go
  • M src/runtime/preempt_noxreg.go
  • M src/runtime/preempt_xreg.go
Change size: S
Delta: 3 files changed, 41 insertions(+), 2 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41
Gerrit-Change-Number: 740681
Gerrit-PatchSet: 1
Gerrit-Owner: Alexander Musman <alexande...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alexander Musman (Gerrit)

unread,
Feb 5, 2026, 1:49:00 PM (2 days ago) Feb 5
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Austin Clements, Dmitry Vyukov and Michael Knyszek

Alexander Musman uploaded new patchset

Alexander Musman uploaded patch set #2 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
  • Dmitry Vyukov
  • Michael Knyszek
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41
Gerrit-Change-Number: 740681
Gerrit-PatchSet: 2
Gerrit-Owner: Alexander Musman <alexande...@gmail.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Reviewer: Dmitry Vyukov <dvy...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
Gerrit-CC: Gopher Robot <go...@golang.org>
Gerrit-Attention: Dmitry Vyukov <dvy...@google.com>
Gerrit-Attention: Austin Clements <aus...@google.com>
Gerrit-Attention: Michael Knyszek <mkny...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alexander Musman (Gerrit)

unread,
Feb 5, 2026, 2:09:25 PM (2 days ago) Feb 5
to goph...@pubsubhelper.golang.org, Keith Randall, Austin Clements, Dmitry Vyukov, Michael Knyszek, Gopher Robot, golang-co...@googlegroups.com
Attention needed from Austin Clements, Dmitry Vyukov, Keith Randall and Michael Knyszek

Alexander Musman added 1 comment

Patchset-level comments
File-level comment, Patchset 2 (Latest):
Alexander Musman . resolved

This CL is part of a chain with CL 738261, which adds SIMD-based
small memory moves on ARM64. Keith Randall requested conservative
scanning of saved SIMD state to ensure pointers in vector registers
aren't missed during GC of async-preempted goroutines. See discussion
in CL 738261.

Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
  • Dmitry Vyukov
  • Keith Randall
  • Michael Knyszek
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41
Gerrit-Change-Number: 740681
Gerrit-PatchSet: 2
Gerrit-Owner: Alexander Musman <alexande...@gmail.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Reviewer: Dmitry Vyukov <dvy...@google.com>
Gerrit-Reviewer: Keith Randall <k...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
Gerrit-CC: Gopher Robot <go...@golang.org>
Gerrit-Attention: Dmitry Vyukov <dvy...@google.com>
Gerrit-Attention: Keith Randall <k...@google.com>
Gerrit-Attention: Austin Clements <aus...@google.com>
Gerrit-Attention: Michael Knyszek <mkny...@google.com>
Gerrit-Comment-Date: Thu, 05 Feb 2026 19:09:18 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
satisfied_requirement
open
diffy

Keith Randall (Gerrit)

unread,
Feb 6, 2026, 8:10:44 PM (8 hours ago) Feb 6
to Alexander Musman, goph...@pubsubhelper.golang.org, Keith Randall, Keith Randall, Austin Clements, Dmitry Vyukov, Michael Knyszek, Gopher Robot, golang-co...@googlegroups.com
Attention needed from Alexander Musman, Austin Clements, Dmitry Vyukov, Keith Randall and Michael Knyszek

Keith Randall voted

Code-Review+2
Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Alexander Musman
  • Austin Clements
  • Dmitry Vyukov
  • Keith Randall
  • Michael Knyszek
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I5f5ce98d6ed6f7cde34b33da0aea1f880c2fcf41
    Gerrit-Change-Number: 740681
    Gerrit-PatchSet: 2
    Gerrit-Owner: Alexander Musman <alexande...@gmail.com>
    Gerrit-Reviewer: Austin Clements <aus...@google.com>
    Gerrit-Reviewer: Dmitry Vyukov <dvy...@google.com>
    Gerrit-Reviewer: Keith Randall <k...@golang.org>
    Gerrit-Reviewer: Keith Randall <k...@google.com>
    Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Dmitry Vyukov <dvy...@google.com>
    Gerrit-Attention: Alexander Musman <alexande...@gmail.com>
    Gerrit-Attention: Keith Randall <k...@google.com>
    Gerrit-Attention: Austin Clements <aus...@google.com>
    Gerrit-Attention: Michael Knyszek <mkny...@google.com>
    Gerrit-Comment-Date: Sat, 07 Feb 2026 01:10:40 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Keith Randall (Gerrit)

    unread,
    Feb 6, 2026, 8:11:10 PM (8 hours ago) Feb 6
    to Alexander Musman, goph...@pubsubhelper.golang.org, Go LUCI, Keith Randall, Austin Clements, Dmitry Vyukov, Michael Knyszek, Gopher Robot, golang-co...@googlegroups.com
    Attention needed from Alexander Musman, Austin Clements, Dmitry Vyukov, Keith Randall and Michael Knyszek

    Keith Randall voted Code-Review+1

    Code-Review+1
    Gerrit-Reviewer: Keith Randall <k...@golang.org>
    Gerrit-Reviewer: Keith Randall <k...@google.com>
    Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Keith Randall <k...@golang.org>
    Gerrit-Attention: Dmitry Vyukov <dvy...@google.com>
    Gerrit-Attention: Alexander Musman <alexande...@gmail.com>
    Gerrit-Attention: Austin Clements <aus...@google.com>
    Gerrit-Attention: Michael Knyszek <mkny...@google.com>
    Gerrit-Comment-Date: Sat, 07 Feb 2026 01:11:05 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages