Currently, shrinkstack will free the stack if the goroutine is dead.
There are only two places that call shrinkstack: scanstack, which will
never call it if the goroutine is dead; and markrootFreeGStacks, which
only calls it on dead goroutines.
Clean this up by separating stack freeing out of shrinkstack.
Change-Id: I7d7891e620550c32a2220833923a025704986681
Reviewed-on: https://go-review.googlesource.com/c/go/+/170890
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
// Free stacks.
q := gQueue{list.head, list.head}
for gp := list.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
- shrinkstack(gp)
+ stackfree(gp.stack)
+ gp.stack.lo = 0
+ gp.stack.hi = 0
// Manipulate the queue directly since the Gs are
// already all linked the right way.
q.tail.set(gp)
// gp must be stopped, but the world need not be.
func shrinkstack(gp *g) {
gstatus := readgstatus(gp)
- if gstatus&^_Gscan == _Gdead {
- if gp.stack.lo != 0 {
- // Free whole stack - it will get reallocated
- // if G is used again.
- stackfree(gp.stack)
- gp.stack.lo = 0
- gp.stack.hi = 0
- }
- return
- }
if gp.stack.lo == 0 {
throw("missing stack in shrinkstack")
}