compiler: rationalize external symbol names
[official-gcc.git] / libgo / go / runtime / pprof / mprof_test.go
blob5d77a1d8986fe6d09cfcfb2e5d8d17494d02d605
1 // Copyright 2014 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 pprof
7 import (
8 "bytes"
9 "fmt"
10 "reflect"
11 "regexp"
12 "runtime"
13 "testing"
14 "unsafe"
17 var memSink interface{}
19 func allocateTransient1M() {
20 for i := 0; i < 1024; i++ {
21 memSink = &struct{ x [1024]byte }{}
25 //go:noinline
26 func allocateTransient2M() {
27 memSink = make([]byte, 2<<20)
30 type Obj32 struct {
31 link *Obj32
32 pad [32 - unsafe.Sizeof(uintptr(0))]byte
35 var persistentMemSink *Obj32
37 func allocatePersistent1K() {
38 for i := 0; i < 32; i++ {
39 // Can't use slice because that will introduce implicit allocations.
40 obj := &Obj32{link: persistentMemSink}
41 persistentMemSink = obj
45 // Allocate transient memory using reflect.Call.
47 func allocateReflectTransient() {
48 memSink = make([]byte, 2<<20)
51 func allocateReflect() {
52 rv := reflect.ValueOf(allocateReflectTransient)
53 rv.Call(nil)
56 var memoryProfilerRun = 0
58 func TestMemoryProfiler(t *testing.T) {
59 // Disable sampling, otherwise it's difficult to assert anything.
60 oldRate := runtime.MemProfileRate
61 runtime.MemProfileRate = 1
62 defer func() {
63 runtime.MemProfileRate = oldRate
64 }()
66 // Allocate a meg to ensure that mcache.next_sample is updated to 1.
67 for i := 0; i < 1024; i++ {
68 memSink = make([]byte, 1024)
71 // Do the interesting allocations.
72 allocateTransient1M()
73 allocateTransient2M()
74 allocatePersistent1K()
75 allocateReflect()
76 memSink = nil
78 runtime.GC() // materialize stats
79 var buf bytes.Buffer
80 if err := Lookup("heap").WriteTo(&buf, 1); err != nil {
81 t.Fatalf("failed to write heap profile: %v", err)
84 memoryProfilerRun++
86 tests := []string{
88 fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+
89 # 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:40
90 # 0x[0-9,a-f]+ runtime_pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:74
91 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
93 fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f x]+
94 # 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:21
95 # 0x[0-9,a-f]+ runtime_pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:72
96 `, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
98 // This should start with "0: 0" but gccgo's imprecise
99 // GC means that sometimes the value is not collected.
100 fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
101 # 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:27
102 # 0x[0-9,a-f]+ runtime_pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:73
103 `, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun),
105 // This should start with "0: 0" but gccgo's imprecise
106 // GC means that sometimes the value is not collected.
107 fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+
108 # 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:48
109 `, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun),
112 for _, test := range tests {
113 if !regexp.MustCompile(test).Match(buf.Bytes()) {
114 t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test, buf.String())