mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
3636ced112
commit
91c4f0ccd5
1 changed files with 8 additions and 2 deletions
|
|
@ -8,6 +8,7 @@ package reflect
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"internal/abi"
|
"internal/abi"
|
||||||
|
"internal/goarch"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -164,13 +165,18 @@ func moveMakeFuncArgPtrs(ctxt *makeFuncCtxt, args *abi.RegArgs) {
|
||||||
for i, arg := range args.Ints {
|
for i, arg := range args.Ints {
|
||||||
// Avoid write barriers! Because our write barrier enqueues what
|
// Avoid write barriers! Because our write barrier enqueues what
|
||||||
// was there before, we might enqueue garbage.
|
// 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) {
|
if ctxt.regPtrs.Get(i) {
|
||||||
*(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = arg
|
*ptr = arg
|
||||||
} else {
|
} else {
|
||||||
// We *must* zero this space ourselves because it's defined in
|
// We *must* zero this space ourselves because it's defined in
|
||||||
// assembly code and the GC will scan these pointers. Otherwise,
|
// assembly code and the GC will scan these pointers. Otherwise,
|
||||||
// there will be garbage here.
|
// there will be garbage here.
|
||||||
*(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = 0
|
*ptr = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue