From 91c4f0ccd542a505f72ad0db952f55688851e49e Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 24 Jul 2025 16:41:23 -0700 Subject: [PATCH] reflect: avoid a bounds check in stack-constrained code Since CL 682496 we need more stack space to handle bounds checks. The code modified here normally has no bounds checks, but in -N builds it still does and thus uses too much stack. Use unsafe arithmetic to avoid the bounds check. This will hopefully fix some of the arm64 linux builders. Change-Id: I5b3096a14b4fb9553e635b7f340e60b8ffba8755 Reviewed-on: https://go-review.googlesource.com/c/go/+/690415 LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase Reviewed-by: Keith Randall --- src/reflect/makefunc.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go index 5da6cd2ec7..d35c92a14c 100644 --- a/src/reflect/makefunc.go +++ b/src/reflect/makefunc.go @@ -8,6 +8,7 @@ package reflect import ( "internal/abi" + "internal/goarch" "unsafe" ) @@ -164,13 +165,18 @@ func moveMakeFuncArgPtrs(ctxt *makeFuncCtxt, args *abi.RegArgs) { for i, arg := range args.Ints { // Avoid write barriers! Because our write barrier enqueues what // was there before, we might enqueue garbage. + // Also avoid bounds checks, we don't have the stack space for it. + // (Normally the prove pass removes them, but for -N builds we + // use too much stack.) + // ptr := &args.Ptrs[i] (but cast from *unsafe.Pointer to *uintptr) + ptr := (*uintptr)(add(unsafe.Pointer(unsafe.SliceData(args.Ptrs[:])), uintptr(i)*goarch.PtrSize, "always in [0:IntArgRegs]")) if ctxt.regPtrs.Get(i) { - *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = arg + *ptr = arg } else { // We *must* zero this space ourselves because it's defined in // assembly code and the GC will scan these pointers. Otherwise, // there will be garbage here. - *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = 0 + *ptr = 0 } } } -- 2.51.0