mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] Revert "[dev.typeparams] runtime,cmd/compile,cmd/link: replace jmpdefer with a loop"
This reverts CL 227652. I'm reverting CL 337651 and this builds on top of it. Change-Id: I03ce363be44c2a3defff2e43e7b1aad83386820d Reviewed-on: https://go-review.googlesource.com/c/go/+/338709 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
40e561d933
commit
e3e9f0bb2d
31 changed files with 324 additions and 39 deletions
|
|
@ -396,39 +396,47 @@ func freedeferfn() {
|
|||
throw("freedefer with d.fn != nil")
|
||||
}
|
||||
|
||||
// deferreturn runs deferred functions for the caller's frame.
|
||||
// Run a deferred function if there is one.
|
||||
// The compiler inserts a call to this at the end of any
|
||||
// function which calls defer.
|
||||
// If there is a deferred function, this will call runtime·jmpdefer,
|
||||
// which will jump to the deferred function such that it appears
|
||||
// to have been called by the caller of deferreturn at the point
|
||||
// just before deferreturn was called. The effect is that deferreturn
|
||||
// is called again and again until there are no more deferred functions.
|
||||
func deferreturn() {
|
||||
gp := getg()
|
||||
for {
|
||||
d := gp._defer
|
||||
if d == nil {
|
||||
return
|
||||
d := gp._defer
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
sp := getcallersp()
|
||||
if d.sp != sp {
|
||||
return
|
||||
}
|
||||
if d.openDefer {
|
||||
done := runOpenDeferFrame(gp, d)
|
||||
if !done {
|
||||
throw("unfinished open-coded defers in deferreturn")
|
||||
}
|
||||
sp := getcallersp()
|
||||
if d.sp != sp {
|
||||
return
|
||||
}
|
||||
if d.openDefer {
|
||||
done := runOpenDeferFrame(gp, d)
|
||||
if !done {
|
||||
throw("unfinished open-coded defers in deferreturn")
|
||||
}
|
||||
gp._defer = d.link
|
||||
freedefer(d)
|
||||
// If this frame uses open defers, then this
|
||||
// must be the only defer record for the
|
||||
// frame, so we can just return.
|
||||
return
|
||||
}
|
||||
|
||||
fn := d.fn
|
||||
d.fn = nil
|
||||
gp._defer = d.link
|
||||
freedefer(d)
|
||||
fn()
|
||||
return
|
||||
}
|
||||
|
||||
fn := d.fn
|
||||
d.fn = nil
|
||||
gp._defer = d.link
|
||||
freedefer(d)
|
||||
// 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 jmpdefer manipulates SP (see issue #8153).
|
||||
_ = **(**funcval)(unsafe.Pointer(&fn))
|
||||
// We must not split the stack between computing argp and
|
||||
// calling jmpdefer because argp is a uintptr stack pointer.
|
||||
argp := getcallersp() + sys.MinFrameSize
|
||||
jmpdefer(fn, argp)
|
||||
}
|
||||
|
||||
// Goexit terminates the goroutine that calls it. No other goroutine is affected.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue