Keith Randall would like Michael Pratt to review this change.
runtime: add a test for issue 78081
Contrive to have a bunch of stack shrinking going on during
memclrNoHeapPointersPreemptible calls.
Fails at tip with this patch:
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -2184,6 +2184,7 @@ func reusableSize(size uintptr) bool {
// Use this with care; if the data being cleared is tagged to contain
// pointers, this allows the GC to run before it is all cleared.
func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
+ y := uintptr(x)
if getg().preempt {
// TODO: no need for this, except to test that
// the preemption point is ok for small zeroings.
@@ -2193,6 +2194,7 @@ func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
// may hold locks, e.g., profiling
goschedguarded()
}
+ x = unsafe.Pointer(y)
// got this from benchmarking. 128k is too small, 512k is too large.
const chunkBytes = 256 * 1024
for size > chunkBytes {
Update #78081
diff --git a/test/fixedbugs/issue78081.go b/test/fixedbugs/issue78081.go
new file mode 100644
index 0000000..cd8a97c
--- /dev/null
+++ b/test/fixedbugs/issue78081.go
@@ -0,0 +1,47 @@
+// run
+
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime"
+
+func main() {
+ runtime.GOMAXPROCS(2)
+ c := make(chan bool)
+ for i := 0; i < 16; i++ {
+ go func() {
+ var b []byte
+ for range 100000 {
+ f(&b)
+ }
+ c <- true
+ }()
+ }
+ for i := 0; i < 16; i++ {
+ <-c
+ }
+}
+
+var n int = 64 // constant, but the compiler doesn't know that
+
+//go:noinline
+func f(sink *[]byte) {
+ useStack(64) // Use 64KB of stack, so that shrinking might happen below.
+
+ x := make([]int, n, 128) // on stack
+ _ = append(x, make([]int, 128-n)...) // memclrNoHeapPointersPreemptible call is here
+
+ *sink = make([]byte, 1024) // make some garbage to cause GC
+}
+
+//go:noinline
+func useStack(depth int) {
+ var b [128]int
+ if depth == b[depth%len(b)] { // depth == 0
+ return
+ }
+ useStack(depth - 1)
+}
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +1 |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
runtime: add a test for issue 78081
Contrive to have a bunch of stack shrinking going on during
memclrNoHeapPointersPreemptible calls.
Fails at tip with this patch:
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -2184,6 +2184,7 @@ func reusableSize(size uintptr) bool {
// Use this with care; if the data being cleared is tagged to contain
// pointers, this allows the GC to run before it is all cleared.
func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
+ y := uintptr(x)
if getg().preempt {
// TODO: no need for this, except to test that
// the preemption point is ok for small zeroings.
@@ -2193,6 +2194,7 @@ func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
// may hold locks, e.g., profiling
goschedguarded()
}
+ x = unsafe.Pointer(y)
// got this from benchmarking. 128k is too small, 512k is too large.
const chunkBytes = 256 * 1024
for size > chunkBytes {
Update #78081
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |