From c1b6e392f56a35d4e59e1e938c68e4c5db4fd919 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 30 Oct 2015 12:47:24 +1300 Subject: [PATCH] cmd/internal/obj, cmd/link, runtime: increase stack limit to accommodate larger frames on ppc64x Larger stack frames mean nosplit functions use more stack and so the limit needs to increase. The change to test/nosplit.go is a bit ugly but I can't really think of a way to make it nicer. Change-Id: I2616b58015f0b62abbd62951575fcd0d2d8643c2 Reviewed-on: https://go-review.googlesource.com/16504 Reviewed-by: Russ Cox --- src/cmd/internal/obj/stack.go | 2 +- src/runtime/stack.go | 2 +- test/nosplit.go | 64 +++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/cmd/internal/obj/stack.go b/src/cmd/internal/obj/stack.go index 87698b3eeb..242e7b51c4 100644 --- a/src/cmd/internal/obj/stack.go +++ b/src/cmd/internal/obj/stack.go @@ -41,7 +41,7 @@ const ( STACKSYSTEM = 0 StackSystem = STACKSYSTEM StackBig = 4096 - StackGuard = 640*stackGuardMultiplier + StackSystem + StackGuard = 720*stackGuardMultiplier + StackSystem StackSmall = 128 StackLimit = StackGuard - StackSystem - StackSmall ) diff --git a/src/runtime/stack.go b/src/runtime/stack.go index db25636885..00cd6aeb1d 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -90,7 +90,7 @@ const ( // The stack guard is a pointer this many bytes above the // bottom of the stack. - _StackGuard = 640*sys.StackGuardMultiplier + _StackSystem + _StackGuard = 720*sys.StackGuardMultiplier + _StackSystem // After a stack split check the SP is allowed to be this // many bytes below the stack guard. This saves an instruction diff --git a/test/nosplit.go b/test/nosplit.go index bc14854574..3c4ae1079d 100644 --- a/test/nosplit.go +++ b/test/nosplit.go @@ -115,10 +115,15 @@ main 132 main 136 # A nosplit leaf can use the whole 128-CallSize bytes available on entry. -main 112 nosplit -main 116 nosplit -main 120 nosplit -main 124 nosplit +# (CallSize is 32 on ppc64) +main 96 nosplit +main 100 nosplit; REJECT ppc64 ppc64le +main 104 nosplit; REJECT ppc64 ppc64le +main 108 nosplit; REJECT ppc64 ppc64le +main 112 nosplit; REJECT ppc64 ppc64le +main 116 nosplit; REJECT ppc64 ppc64le +main 120 nosplit; REJECT ppc64 ppc64le +main 124 nosplit; REJECT ppc64 ppc64le main 128 nosplit; REJECT main 132 nosplit; REJECT main 136 nosplit; REJECT @@ -126,11 +131,16 @@ main 136 nosplit; REJECT # Calling a nosplit function from a nosplit function requires # having room for the saved caller PC and the called frame. # Because ARM doesn't save LR in the leaf, it gets an extra 4 bytes. -# Because ppc64 doesn't save LR in the leaf, it gets an extra 8 bytes. -main 112 nosplit call f; f 0 nosplit -main 116 nosplit call f; f 0 nosplit -main 120 nosplit call f; f 0 nosplit; REJECT amd64 -main 124 nosplit call f; f 0 nosplit; REJECT amd64 386 +# Because arm64 doesn't save LR in the leaf, it gets an extra 8 bytes. +# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 fewer bytes than amd64. +main 96 nosplit call f; f 0 nosplit +main 100 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le +main 104 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le +main 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le +main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le +main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le +main 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 +main 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386 main 128 nosplit call f; f 0 nosplit; REJECT main 132 nosplit call f; f 0 nosplit; REJECT main 136 nosplit call f; f 0 nosplit; REJECT @@ -138,24 +148,28 @@ main 136 nosplit call f; f 0 nosplit; REJECT # Calling a splitting function from a nosplit function requires # having room for the saved caller PC of the call but also the # saved caller PC for the call to morestack. -# Again the ARM and ppc64 work in less space. -main 104 nosplit call f; f 0 call f -main 108 nosplit call f; f 0 call f -main 112 nosplit call f; f 0 call f; REJECT amd64 -main 116 nosplit call f; f 0 call f; REJECT amd64 -main 120 nosplit call f; f 0 call f; REJECT amd64 386 -main 124 nosplit call f; f 0 call f; REJECT amd64 386 +# RISC architectures differ in the same way as before. +main 96 nosplit call f; f 0 call f +main 100 nosplit call f; f 0 call f; REJECT ppc64 ppc64le +main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le +main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le +main 112 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 +main 116 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 +main 120 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386 +main 124 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386 main 128 nosplit call f; f 0 call f; REJECT main 132 nosplit call f; f 0 call f; REJECT main 136 nosplit call f; f 0 call f; REJECT # Indirect calls are assumed to be splitting functions. -main 104 nosplit callind -main 108 nosplit callind -main 112 nosplit callind; REJECT amd64 -main 116 nosplit callind; REJECT amd64 -main 120 nosplit callind; REJECT amd64 386 -main 124 nosplit callind; REJECT amd64 386 +main 96 nosplit callind +main 100 nosplit callind; REJECT ppc64 ppc64le +main 104 nosplit callind; REJECT ppc64 ppc64le +main 108 nosplit callind; REJECT ppc64 ppc64le +main 112 nosplit callind; REJECT ppc64 ppc64le amd64 +main 116 nosplit callind; REJECT ppc64 ppc64le amd64 +main 120 nosplit callind; REJECT ppc64 ppc64le amd64 386 +main 124 nosplit callind; REJECT ppc64 ppc64le amd64 386 main 128 nosplit callind; REJECT main 132 nosplit callind; REJECT main 136 nosplit callind; REJECT @@ -284,16 +298,16 @@ TestCases: name := m[1] size, _ := strconv.Atoi(m[2]) - // The limit was originally 128 but is now 512. + // The limit was originally 128 but is now 592. // Instead of rewriting the test cases above, adjust // the first stack frame to use up the extra bytes. if i == 0 { - size += 512 - 128 + size += 592 - 128 // Noopt builds have a larger stackguard. // See ../cmd/dist/buildruntime.go:stackGuardMultiplier for _, s := range strings.Split(os.Getenv("GO_GCFLAGS"), " ") { if s == "-N" { - size += 640 + size += 720 } } }