libgo, compiler: Upgrade libgo to Go 1.4, except for runtime.
[official-gcc.git] / libgo / go / runtime / runtime_test.go
blob8059d1ad9a15b1e07858cbe58d8689597968356d
1 // Copyright 2012 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 "io"
9 // "io/ioutil"
10 // "os"
11 // "os/exec"
12 . "runtime"
13 "runtime/debug"
14 // "strconv"
15 // "strings"
16 "testing"
17 "unsafe"
20 var errf error
22 func errfn() error {
23 return errf
26 func errfn1() error {
27 return io.EOF
30 func BenchmarkIfaceCmp100(b *testing.B) {
31 for i := 0; i < b.N; i++ {
32 for j := 0; j < 100; j++ {
33 if errfn() == io.EOF {
34 b.Fatal("bad comparison")
40 func BenchmarkIfaceCmpNil100(b *testing.B) {
41 for i := 0; i < b.N; i++ {
42 for j := 0; j < 100; j++ {
43 if errfn1() == nil {
44 b.Fatal("bad comparison")
50 func BenchmarkDefer(b *testing.B) {
51 for i := 0; i < b.N; i++ {
52 defer1()
56 func defer1() {
57 defer func(x, y, z int) {
58 if recover() != nil || x != 1 || y != 2 || z != 3 {
59 panic("bad recover")
61 }(1, 2, 3)
62 return
65 func BenchmarkDefer10(b *testing.B) {
66 for i := 0; i < b.N/10; i++ {
67 defer2()
71 func defer2() {
72 for i := 0; i < 10; i++ {
73 defer func(x, y, z int) {
74 if recover() != nil || x != 1 || y != 2 || z != 3 {
75 panic("bad recover")
77 }(1, 2, 3)
81 func BenchmarkDeferMany(b *testing.B) {
82 for i := 0; i < b.N; i++ {
83 defer func(x, y, z int) {
84 if recover() != nil || x != 1 || y != 2 || z != 3 {
85 panic("bad recover")
87 }(1, 2, 3)
91 /* The go tool is not present in gccgo.
93 // The profiling signal handler needs to know whether it is executing runtime.gogo.
94 // The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
95 // we don't have a way to obtain it from the linker (perhaps someday).
96 // Test that the constant matches the size determined by 'go tool nm -S'.
97 // The value reported will include the padding between runtime.gogo and the
98 // next function in memory. That's fine.
99 func TestRuntimeGogoBytes(t *testing.T) {
100 switch GOOS {
101 case "android", "nacl":
102 t.Skipf("skipping on %s", GOOS)
105 dir, err := ioutil.TempDir("", "go-build")
106 if err != nil {
107 t.Fatalf("failed to create temp directory: %v", err)
109 defer os.RemoveAll(dir)
111 out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
112 if err != nil {
113 t.Fatalf("building hello world: %v\n%s", err, out)
116 out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
117 if err != nil {
118 t.Fatalf("go tool nm: %v\n%s", err, out)
121 for _, line := range strings.Split(string(out), "\n") {
122 f := strings.Fields(line)
123 if len(f) == 4 && f[3] == "runtime.gogo" {
124 size, _ := strconv.Atoi(f[1])
125 if GogoBytes() != int32(size) {
126 t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
128 return
132 t.Fatalf("go tool nm did not report size for runtime.gogo")
136 // golang.org/issue/7063
137 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
138 SetCPUProfileRate(0)
141 // Addresses to test for faulting behavior.
142 // This is less a test of SetPanicOnFault and more a check that
143 // the operating system and the runtime can process these faults
144 // correctly. That is, we're indirectly testing that without SetPanicOnFault
145 // these would manage to turn into ordinary crashes.
146 // Note that these are truncated on 32-bit systems, so the bottom 32 bits
147 // of the larger addresses must themselves be invalid addresses.
148 // We might get unlucky and the OS might have mapped one of these
149 // addresses, but probably not: they're all in the first page, very high
150 // adderesses that normally an OS would reserve for itself, or malformed
151 // addresses. Even so, we might have to remove one or two on different
152 // systems. We will see.
154 var faultAddrs = []uint64{
155 // low addresses
158 0xfff,
159 // high (kernel) addresses
160 // or else malformed.
161 0xffffffffffffffff,
162 0xfffffffffffff001,
163 0xffffffffffff0001,
164 0xfffffffffff00001,
165 0xffffffffff000001,
166 0xfffffffff0000001,
167 0xffffffff00000001,
168 0xfffffff000000001,
169 0xffffff0000000001,
170 0xfffff00000000001,
171 0xffff000000000001,
172 0xfff0000000000001,
173 0xff00000000000001,
174 0xf000000000000001,
175 0x8000000000000001,
178 func TestSetPanicOnFault(t *testing.T) {
179 // This currently results in a fault in the signal trampoline on
180 // dragonfly/386 - see issue 7421.
181 if GOOS == "dragonfly" && GOARCH == "386" {
182 t.Skip("skipping test on dragonfly/386")
185 old := debug.SetPanicOnFault(true)
186 defer debug.SetPanicOnFault(old)
188 nfault := 0
189 for _, addr := range faultAddrs {
190 testSetPanicOnFault(t, uintptr(addr), &nfault)
192 if nfault == 0 {
193 t.Fatalf("none of the addresses faulted")
197 func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
198 if GOOS == "nacl" {
199 t.Skip("nacl doesn't seem to fault on high addresses")
202 defer func() {
203 if err := recover(); err != nil {
204 *nfault++
208 // The read should fault, except that sometimes we hit
209 // addresses that have had C or kernel pages mapped there
210 // readable by user code. So just log the content.
211 // If no addresses fault, we'll fail the test.
212 v := *(*byte)(unsafe.Pointer(addr))
213 t.Logf("addr %#x: %#x\n", addr, v)
216 func eqstring_generic(s1, s2 string) bool {
217 if len(s1) != len(s2) {
218 return false
220 // optimization in assembly versions:
221 // if s1.str == s2.str { return true }
222 for i := 0; i < len(s1); i++ {
223 if s1[i] != s2[i] {
224 return false
227 return true
230 func TestEqString(t *testing.T) {
231 // This isn't really an exhaustive test of eqstring, it's
232 // just a convenient way of documenting (via eqstring_generic)
233 // what eqstring does.
234 s := []string{
236 "a",
237 "c",
238 "aaa",
239 "ccc",
240 "cccc"[:3], // same contents, different string
241 "1234567890",
243 for _, s1 := range s {
244 for _, s2 := range s {
245 x := s1 == s2
246 y := eqstring_generic(s1, s2)
247 if x != y {
248 t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)