mirror of
https://github.com/golang/go
synced 2024-11-12 00:20:22 -07:00
runtime: make gcTestMoveStackOnNextCall not double the stack
Currently, gcTestMoveStackOnNextCall doubles the stack allocation on each call because stack movement always doubles the stack. That's rather unfortunate if you're doing a bunch of stack movement tests in a row that don't actually have to grow the stack because you'll quickly hit the stack size limit even though you're hardly using any of the stack. Fix this by adding a special stack poison value for gcTestMoveStackOnNextCall that newstack recognizes and inhibits the allocation doubling. Change-Id: Iace7055a0f33cb48dc97b8f4b46e45304bee832c Reviewed-on: https://go-review.googlesource.com/c/go/+/306672 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
41e8a9f1cf
commit
97b3ce430b
@ -242,6 +242,23 @@ func moveStackCheck(t *testing.T, new *int, old uintptr) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGCTestMoveStackRepeatedly(t *testing.T) {
|
||||||
|
// Move the stack repeatedly to make sure we're not doubling
|
||||||
|
// it each time.
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
runtime.GCTestMoveStackOnNextCall()
|
||||||
|
moveStack1(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noinline
|
||||||
|
func moveStack1(x bool) {
|
||||||
|
// Make sure this function doesn't get auto-nosplit.
|
||||||
|
if x {
|
||||||
|
println("x")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGCTestIsReachable(t *testing.T) {
|
func TestGCTestIsReachable(t *testing.T) {
|
||||||
var all, half []unsafe.Pointer
|
var all, half []unsafe.Pointer
|
||||||
var want uint64
|
var want uint64
|
||||||
|
@ -2352,7 +2352,7 @@ func fmtNSAsMS(buf []byte, ns uint64) []byte {
|
|||||||
// there's a preemption between this call and the next.
|
// there's a preemption between this call and the next.
|
||||||
func gcTestMoveStackOnNextCall() {
|
func gcTestMoveStackOnNextCall() {
|
||||||
gp := getg()
|
gp := getg()
|
||||||
gp.stackguard0 = getcallersp()
|
gp.stackguard0 = stackForceMove
|
||||||
}
|
}
|
||||||
|
|
||||||
// gcTestIsReachable performs a GC and returns a bit set where bit i
|
// gcTestIsReachable performs a GC and returns a bit set where bit i
|
||||||
|
@ -132,6 +132,10 @@ const (
|
|||||||
// Stored into g->stackguard0 to cause split stack check failure.
|
// Stored into g->stackguard0 to cause split stack check failure.
|
||||||
// Must be greater than any real sp.
|
// Must be greater than any real sp.
|
||||||
stackFork = uintptrMask & -1234
|
stackFork = uintptrMask & -1234
|
||||||
|
|
||||||
|
// Force a stack movement. Used for debugging.
|
||||||
|
// 0xfffffeed in hex.
|
||||||
|
stackForceMove = uintptrMask & -275
|
||||||
)
|
)
|
||||||
|
|
||||||
// Global pool of spans that have free stacks.
|
// Global pool of spans that have free stacks.
|
||||||
@ -1054,11 +1058,18 @@ func newstack() {
|
|||||||
// recheck the bounds on return.)
|
// recheck the bounds on return.)
|
||||||
if f := findfunc(gp.sched.pc); f.valid() {
|
if f := findfunc(gp.sched.pc); f.valid() {
|
||||||
max := uintptr(funcMaxSPDelta(f))
|
max := uintptr(funcMaxSPDelta(f))
|
||||||
for newsize-oldsize < max+_StackGuard {
|
for newsize-gp.sched.sp < max+_StackGuard {
|
||||||
newsize *= 2
|
newsize *= 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if gp.stackguard0 == stackForceMove {
|
||||||
|
// Forced stack movement used for debugging.
|
||||||
|
// Don't double the stack (or we may quickly run out
|
||||||
|
// if this is done repeatedly).
|
||||||
|
newsize = oldsize
|
||||||
|
}
|
||||||
|
|
||||||
if newsize > maxstacksize || newsize > maxstackceiling {
|
if newsize > maxstacksize || newsize > maxstackceiling {
|
||||||
if maxstacksize < maxstackceiling {
|
if maxstacksize < maxstackceiling {
|
||||||
print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
|
print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
|
||||||
|
Loading…
Reference in New Issue
Block a user