mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
1318fb4a32
commit
e0ce0af6ef
4 changed files with 37 additions and 0 deletions
|
|
@ -228,6 +228,11 @@ func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
|
||||||
throw("defer on system stack")
|
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
|
// the arguments of fn are in a perilous state. The stack map
|
||||||
// for deferproc does not describe them. So we can't let garbage
|
// for deferproc does not describe them. So we can't let garbage
|
||||||
// collection or stack copying trigger until we've copied them out
|
// 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
|
// go code on the system stack can't defer
|
||||||
throw("defer on system stack")
|
throw("defer on system stack")
|
||||||
}
|
}
|
||||||
|
if experimentRegabiDefer && d.siz != 0 {
|
||||||
|
throw("defer with non-empty frame")
|
||||||
|
}
|
||||||
// siz and fn are already set.
|
// siz and fn are already set.
|
||||||
// The other fields are junk on entry to deferprocStack and
|
// The other fields are junk on entry to deferprocStack and
|
||||||
// are initialized here.
|
// are initialized here.
|
||||||
|
|
@ -824,6 +832,9 @@ func runOpenDeferFrame(gp *g, d *_defer) bool {
|
||||||
argWidth, fd = readvarintUnsafe(fd)
|
argWidth, fd = readvarintUnsafe(fd)
|
||||||
closureOffset, fd = readvarintUnsafe(fd)
|
closureOffset, fd = readvarintUnsafe(fd)
|
||||||
nArgs, fd = readvarintUnsafe(fd)
|
nArgs, fd = readvarintUnsafe(fd)
|
||||||
|
if experimentRegabiDefer && argWidth != 0 {
|
||||||
|
throw("defer with non-empty frame")
|
||||||
|
}
|
||||||
if deferBits&(1<<i) == 0 {
|
if deferBits&(1<<i) == 0 {
|
||||||
for j := uint32(0); j < nArgs; j++ {
|
for j := uint32(0); j < nArgs; j++ {
|
||||||
_, fd = readvarintUnsafe(fd)
|
_, fd = readvarintUnsafe(fd)
|
||||||
|
|
|
||||||
|
|
@ -4019,6 +4019,12 @@ func malg(stacksize int32) *g {
|
||||||
//
|
//
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
func newproc(siz int32, fn *funcval) {
|
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)
|
argp := add(unsafe.Pointer(&fn), sys.PtrSize)
|
||||||
gp := getg()
|
gp := getg()
|
||||||
pc := getcallerpc()
|
pc := getcallerpc()
|
||||||
|
|
|
||||||
10
src/runtime/regabidefer_off.go
Normal file
10
src/runtime/regabidefer_off.go
Normal file
|
|
@ -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
|
||||||
10
src/runtime/regabidefer_on.go
Normal file
10
src/runtime/regabidefer_on.go
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue