aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/stack.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2021-01-28 15:23:05 +0000
committerMichael Knyszek <mknyszek@google.com>2021-04-02 16:53:18 +0000
commit28c5fed5576483cc696db233d7f6fffecd2833a2 (patch)
tree00109d3e508e63bbfff7c5c73f2b54ea321c402c /src/runtime/stack.go
parent6996bae5d1d34ea9e2ab6399f70adb402697ed94 (diff)
downloadgo-28c5fed5576483cc696db233d7f6fffecd2833a2.tar.xz
reflect: add register ABI support for makeFuncStub and methodValueCall
This change finishes off functionality register ABI for the reflect package. Specifically, it implements a call on a MakeFunc'd value by performing the reverse process that reflect.Value.Call does, using the same ABI steps. It implements a call on a method value created by reflect by translating between the method value's ABI to the method's ABI. Tests are added for both cases. For #40724. Change-Id: I302820b61fc0a8f94c5525a002bc02776aef41af Reviewed-on: https://go-review.googlesource.com/c/go/+/298670 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>
Diffstat (limited to 'src/runtime/stack.go')
-rw-r--r--src/runtime/stack.go42
1 files changed, 31 insertions, 11 deletions
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 5c7fadc2d2..cdccdcc2c5 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -5,6 +5,7 @@
package runtime
import (
+ "internal/abi"
"internal/cpu"
"runtime/internal/atomic"
"runtime/internal/sys"
@@ -1312,23 +1313,42 @@ func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, args
}
// stack objects.
- p := funcdata(f, _FUNCDATA_StackObjects)
- if p != nil {
- n := *(*uintptr)(p)
- p = add(p, sys.PtrSize)
- *(*slice)(unsafe.Pointer(&objs)) = slice{array: noescape(p), len: int(n), cap: int(n)}
- // Note: the noescape above is needed to keep
- // getStackMap from "leaking param content:
- // frame". That leak propagates up to getgcmask, then
- // GCMask, then verifyGCInfo, which converts the stack
- // gcinfo tests into heap gcinfo tests :(
+ if GOARCH == "amd64" && unsafe.Sizeof(abi.RegArgs{}) > 0 && frame.argmap != nil {
+ // argmap is set when the function is reflect.makeFuncStub or reflect.methodValueCall.
+ // We don't actually use argmap in this case, but we need to fake the stack object
+ // record for these frames which contain an internal/abi.RegArgs at a hard-coded offset
+ // on amd64.
+ objs = methodValueCallFrameObjs
+ } else {
+ p := funcdata(f, _FUNCDATA_StackObjects)
+ if p != nil {
+ n := *(*uintptr)(p)
+ p = add(p, sys.PtrSize)
+ *(*slice)(unsafe.Pointer(&objs)) = slice{array: noescape(p), len: int(n), cap: int(n)}
+ // Note: the noescape above is needed to keep
+ // getStackMap from "leaking param content:
+ // frame". That leak propagates up to getgcmask, then
+ // GCMask, then verifyGCInfo, which converts the stack
+ // gcinfo tests into heap gcinfo tests :(
+ }
}
return
}
+var (
+ abiRegArgsEface interface{} = abi.RegArgs{}
+ abiRegArgsType *_type = efaceOf(&abiRegArgsEface)._type
+ methodValueCallFrameObjs = []stackObjectRecord{
+ {
+ off: -int(alignUp(abiRegArgsType.size, 8)), // It's always the highest address local.
+ typ: abiRegArgsType,
+ },
+ }
+)
+
// A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
-// This record must match the generator code in cmd/compile/internal/gc/ssa.go:emitStackObjects.
+// This record must match the generator code in cmd/compile/internal/liveness/plive.go:emitStackObjects.
type stackObjectRecord struct {
// offset in frame
// if negative, offset from varp