aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-10-22 16:29:04 +0000
committerMichael Knyszek <mknyszek@google.com>2021-02-16 15:51:50 +0000
commite0215315f51c62f6d2c5ea5ed7008b7e7963dd5d (patch)
tree1ea397eaca06f15c08b4fd79a6a95af6f215ed26 /src/internal
parentb81efb7ec4348951211058cf4fdfc045c75255d6 (diff)
downloadgo-e0215315f51c62f6d2c5ea5ed7008b7e7963dd5d.tar.gz
go-e0215315f51c62f6d2c5ea5ed7008b7e7963dd5d.zip
[dev.regabi] reflect: support for register ABI on amd64 for reflect.(Value).Call
This change adds support for the new register ABI on amd64 to reflect.(Value).Call. If internal/abi's register counts are non-zero, reflect will try to set up arguments in registers on the Call path. Note that because the register ABI becomes ABI0 with zero registers available, this should keep working as it did before. This change does not add any tests for the register ABI case because there's no way to do so at the moment. For #40724. Change-Id: I8aa089a5aa5a31b72e56b3d9388dd3f82203985b Reviewed-on: https://go-review.googlesource.com/c/go/+/272568 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> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/abi/abi.go45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/internal/abi/abi.go b/src/internal/abi/abi.go
index 07ea51df8f..6700facc04 100644
--- a/src/internal/abi/abi.go
+++ b/src/internal/abi/abi.go
@@ -4,9 +4,50 @@
package abi
+import "unsafe"
+
// RegArgs is a struct that has space for each argument
// and return value register on the current architecture.
+//
+// Assembly code knows the layout of the first two fields
+// of RegArgs.
+//
+// RegArgs also contains additional space to hold pointers
+// when it may not be safe to keep them only in the integer
+// register space otherwise.
type RegArgs struct {
- Ints [IntArgRegs]uintptr
- Floats [FloatArgRegs]uint64
+ Ints [IntArgRegs]uintptr // untyped integer registers
+ Floats [FloatArgRegs]uint64 // untyped float registers
+
+ // Fields above this point are known to assembly.
+
+ // Ptrs is a space that duplicates Ints but with pointer type,
+ // used to make pointers passed or returned in registers
+ // visible to the GC by making the type unsafe.Pointer.
+ Ptrs [IntArgRegs]unsafe.Pointer
+
+ // ReturnIsPtr is a bitmap that indicates which registers
+ // contain or will contain pointers on the return path from
+ // a reflectcall. The i'th bit indicates whether the i'th
+ // register contains or will contain a valid Go pointer.
+ ReturnIsPtr IntArgRegBitmap
+}
+
+// IntArgRegBitmap is a bitmap large enough to hold one bit per
+// integer argument/return register.
+type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8
+
+// Set sets the i'th bit of the bitmap to 1.
+func (b *IntArgRegBitmap) Set(i int) {
+ b[i/8] |= uint8(1) << (i % 8)
+}
+
+// Get returns whether the i'th bit of the bitmap is set.
+//
+// nosplit because it's called in extremely sensitive contexts, like
+// on the reflectcall return path.
+//
+//go:nosplit
+func (b *IntArgRegBitmap) Get(i int) bool {
+ return b[i/8]&(uint8(1)<<(i%8)) != 0
}