aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2021-03-30 14:45:00 -0400
committerAustin Clements <austin@google.com>2021-03-30 21:20:51 +0000
commite0ce0af6ef5232352852fa027fe51fa3fd01198e (patch)
tree13c52cb0f5d8469cf4744e94e15888e9c46ffe75 /src/runtime
parent1318fb4a32371311688c6b868c3041f0501b6aeb (diff)
downloadgo-e0ce0af6ef5232352852fa027fe51fa3fd01198e.tar.xz
runtime: check that defer/go frames are empty
With GOEXPERIMENT=regabidefer, these frames should always be empty. Check that. For #40724. Change-Id: Id8e418a9e06b4f94543cb16b868a7e10e013c2d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/306009 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/panic.go11
-rw-r--r--src/runtime/proc.go6
-rw-r--r--src/runtime/regabidefer_off.go10
-rw-r--r--src/runtime/regabidefer_on.go10
4 files changed, 37 insertions, 0 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index b5133fa5b4..c265a5af79 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -228,6 +228,11 @@ func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
throw("defer on system stack")
}
+ if experimentRegabiDefer && siz != 0 {
+ // TODO: Make deferproc just take a func().
+ throw("defer with non-empty frame")
+ }
+
// the arguments of fn are in a perilous state. The stack map
// for deferproc does not describe them. So we can't let garbage
// collection or stack copying trigger until we've copied them out
@@ -280,6 +285,9 @@ func deferprocStack(d *_defer) {
// go code on the system stack can't defer
throw("defer on system stack")
}
+ if experimentRegabiDefer && d.siz != 0 {
+ throw("defer with non-empty frame")
+ }
// siz and fn are already set.
// The other fields are junk on entry to deferprocStack and
// are initialized here.
@@ -824,6 +832,9 @@ func runOpenDeferFrame(gp *g, d *_defer) bool {
argWidth, fd = readvarintUnsafe(fd)
closureOffset, fd = readvarintUnsafe(fd)
nArgs, fd = readvarintUnsafe(fd)
+ if experimentRegabiDefer && argWidth != 0 {
+ throw("defer with non-empty frame")
+ }
if deferBits&(1<<i) == 0 {
for j := uint32(0); j < nArgs; j++ {
_, fd = readvarintUnsafe(fd)
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index c2edb40948..d868c596bf 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -4019,6 +4019,12 @@ func malg(stacksize int32) *g {
//
//go:nosplit
func newproc(siz int32, fn *funcval) {
+ if experimentRegabiDefer && siz != 0 {
+ // TODO: When we commit to experimentRegabiDefer,
+ // rewrite newproc's comment, since it will no longer
+ // have a funny stack layout or need to be nosplit.
+ throw("go with non-empty frame")
+ }
argp := add(unsafe.Pointer(&fn), sys.PtrSize)
gp := getg()
pc := getcallerpc()
diff --git a/src/runtime/regabidefer_off.go b/src/runtime/regabidefer_off.go
new file mode 100644
index 0000000000..72e3cf9c50
--- /dev/null
+++ b/src/runtime/regabidefer_off.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !goexperiment.regabidefer
+// +build !goexperiment.regabidefer
+
+package runtime
+
+const experimentRegabiDefer = false
diff --git a/src/runtime/regabidefer_on.go b/src/runtime/regabidefer_on.go
new file mode 100644
index 0000000000..281694b061
--- /dev/null
+++ b/src/runtime/regabidefer_on.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.regabidefer
+// +build goexperiment.regabidefer
+
+package runtime
+
+const experimentRegabiDefer = true