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>
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index c437553..f8f2f39 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -541,10 +541,8 @@
 // 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 {
@@ -570,13 +568,14 @@
 	// 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
@@ -588,7 +587,7 @@
 	// 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.
@@ -911,7 +910,7 @@
 		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())
 	}
@@ -937,7 +936,7 @@
 		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())
 	}
@@ -1034,7 +1033,7 @@
 				addOneOpenDeferFrame(gp, 0, nil)
 			}
 		} else {
-			p.argp = unsafe.Pointer(getargp(0))
+			p.argp = unsafe.Pointer(getargp())
 
 			if goexperiment.RegabiDefer {
 				fn := deferFunc(d)
@@ -1146,9 +1145,8 @@
 // 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.