blob: a1abd9b1d122010ecd3d9d5a031abc15da72c3bf [file] [log] [blame]
Colin Crossd9c6b802019-03-19 21:10:31 -07001// run
2
3// Copyright 2018 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
7package main
8
9import (
10 "fmt"
11 "runtime"
12)
13
14// linked list up the stack, to test lots of stack objects.
15
16type T struct {
17 // points to a heap object. Test will make sure it isn't freed.
18 data *int64
19 // next pointer for a linked list of stack objects
20 next *T
21 // duplicate of next, to stress test the pointer buffers
22 // used during stack tracing.
23 next2 *T
24}
25
26func main() {
27 makelist(nil, 10000)
28}
29
30func makelist(x *T, n int64) {
31 if n%2 != 0 {
32 panic("must be multiple of 2")
33 }
34 if n == 0 {
35 runtime.GC()
36 i := int64(1)
37 for ; x != nil; x, i = x.next, i+1 {
38 // Make sure x.data hasn't been collected.
39 if got := *x.data; got != i {
40 panic(fmt.Sprintf("bad data want %d, got %d", i, got))
41 }
42 }
43 return
44 }
45 // Put 2 objects in each frame, to test intra-frame pointers.
46 // Use both orderings to ensure the linked list isn't always in address order.
47 var a, b T
48 if n%3 == 0 {
49 a.data = newInt(n)
50 a.next = x
51 a.next2 = x
52 b.data = newInt(n - 1)
53 b.next = &a
54 b.next2 = &a
55 x = &b
56 } else {
57 b.data = newInt(n)
58 b.next = x
59 b.next2 = x
60 a.data = newInt(n - 1)
61 a.next = &b
62 a.next2 = &b
63 x = &a
64 }
65
66 makelist(x, n-2)
67}
68
69// big enough and pointer-y enough to not be tinyalloc'd
70type NotTiny struct {
71 n int64
72 p *byte
73}
74
75// newInt allocates n on the heap and returns a pointer to it.
76func newInt(n int64) *int64 {
77 h := &NotTiny{n: n}
78 p := &h.n
79 escape = p
80 return p
81}
82
83var escape *int64