1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:24:47 -07:00

runtime: remove deferreturn dummy argument

deferreturn has a dummy argument, that is only used for getting
the caller's SP. When generating deferreturn calls, the compiler
does not pass an actual argument or reserve its stack space.
Also, the current code is written with the assumption about where
the argument's address is on the stack. Currently this is correct
for both ABI0 and the register ABI, but it may change in the
future (e.g. if we remove dedicated spill slots). Remove the
argument.

Also remove the argument for getargp.

Change-Id: I96d07efa79a9c1a53ef3fc5adbecc11877e99dc1
Reviewed-on: https://go-review.googlesource.com/c/go/+/309329
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-10 23:02:04 -04:00
parent 9ed0e32059
commit 585b52261c

View File

@ -541,10 +541,8 @@ func freedeferfn() {
// modifying the caller's frame in order to reuse the frame to call the deferred // modifying the caller's frame in order to reuse the frame to call the deferred
// function. // function.
// //
// The single argument isn't actually used - it just has its address
// taken so it can be matched against pending defers.
//go:nosplit //go:nosplit
func deferreturn(arg0 uintptr) { func deferreturn() {
gp := getg() gp := getg()
d := gp._defer d := gp._defer
if d == nil { if d == nil {
@ -570,13 +568,14 @@ func deferreturn(arg0 uintptr) {
// nosplit because the garbage collector won't know the form // nosplit because the garbage collector won't know the form
// of the arguments until the jmpdefer can flip the PC over to // of the arguments until the jmpdefer can flip the PC over to
// fn. // fn.
argp := getcallersp() + sys.MinFrameSize
switch d.siz { switch d.siz {
case 0: case 0:
// Do nothing. // Do nothing.
case sys.PtrSize: case sys.PtrSize:
*(*uintptr)(unsafe.Pointer(&arg0)) = *(*uintptr)(deferArgs(d)) *(*uintptr)(unsafe.Pointer(argp)) = *(*uintptr)(deferArgs(d))
default: default:
memmove(unsafe.Pointer(&arg0), deferArgs(d), uintptr(d.siz)) memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
} }
fn := d.fn fn := d.fn
d.fn = nil d.fn = nil
@ -588,7 +587,7 @@ func deferreturn(arg0 uintptr) {
// stack, because the stack trace can be incorrect in that case - see // stack, because the stack trace can be incorrect in that case - see
// issue #8153). // issue #8153).
_ = fn.fn _ = fn.fn
jmpdefer(fn, uintptr(unsafe.Pointer(&arg0))) jmpdefer(fn, argp)
} }
// Goexit terminates the goroutine that calls it. No other goroutine is affected. // Goexit terminates the goroutine that calls it. No other goroutine is affected.
@ -911,7 +910,7 @@ func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
throw("not allowed with GOEXPERIMENT=regabidefer") throw("not allowed with GOEXPERIMENT=regabidefer")
} }
if p != nil { if p != nil {
p.argp = unsafe.Pointer(getargp(0)) p.argp = unsafe.Pointer(getargp())
p.pc = getcallerpc() p.pc = getcallerpc()
p.sp = unsafe.Pointer(getcallersp()) p.sp = unsafe.Pointer(getcallersp())
} }
@ -937,7 +936,7 @@ func deferCallSave(p *_panic, fn func()) {
throw("only allowed with GOEXPERIMENT=regabidefer") throw("only allowed with GOEXPERIMENT=regabidefer")
} }
if p != nil { if p != nil {
p.argp = unsafe.Pointer(getargp(0)) p.argp = unsafe.Pointer(getargp())
p.pc = getcallerpc() p.pc = getcallerpc()
p.sp = unsafe.Pointer(getcallersp()) p.sp = unsafe.Pointer(getcallersp())
} }
@ -1034,7 +1033,7 @@ func gopanic(e interface{}) {
addOneOpenDeferFrame(gp, 0, nil) addOneOpenDeferFrame(gp, 0, nil)
} }
} else { } else {
p.argp = unsafe.Pointer(getargp(0)) p.argp = unsafe.Pointer(getargp())
if goexperiment.RegabiDefer { if goexperiment.RegabiDefer {
fn := deferFunc(d) fn := deferFunc(d)
@ -1146,9 +1145,8 @@ func gopanic(e interface{}) {
// writes outgoing function call arguments. // writes outgoing function call arguments.
//go:nosplit //go:nosplit
//go:noinline //go:noinline
func getargp(x int) uintptr { func getargp() uintptr {
// x is an argument mainly so that we can return its address. return getcallersp() + sys.MinFrameSize
return uintptr(noescape(unsafe.Pointer(&x)))
} }
// The implementation of the predeclared function recover. // The implementation of the predeclared function recover.