Rebase.
[official-gcc.git] / libgo / go / runtime / gc_test.go
blob5a1e9b89c4294bb353f402f009c9028416087bfd
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package runtime_test
7 import (
8 // "os"
9 "runtime"
10 "runtime/debug"
11 "testing"
12 "time"
15 func TestGcSys(t *testing.T) {
16 /* gccgo does not have a go command
17 if os.Getenv("GOGC") == "off" {
18 t.Skip("skipping test; GOGC=off in environment")
20 data := struct{ Short bool }{testing.Short()}
21 got := executeTest(t, testGCSysSource, &data)
22 want := "OK\n"
23 if got != want {
24 t.Fatalf("expected %q, but got %q", want, got)
29 const testGCSysSource = `
30 package main
32 import (
33 "fmt"
34 "runtime"
37 func main() {
38 runtime.GOMAXPROCS(1)
39 memstats := new(runtime.MemStats)
40 runtime.GC()
41 runtime.ReadMemStats(memstats)
42 sys := memstats.Sys
44 runtime.MemProfileRate = 0 // disable profiler
46 itercount := 1000000
47 {{if .Short}}
48 itercount = 100000
49 {{end}}
50 for i := 0; i < itercount; i++ {
51 workthegc()
54 // Should only be using a few MB.
55 // We allocated 100 MB or (if not short) 1 GB.
56 runtime.ReadMemStats(memstats)
57 if sys > memstats.Sys {
58 sys = 0
59 } else {
60 sys = memstats.Sys - sys
62 if sys > 16<<20 {
63 fmt.Printf("using too much memory: %d bytes\n", sys)
64 return
66 fmt.Printf("OK\n")
69 func workthegc() []byte {
70 return make([]byte, 1029)
74 func TestGcDeepNesting(t *testing.T) {
75 type T [2][2][2][2][2][2][2][2][2][2]*int
76 a := new(T)
78 // Prevent the compiler from applying escape analysis.
79 // This makes sure new(T) is allocated on heap, not on the stack.
80 t.Logf("%p", a)
82 a[0][0][0][0][0][0][0][0][0][0] = new(int)
83 *a[0][0][0][0][0][0][0][0][0][0] = 13
84 runtime.GC()
85 if *a[0][0][0][0][0][0][0][0][0][0] != 13 {
86 t.Fail()
90 func TestGcHashmapIndirection(t *testing.T) {
91 defer debug.SetGCPercent(debug.SetGCPercent(1))
92 runtime.GC()
93 type T struct {
94 a [256]int
96 m := make(map[T]T)
97 for i := 0; i < 2000; i++ {
98 var a T
99 a.a[0] = i
100 m[a] = T{}
104 func TestGcArraySlice(t *testing.T) {
105 type X struct {
106 buf [1]byte
107 nextbuf []byte
108 next *X
110 var head *X
111 for i := 0; i < 10; i++ {
112 p := &X{}
113 p.buf[0] = 42
114 p.next = head
115 if head != nil {
116 p.nextbuf = head.buf[:]
118 head = p
119 runtime.GC()
121 for p := head; p != nil; p = p.next {
122 if p.buf[0] != 42 {
123 t.Fatal("corrupted heap")
128 func TestGcRescan(t *testing.T) {
129 type X struct {
130 c chan error
131 nextx *X
133 type Y struct {
135 nexty *Y
136 p *int
138 var head *Y
139 for i := 0; i < 10; i++ {
140 p := &Y{}
141 p.c = make(chan error)
142 if head != nil {
143 p.nextx = &head.X
145 p.nexty = head
146 p.p = new(int)
147 *p.p = 42
148 head = p
149 runtime.GC()
151 for p := head; p != nil; p = p.nexty {
152 if *p.p != 42 {
153 t.Fatal("corrupted heap")
158 func TestGcLastTime(t *testing.T) {
159 ms := new(runtime.MemStats)
160 t0 := time.Now().UnixNano()
161 runtime.GC()
162 t1 := time.Now().UnixNano()
163 runtime.ReadMemStats(ms)
164 last := int64(ms.LastGC)
165 if t0 > last || last > t1 {
166 t.Fatalf("bad last GC time: got %v, want [%v, %v]", last, t0, t1)
170 func BenchmarkSetTypeNoPtr1(b *testing.B) {
171 type NoPtr1 struct {
172 p uintptr
174 var p *NoPtr1
175 for i := 0; i < b.N; i++ {
176 p = &NoPtr1{}
178 _ = p
180 func BenchmarkSetTypeNoPtr2(b *testing.B) {
181 type NoPtr2 struct {
182 p, q uintptr
184 var p *NoPtr2
185 for i := 0; i < b.N; i++ {
186 p = &NoPtr2{}
188 _ = p
190 func BenchmarkSetTypePtr1(b *testing.B) {
191 type Ptr1 struct {
192 p *byte
194 var p *Ptr1
195 for i := 0; i < b.N; i++ {
196 p = &Ptr1{}
198 _ = p
200 func BenchmarkSetTypePtr2(b *testing.B) {
201 type Ptr2 struct {
202 p, q *byte
204 var p *Ptr2
205 for i := 0; i < b.N; i++ {
206 p = &Ptr2{}
208 _ = p
211 func BenchmarkAllocation(b *testing.B) {
212 type T struct {
213 x, y *byte
215 ngo := runtime.GOMAXPROCS(0)
216 work := make(chan bool, b.N+ngo)
217 result := make(chan *T)
218 for i := 0; i < b.N; i++ {
219 work <- true
221 for i := 0; i < ngo; i++ {
222 work <- false
224 for i := 0; i < ngo; i++ {
225 go func() {
226 var x *T
227 for <-work {
228 for i := 0; i < 1000; i++ {
229 x = &T{}
232 result <- x
235 for i := 0; i < ngo; i++ {
236 <-result