1// 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 84