aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/stack_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-08-17 23:43:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-08-17 23:43:08 +0000
commite68035acfd6997ed97eb32aec4f277f3b6858550 (patch)
treef0e21a4a0680568bf5045771a16e20292aad1cfc /libgo/go/runtime/stack_test.go
parentb9a21efdea18862f79c68ceb2eee0704844ead53 (diff)
downloadgcc-e68035acfd6997ed97eb32aec4f277f3b6858550.zip
gcc-e68035acfd6997ed97eb32aec4f277f3b6858550.tar.gz
gcc-e68035acfd6997ed97eb32aec4f277f3b6858550.tar.bz2
compiler, runtime: allocate defer records on the stack
When a defer is executed at most once in a function body, we can allocate the defer record for it on the stack instead of on the heap. This should make defers like this (which are very common) faster. This is a port of CL 171758 from the gc repo. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/190410 From-SVN: r274613
Diffstat (limited to 'libgo/go/runtime/stack_test.go')
-rw-r--r--libgo/go/runtime/stack_test.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/libgo/go/runtime/stack_test.go b/libgo/go/runtime/stack_test.go
new file mode 100644
index 0000000..b696253
--- /dev/null
+++ b/libgo/go/runtime/stack_test.go
@@ -0,0 +1,62 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import "testing"
+
+func TestDeferHeapAndStack(t *testing.T) {
+ P := 4 // processors
+ N := 10000 // iterations
+ D := 200 // stack depth
+
+ if testing.Short() {
+ P /= 2
+ N /= 10
+ D /= 10
+ }
+ c := make(chan bool)
+ for p := 0; p < P; p++ {
+ go func() {
+ for i := 0; i < N; i++ {
+ if deferHeapAndStack(D) != 2*D {
+ panic("bad result")
+ }
+ }
+ c <- true
+ }()
+ }
+ for p := 0; p < P; p++ {
+ <-c
+ }
+}
+
+// deferHeapAndStack(n) computes 2*n
+func deferHeapAndStack(n int) (r int) {
+ if n == 0 {
+ return 0
+ }
+ if n%2 == 0 {
+ // heap-allocated defers
+ for i := 0; i < 2; i++ {
+ defer func() {
+ r++
+ }()
+ }
+ } else {
+ // stack-allocated defers
+ defer func() {
+ r++
+ }()
+ defer func() {
+ r++
+ }()
+ }
+ r = deferHeapAndStack(n - 1)
+ escapeMe(new([1024]byte)) // force some GCs
+ return
+}
+
+// Pass a value to escapeMe to force it to escape.
+var escapeMe = func(x interface{}) {}