diff options
Diffstat (limited to 'test/stackobj2.go')
-rw-r--r-- | test/stackobj2.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test/stackobj2.go b/test/stackobj2.go new file mode 100644 index 0000000..a1abd9b --- /dev/null +++ b/test/stackobj2.go @@ -0,0 +1,83 @@ +// run + +// Copyright 2018 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 main + +import ( + "fmt" + "runtime" +) + +// linked list up the stack, to test lots of stack objects. + +type T struct { + // points to a heap object. Test will make sure it isn't freed. + data *int64 + // next pointer for a linked list of stack objects + next *T + // duplicate of next, to stress test the pointer buffers + // used during stack tracing. + next2 *T +} + +func main() { + makelist(nil, 10000) +} + +func makelist(x *T, n int64) { + if n%2 != 0 { + panic("must be multiple of 2") + } + if n == 0 { + runtime.GC() + i := int64(1) + for ; x != nil; x, i = x.next, i+1 { + // Make sure x.data hasn't been collected. + if got := *x.data; got != i { + panic(fmt.Sprintf("bad data want %d, got %d", i, got)) + } + } + return + } + // Put 2 objects in each frame, to test intra-frame pointers. + // Use both orderings to ensure the linked list isn't always in address order. + var a, b T + if n%3 == 0 { + a.data = newInt(n) + a.next = x + a.next2 = x + b.data = newInt(n - 1) + b.next = &a + b.next2 = &a + x = &b + } else { + b.data = newInt(n) + b.next = x + b.next2 = x + a.data = newInt(n - 1) + a.next = &b + a.next2 = &b + x = &a + } + + makelist(x, n-2) +} + +// big enough and pointer-y enough to not be tinyalloc'd +type NotTiny struct { + n int64 + p *byte +} + +// newInt allocates n on the heap and returns a pointer to it. +func newInt(n int64) *int64 { + h := &NotTiny{n: n} + p := &h.n + escape = p + return p +} + +var escape *int64 |