diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-08-17 23:43:08 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-08-17 23:43:08 +0000 |
commit | e68035acfd6997ed97eb32aec4f277f3b6858550 (patch) | |
tree | f0e21a4a0680568bf5045771a16e20292aad1cfc /libgo/go/runtime/stack_test.go | |
parent | b9a21efdea18862f79c68ceb2eee0704844ead53 (diff) | |
download | gcc-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.go | 62 |
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{}) {} |