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