diff options
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r-- | src/runtime/panic.go | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go index 85d39b9250..35f3b44a4d 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -227,7 +227,7 @@ func panicmemAddr(addr uintptr) { // Create a new deferred function fn, which has no arguments and results. // The compiler turns a defer statement into a call to this. -func deferproc(fn *funcval) { // TODO: Make deferproc just take a func(). +func deferproc(fn func()) { gp := getg() if gp.m.curg != gp { // go code on the system stack can't defer @@ -303,16 +303,6 @@ func deferprocStack(d *_defer) { // been set and must not be clobbered. } -// deferFunc returns d's deferred function. This is temporary while we -// support both modes of GOEXPERIMENT=regabidefer. Once we commit to -// that experiment, we should change the type of d.fn. -//go:nosplit -func deferFunc(d *_defer) func() { - var fn func() - *(**funcval)(unsafe.Pointer(&fn)) = d.fn - return fn -} - // Each P holds a pool for defers. // Allocate a Defer, usually using per-P pool. @@ -470,9 +460,8 @@ func deferreturn() { // If the defer function pointer is nil, force the seg fault to happen // here rather than in jmpdefer. gentraceback() throws an error if it is // called with a callback on an LR architecture and jmpdefer is on the - // stack, because the stack trace can be incorrect in that case - see - // issue #8153). - _ = fn.fn + // stack, because jmpdefer manipulates SP (see issue #8153). + _ = **(**funcval)(unsafe.Pointer(&fn)) jmpdefer(fn, argp) } @@ -536,7 +525,7 @@ func Goexit() { } else { // Save the pc/sp in deferCallSave(), so we can "recover" back to this // loop if necessary. - deferCallSave(&p, deferFunc(d)) + deferCallSave(&p, d.fn) } if p.aborted { // We had a recursive panic in the defer d we started, and @@ -728,12 +717,14 @@ func runOpenDeferFrame(gp *g, d *_defer) bool { if deferBits&(1<<i) == 0 { continue } - closure := *(**funcval)(unsafe.Pointer(d.varp - uintptr(closureOffset))) + closure := *(*func())(unsafe.Pointer(d.varp - uintptr(closureOffset))) d.fn = closure deferBits = deferBits &^ (1 << i) *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits p := d._panic - deferCallSave(p, deferFunc(d)) + // Call the defer. Note that this can change d.varp if + // the stack moves. + deferCallSave(p, d.fn) if p != nil && p.aborted { break } @@ -854,8 +845,7 @@ func gopanic(e interface{}) { } } else { p.argp = unsafe.Pointer(getargp()) - fn := deferFunc(d) - fn() + d.fn() } p.argp = nil |