mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: avoid relying on the unwinder in deferreturn
This CL changes deferreturn so that it never needs to invoke the unwinder. Instead, in the unusual case that we recover into a frame with pending open-coded defers, we now save the extra state needed to find them in g.param. Change-Id: Ied35f6c1063fee5b6044cc37b2bccd3f90682fe6 Reviewed-on: https://go-review.googlesource.com/c/go/+/515856 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
2bf8b3985f
commit
9869699c44
2 changed files with 64 additions and 23 deletions
|
|
@ -433,7 +433,7 @@ type g struct {
|
|||
// param is a generic pointer parameter field used to pass
|
||||
// values in particular contexts where other storage for the
|
||||
// parameter would be difficult to find. It is currently used
|
||||
// in three ways:
|
||||
// in four ways:
|
||||
// 1. When a channel operation wakes up a blocked goroutine, it sets param to
|
||||
// point to the sudog of the completed blocking operation.
|
||||
// 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
|
||||
|
|
@ -441,6 +441,8 @@ type g struct {
|
|||
// stack may have moved in the meantime.
|
||||
// 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
|
||||
// closure in the runtime is forbidden.
|
||||
// 4. When a panic is recovered and control returns to the respective frame,
|
||||
// param may point to a savedOpenDeferState.
|
||||
param unsafe.Pointer
|
||||
atomicstatus atomic.Uint32
|
||||
stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
|
||||
|
|
@ -1041,6 +1043,15 @@ type _panic struct {
|
|||
deferreturn bool
|
||||
}
|
||||
|
||||
// savedOpenDeferState tracks the extra state from _panic that's
|
||||
// necessary for deferreturn to pick up where gopanic left off,
|
||||
// without needing to unwind the stack.
|
||||
type savedOpenDeferState struct {
|
||||
retpc uintptr
|
||||
deferBitsOffset uintptr
|
||||
slotsOffset uintptr
|
||||
}
|
||||
|
||||
// ancestorInfo records details of where a goroutine was started.
|
||||
type ancestorInfo struct {
|
||||
pcs []uintptr // pcs from the stack of this goroutine
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue