// we scan the stacks we can and ask running
// goroutines to scan themselves; and the
// second blocks.
- scang(gp)
+ scang(gp, gcw)
if selfScan {
casgstatus(userG, _Gwaiting, _Grunning)
//
//go:nowritebarrier
//go:systemstack
-func scanstack(gp *g) {
+func scanstack(gp *g, gcw *gcWork) {
if gp.gcscanvalid {
return
}
// Scan the stack.
var cache pcvalueCache
- gcw := &getg().m.p.ptr().gcw
n := 0
scanframe := func(frame *stkframe, unused unsafe.Pointer) bool {
scanframeworker(frame, &cache, gcw)
}
gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, scanframe, nil, 0)
tracebackdefers(gp, scanframe, nil)
- if gcphase == _GCmarktermination {
- gcw.dispose()
- }
gcUnlockStackBarriers(gp)
if gcphase == _GCmark {
// gp may have added itself to the rescan list between
// scang blocks until gp's stack has been scanned.
// It might be scanned by scang or it might be scanned by the goroutine itself.
// Either way, the stack scan has completed when scang returns.
-func scang(gp *g) {
+func scang(gp *g, gcw *gcWork) {
// Invariant; we (the caller, markroot for a specific goroutine) own gp.gcscandone.
// Nothing is racing with us now, but gcscandone might be set to true left over
// from an earlier round of stack scanning (we scan twice per GC).
// the goroutine until we're done.
if castogscanstatus(gp, s, s|_Gscan) {
if !gp.gcscandone {
- scanstack(gp)
+ scanstack(gp, gcw)
gp.gcscandone = true
}
restartg(gp)