if d._panic != nil {
freedeferpanic()
}
+ if d.fn != nil {
+ freedeferfn()
+ }
sc := deferclass(uintptr(d.siz))
if sc < uintptr(len(p{}.deferpool)) {
mp := acquirem()
gothrow("freedefer with d._panic != nil")
}
+func freedeferfn() {
+ // fn must be cleared before d is unlinked from gp.
+ gothrow("freedefer with d.fn != nil")
+}
+
// Run a deferred function if there is one.
// The compiler inserts a call to this at the end of any
// function which calls defer.
mp := acquirem()
memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
fn := d.fn
+ d.fn = nil
gp._defer = d.link
freedefer(d)
releasem(mp)
d._panic.aborted = true
d._panic = nil
}
+ d.fn = nil
gp._defer = d.link
freedefer(d)
continue
gothrow("bad defer entry in Goexit")
}
d._panic = nil
+ d.fn = nil
gp._defer = d.link
freedefer(d)
// Note: we ignore recovers here because Goexit isn't a panic
d._panic.aborted = true
}
d._panic = nil
+ d.fn = nil
gp._defer = d.link
freedefer(d)
continue
gothrow("bad defer entry in panic")
}
d._panic = nil
+ d.fn = nil
gp._defer = d.link
// trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic