]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: avoid a bounds check in stack-constrained code
authorKeith Randall <khr@golang.org>
Thu, 24 Jul 2025 23:41:23 +0000 (16:41 -0700)
committerKeith Randall <khr@golang.org>
Fri, 25 Jul 2025 16:45:13 +0000 (09:45 -0700)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@google.com>
src/reflect/makefunc.go

index 5da6cd2ec7d4eaf1eedcce11f8851e14ce0f784e..d35c92a14c73176d0155b2c0debdb3c245ccf44a 100644 (file)
@@ -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
                }
        }
 }