Source file test/stackobj2.go

     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  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"runtime"
    12  )
    13  
    14  // linked list up the stack, to test lots of stack objects.
    15  
    16  type 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  
    26  func main() {
    27  	makelist(nil, 10000)
    28  }
    29  
    30  func 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
    70  type NotTiny struct {
    71  	n int64
    72  	p *byte
    73  }
    74  
    75  // newInt allocates n on the heap and returns a pointer to it.
    76  func newInt(n int64) *int64 {
    77  	h := &NotTiny{n: n}
    78  	p := &h.n
    79  	escape = p
    80  	return p
    81  }
    82  
    83  var escape *int64
    84  

View as plain text