]> Cypherpunks.ru repositories - gostls13.git/blob - test/stack.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / stack.go
1 // run
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test stack splitting code.
8 // Try to tickle stack splitting bugs by doing
9 // go, defer, and closure calls at different stack depths.
10
11 package main
12
13 type T [20]int
14
15 func g(c chan int, t T) {
16         s := 0
17         for i := 0; i < len(t); i++ {
18                 s += t[i]
19         }
20         c <- s
21 }
22
23 func d(t T) {
24         s := 0
25         for i := 0; i < len(t); i++ {
26                 s += t[i]
27         }
28         if s != len(t) {
29                 println("bad defer", s)
30                 panic("fail")
31         }
32 }
33
34 func f0() {
35         // likely to make a new stack for f0,
36         // because the call to f1 puts 3000 bytes
37         // in our frame.
38         f1()
39 }
40
41 func f1() [3000]byte {
42         // likely to make a new stack for f1,
43         // because 3000 bytes were used by f0
44         // and we need 3000 more for the call
45         // to f2.  if the call to morestack in f1
46         // does not pass the frame size, the new
47         // stack (default size 5k) will not be big
48         // enough for the frame, and the morestack
49         // check in f2 will die, if we get that far 
50         // without faulting.
51         f2()
52         return [3000]byte{}
53 }
54
55 func f2() [3000]byte {
56         // just take up space
57         return [3000]byte{}
58 }
59
60 var c = make(chan int)
61 var t T
62 var b = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
63
64 func recur(n int) {
65         ss := string(b)
66         if len(ss) != len(b) {
67                 panic("bad []byte -> string")
68         }
69         go g(c, t)
70         f0()
71         s := <-c
72         if s != len(t) {
73                 println("bad go", s)
74                 panic("fail")
75         }
76         f := func(t T) int {
77                 s := 0
78                 for i := 0; i < len(t); i++ {
79                         s += t[i]
80                 }
81                 s += n
82                 return s
83         }
84         s = f(t)
85         if s != len(t)+n {
86                 println("bad func", s, "at level", n)
87                 panic("fail")
88         }
89         if n > 0 {
90                 recur(n - 1)
91         }
92         defer d(t)
93 }
94
95 func main() {
96         for i := 0; i < len(t); i++ {
97                 t[i] = 1
98         }
99         recur(8000)
100 }