From 8f296f59de0703b0559474beb434a265e277bdca Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Sat, 8 Jun 2019 17:20:57 +0000 Subject: Revert "Revert "cmd/compile,runtime: allocate defer records on the stack"" This reverts CL 180761 Reason for revert: Reinstate the stack-allocated defer CL. There was nothing wrong with the CL proper, but stack allocation of defers exposed two other issues. Issue #32477: Fix has been submitted as CL 181258. Issue #32498: Possible fix is CL 181377 (not submitted yet). Change-Id: I32b3365d5026600069291b068bbba6cb15295eb3 Reviewed-on: https://go-review.googlesource.com/c/go/+/181378 Reviewed-by: Brad Fitzpatrick --- src/runtime/stack_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/runtime/stack_test.go') diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go index df73b3a1d5..143d3a99a0 100644 --- a/src/runtime/stack_test.go +++ b/src/runtime/stack_test.go @@ -799,3 +799,58 @@ func TestDeferLiveness(t *testing.T) { t.Errorf("output:\n%s\n\nwant no output", output) } } + +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{}) {} -- cgit v1.3