Skip to content

Commit

Permalink
runtime: simplify stkframe.argMapInternal
Browse files Browse the repository at this point in the history
Use an early return to reduce indentation and clarify flow.

For #54466.

Change-Id: I12ce810bea0f22b8707a175dc5ba66241c0a9a21
Reviewed-on: https://go-review.googlesource.com/c/go/+/425936
Run-TryBot: Austin Clements <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
Auto-Submit: Austin Clements <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
aclements authored and gopherbot committed Sep 2, 2022
1 parent 35026f3 commit 55ca6a2
Showing 1 changed file with 50 additions and 49 deletions.
99 changes: 50 additions & 49 deletions src/runtime/stkframe.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,58 +93,59 @@ func (frame *stkframe) argBytes() uintptr {
// function stack object, which the caller must synthesize.
func (frame *stkframe) argMapInternal() (argMap bitvector, hasReflectStackObj bool) {
f := frame.fn
argMap.n = f.args / goarch.PtrSize
if f.args == _ArgsSizeUnknown {
// Extract argument bitmaps for reflect stubs from the calls they made to reflect.
switch funcname(f) {
case "reflect.makeFuncStub", "reflect.methodValueCall":
// These take a *reflect.methodValue as their
// context register and immediately save it to 0(SP).
// Get the methodValue from 0(SP).
arg0 := frame.sp + sys.MinFrameSize
if f.args != _ArgsSizeUnknown {
argMap.n = f.args / goarch.PtrSize
return
}
// Extract argument bitmaps for reflect stubs from the calls they made to reflect.
switch funcname(f) {
case "reflect.makeFuncStub", "reflect.methodValueCall":
// These take a *reflect.methodValue as their
// context register and immediately save it to 0(SP).
// Get the methodValue from 0(SP).
arg0 := frame.sp + sys.MinFrameSize

minSP := frame.fp
if !usesLR {
// The CALL itself pushes a word.
// Undo that adjustment.
minSP -= goarch.PtrSize
}
if arg0 >= minSP {
// The function hasn't started yet.
// This only happens if f was the
// start function of a new goroutine
// that hasn't run yet *and* f takes
// no arguments and has no results
// (otherwise it will get wrapped in a
// closure). In this case, we can't
// reach into its locals because it
// doesn't have locals yet, but we
// also know its argument map is
// empty.
if frame.pc != f.entry() {
print("runtime: confused by ", funcname(f), ": no frame (sp=", hex(frame.sp), " fp=", hex(frame.fp), ") at entry+", hex(frame.pc-f.entry()), "\n")
throw("reflect mismatch")
}
return bitvector{}, false // No locals, so also no stack objects
}
hasReflectStackObj = true
mv := *(**reflectMethodValue)(unsafe.Pointer(arg0))
// Figure out whether the return values are valid.
// Reflect will update this value after it copies
// in the return values.
retValid := *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
if mv.fn != f.entry() {
print("runtime: confused by ", funcname(f), "\n")
minSP := frame.fp
if !usesLR {
// The CALL itself pushes a word.
// Undo that adjustment.
minSP -= goarch.PtrSize
}
if arg0 >= minSP {
// The function hasn't started yet.
// This only happens if f was the
// start function of a new goroutine
// that hasn't run yet *and* f takes
// no arguments and has no results
// (otherwise it will get wrapped in a
// closure). In this case, we can't
// reach into its locals because it
// doesn't have locals yet, but we
// also know its argument map is
// empty.
if frame.pc != f.entry() {
print("runtime: confused by ", funcname(f), ": no frame (sp=", hex(frame.sp), " fp=", hex(frame.fp), ") at entry+", hex(frame.pc-f.entry()), "\n")
throw("reflect mismatch")
}
argMap = *mv.stack
if !retValid {
// argMap.n includes the results, but
// those aren't valid, so drop them.
n := int32((uintptr(mv.argLen) &^ (goarch.PtrSize - 1)) / goarch.PtrSize)
if n < argMap.n {
argMap.n = n
}
return bitvector{}, false // No locals, so also no stack objects
}
hasReflectStackObj = true
mv := *(**reflectMethodValue)(unsafe.Pointer(arg0))
// Figure out whether the return values are valid.
// Reflect will update this value after it copies
// in the return values.
retValid := *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
if mv.fn != f.entry() {
print("runtime: confused by ", funcname(f), "\n")
throw("reflect mismatch")
}
argMap = *mv.stack
if !retValid {
// argMap.n includes the results, but
// those aren't valid, so drop them.
n := int32((uintptr(mv.argLen) &^ (goarch.PtrSize - 1)) / goarch.PtrSize)
if n < argMap.n {
argMap.n = n
}
}
}
Expand Down

0 comments on commit 55ca6a2

Please sign in to comment.