
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
62 lines
1.1 KiB
Go
62 lines
1.1 KiB
Go
// 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{}) {}
|