1
0
mirror of https://github.com/golang/go synced 2024-11-07 17:46:23 -07:00

reflect: use global variables for register count

This change switches reflect to use global variables for ABI-related
register counts instead of internal/abi constants. The advantage of
doing so is that we can make the internal/abi constants non-zero and
enable the runtime register argument spiller/unspiller even if they're
not used. It's basically turning two things we need to flip when we
switch to the register ABI into one.

It also paves the way for testing the reflect register ABI path
independently, because now we can switch the global variables at will
and run the register-assignment algorithm in tests without having the
rest of the runtime be broken.

Change-Id: Ie23629a37a5c80aeb24909d4bd9eacbd3f0c06d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/293149
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Michael Anthony Knyszek 2021-02-17 19:28:33 +00:00 committed by Michael Knyszek
parent 302a400316
commit c5a1c2276e
3 changed files with 30 additions and 13 deletions

View File

@ -10,16 +10,12 @@ package abi
const (
// See abi_generic.go.
// Currently these values are zero because whatever uses
// them will expect the register ABI, which isn't ready
// yet.
// RAX, RBX, RCX, RDI, RSI, R8, R9, R10, R11.
IntArgRegs = 0 // 9
IntArgRegs = 9
// X0 -> X14.
FloatArgRegs = 0 // 15
FloatArgRegs = 15
// We use SSE2 registers which support 64-bit float operations.
EffectiveFloatRegSize = 0 // 8
EffectiveFloatRegSize = 8
)

View File

@ -9,6 +9,30 @@ import (
"unsafe"
)
// These variables are used by the register assignment
// algorithm in this file.
//
// They should be modified with care (no other reflect code
// may be executing) and are generally only modified
// when testing this package.
//
// They should never be set higher than their internal/abi
// constant counterparts, because the system relies on a
// structure that is at least large enough to hold the
// registers the system supports.
//
// Currently they're set to zero because using the actual
// constants will break every part of the toolchain that
// uses reflect to call functions (e.g. go test, or anything
// that uses text/template). The values that are currently
// commented out there should be the actual values once
// we're ready to use the register ABI everywhere.
var (
intArgRegs = 0 // abi.IntArgRegs
floatArgRegs = 0 // abi.FloatArgRegs
floatRegSize = uintptr(0) // uintptr(abi.EffectiveFloatRegSize)
)
// abiStep represents an ABI "instruction." Each instruction
// describes one part of how to translate between a Go value
// in memory and a call frame.
@ -226,7 +250,7 @@ func (a *abiSeq) assignIntN(offset, size uintptr, n int, ptrMap uint8) bool {
if ptrMap != 0 && size != ptrSize {
panic("non-empty pointer map passed for non-pointer-size values")
}
if a.iregs+n > abi.IntArgRegs {
if a.iregs+n > intArgRegs {
return false
}
for i := 0; i < n; i++ {
@ -255,7 +279,7 @@ func (a *abiSeq) assignFloatN(offset, size uintptr, n int) bool {
if n < 0 {
panic("invalid n")
}
if a.fregs+n > abi.FloatArgRegs || abi.EffectiveFloatRegSize < size {
if a.fregs+n > floatArgRegs || floatRegSize < size {
return false
}
for i := 0; i < n; i++ {

View File

@ -442,10 +442,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
MOVL $0, DX
JMP runtime·morestack(SB)
// REFLECTCALL_USE_REGABI is not defined. It must be defined in conjunction with the
// register constants in the internal/abi package.
#ifdef REFLECTCALL_USE_REGABI
#ifdef GOEXPERIMENT_REGABI
// spillArgs stores return values from registers to a *internal/abi.RegArgs in R12.
TEXT spillArgs<>(SB),NOSPLIT,$0-0
MOVQ AX, 0(R12)