mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: replace stkframe.arglen/argmap with methods
Currently, stkframe.arglen and stkframe.argmap are populated by gentraceback under a particular set of circumstances. But because they can be constructed from other fields in stkframe, they don't need to be computed eagerly at all. They're also rather misleading, as they're only part of computing the actual argument map and most callers should be using getStackMap, which does the rest of the work. This CL drops these fields from stkframe. It shifts the functions that used to compute them, getArgInfoFast and getArgInfo, into corresponding methods stkframe.argBytes and stkframe.argMapInternal. argBytes is expected to be used by callers that need to know only the argument frame size, while argMapInternal is used only by argBytes and getStackMap. We also move some of the logic from getStackMap into argMapInternal because the previous split of responsibilities didn't make much sense. This lets us return just a bitvector from argMapInternal, rather than both a bitvector, which carries a size, and an "actually use this size". The getArgInfoFast function was inlined before (and inl_test checked this). We drop that requirement from stkframe.argBytes because the uses of this have shifted and now it's only called from heap dumping (which never happens) and conservative stack frame scanning (which very, very rarely happens). There will be a few follow-up clean-up CLs. For #54466. This is a nice clean-up on its own, but it also serves to remove pointers from the traceback state that would eventually become troublesome write barriers once we stack-rip gentraceback. Change-Id: I107f98ed8e7b00185c081de425bbf24af02a4163 Reviewed-on: https://go-review.googlesource.com/c/go/+/424514 Run-TryBot: Austin Clements <austin@google.com> Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
511cd9b8af
commit
dbf442b1b2
6 changed files with 65 additions and 71 deletions
|
|
@ -1305,40 +1305,35 @@ func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, args
|
|||
}
|
||||
}
|
||||
|
||||
// Arguments.
|
||||
if frame.arglen > 0 {
|
||||
if frame.argmap != nil {
|
||||
// argmap is set when the function is reflect.makeFuncStub or reflect.methodValueCall.
|
||||
// In this case, arglen specifies how much of the args section is actually live.
|
||||
// (It could be either all the args + results, or just the args.)
|
||||
args = *frame.argmap
|
||||
n := int32(frame.arglen / goarch.PtrSize)
|
||||
if n < args.n {
|
||||
args.n = n // Don't use more of the arguments than arglen.
|
||||
}
|
||||
// Arguments. First fetch frame size and special-case argument maps.
|
||||
var isReflect bool
|
||||
args, isReflect = frame.argMapInternal()
|
||||
if args.n > 0 && args.bytedata == nil {
|
||||
// Non-empty argument frame, but not a special map.
|
||||
// Fetch the argument map at pcdata.
|
||||
stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
|
||||
if stackmap == nil || stackmap.n <= 0 {
|
||||
print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(args.n*goarch.PtrSize), "\n")
|
||||
throw("missing stackmap")
|
||||
}
|
||||
if pcdata < 0 || pcdata >= stackmap.n {
|
||||
// don't know where we are
|
||||
print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
|
||||
throw("bad symbol table")
|
||||
}
|
||||
if stackmap.nbit == 0 {
|
||||
args.n = 0
|
||||
} else {
|
||||
stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
|
||||
if stackmap == nil || stackmap.n <= 0 {
|
||||
print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(frame.arglen), "\n")
|
||||
throw("missing stackmap")
|
||||
}
|
||||
if pcdata < 0 || pcdata >= stackmap.n {
|
||||
// don't know where we are
|
||||
print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
|
||||
throw("bad symbol table")
|
||||
}
|
||||
if stackmap.nbit > 0 {
|
||||
args = stackmapdata(stackmap, pcdata)
|
||||
}
|
||||
args = stackmapdata(stackmap, pcdata)
|
||||
}
|
||||
}
|
||||
|
||||
// stack objects.
|
||||
if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") &&
|
||||
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.
|
||||
unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect {
|
||||
// For reflect.makeFuncStub and reflect.methodValueCall,
|
||||
// we need to fake the stack object record.
|
||||
// These frames contain an internal/abi.RegArgs at a hard-coded offset.
|
||||
// This offset matches the assembly code on amd64 and arm64.
|
||||
objs = methodValueCallFrameObjs[:]
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue