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. 4 5 package runtime_test 6 7 import ( 8 "runtime" 9 "testing" 10 ) 11 12 type I1 interface { 13 Method1() 14 } 15 16 type I2 interface { 17 Method1() 18 Method2() 19 } 20 21 type TS uint16 22 type TM uintptr 23 type TL [2]uintptr 24 25 func (TS) Method1() {} 26 func (TS) Method2() {} 27 func (TM) Method1() {} 28 func (TM) Method2() {} 29 func (TL) Method1() {} 30 func (TL) Method2() {} 31 32 var ( 33 e interface{} 34 e_ interface{} 35 i1 I1 36 i2 I2 37 ts TS 38 tm TM 39 tl TL 40 ok bool 41 ) 42 43 // Issue 9370 44 func TestCmpIfaceConcreteAlloc(t *testing.T) { 45 if runtime.Compiler != "gc" { 46 t.Skip("skipping on non-gc compiler") 47 } 48 49 n := testing.AllocsPerRun(1, func() { 50 _ = e == ts 51 _ = i1 == ts 52 _ = e == 1 53 }) 54 55 if n > 0 { 56 t.Fatalf("iface cmp allocs=%v; want 0", n) 57 } 58 } 59 60 func BenchmarkEqEfaceConcrete(b *testing.B) { 61 for i := 0; i < b.N; i++ { 62 _ = e == ts 63 } 64 } 65 66 func BenchmarkEqIfaceConcrete(b *testing.B) { 67 for i := 0; i < b.N; i++ { 68 _ = i1 == ts 69 } 70 } 71 72 func BenchmarkNeEfaceConcrete(b *testing.B) { 73 for i := 0; i < b.N; i++ { 74 _ = e != ts 75 } 76 } 77 78 func BenchmarkNeIfaceConcrete(b *testing.B) { 79 for i := 0; i < b.N; i++ { 80 _ = i1 != ts 81 } 82 } 83 84 func BenchmarkConvT2ESmall(b *testing.B) { 85 for i := 0; i < b.N; i++ { 86 e = ts 87 } 88 } 89 90 func BenchmarkConvT2EUintptr(b *testing.B) { 91 for i := 0; i < b.N; i++ { 92 e = tm 93 } 94 } 95 96 func BenchmarkConvT2ELarge(b *testing.B) { 97 for i := 0; i < b.N; i++ { 98 e = tl 99 } 100 } 101 102 func BenchmarkConvT2ISmall(b *testing.B) { 103 for i := 0; i < b.N; i++ { 104 i1 = ts 105 } 106 } 107 108 func BenchmarkConvT2IUintptr(b *testing.B) { 109 for i := 0; i < b.N; i++ { 110 i1 = tm 111 } 112 } 113 114 func BenchmarkConvT2ILarge(b *testing.B) { 115 for i := 0; i < b.N; i++ { 116 i1 = tl 117 } 118 } 119 120 func BenchmarkConvI2E(b *testing.B) { 121 i2 = tm 122 for i := 0; i < b.N; i++ { 123 e = i2 124 } 125 } 126 127 func BenchmarkConvI2I(b *testing.B) { 128 i2 = tm 129 for i := 0; i < b.N; i++ { 130 i1 = i2 131 } 132 } 133 134 func BenchmarkAssertE2T(b *testing.B) { 135 e = tm 136 for i := 0; i < b.N; i++ { 137 tm = e.(TM) 138 } 139 } 140 141 func BenchmarkAssertE2TLarge(b *testing.B) { 142 e = tl 143 for i := 0; i < b.N; i++ { 144 tl = e.(TL) 145 } 146 } 147 148 func BenchmarkAssertE2I(b *testing.B) { 149 e = tm 150 for i := 0; i < b.N; i++ { 151 i1 = e.(I1) 152 } 153 } 154 155 func BenchmarkAssertI2T(b *testing.B) { 156 i1 = tm 157 for i := 0; i < b.N; i++ { 158 tm = i1.(TM) 159 } 160 } 161 162 func BenchmarkAssertI2I(b *testing.B) { 163 i1 = tm 164 for i := 0; i < b.N; i++ { 165 i2 = i1.(I2) 166 } 167 } 168 169 func BenchmarkAssertI2E(b *testing.B) { 170 i1 = tm 171 for i := 0; i < b.N; i++ { 172 e = i1.(interface{}) 173 } 174 } 175 176 func BenchmarkAssertE2E(b *testing.B) { 177 e = tm 178 for i := 0; i < b.N; i++ { 179 e_ = e 180 } 181 } 182 183 func BenchmarkAssertE2T2(b *testing.B) { 184 e = tm 185 for i := 0; i < b.N; i++ { 186 tm, ok = e.(TM) 187 } 188 } 189 190 func BenchmarkAssertE2T2Blank(b *testing.B) { 191 e = tm 192 for i := 0; i < b.N; i++ { 193 _, ok = e.(TM) 194 } 195 } 196 197 func BenchmarkAssertI2E2(b *testing.B) { 198 i1 = tm 199 for i := 0; i < b.N; i++ { 200 e, ok = i1.(interface{}) 201 } 202 } 203 204 func BenchmarkAssertI2E2Blank(b *testing.B) { 205 i1 = tm 206 for i := 0; i < b.N; i++ { 207 _, ok = i1.(interface{}) 208 } 209 } 210 211 func BenchmarkAssertE2E2(b *testing.B) { 212 e = tm 213 for i := 0; i < b.N; i++ { 214 e_, ok = e.(interface{}) 215 } 216 } 217 218 func BenchmarkAssertE2E2Blank(b *testing.B) { 219 e = tm 220 for i := 0; i < b.N; i++ { 221 _, ok = e.(interface{}) 222 } 223 } 224 225 func TestNonEscapingConvT2E(t *testing.T) { 226 m := make(map[interface{}]bool) 227 m[42] = true 228 if !m[42] { 229 t.Fatalf("42 is not present in the map") 230 } 231 if m[0] { 232 t.Fatalf("0 is present in the map") 233 } 234 235 n := testing.AllocsPerRun(1000, func() { 236 if m[0] { 237 t.Fatalf("0 is present in the map") 238 } 239 }) 240 if n != 0 { 241 t.Fatalf("want 0 allocs, got %v", n) 242 } 243 } 244 245 func TestNonEscapingConvT2I(t *testing.T) { 246 m := make(map[I1]bool) 247 m[TM(42)] = true 248 if !m[TM(42)] { 249 t.Fatalf("42 is not present in the map") 250 } 251 if m[TM(0)] { 252 t.Fatalf("0 is present in the map") 253 } 254 255 n := testing.AllocsPerRun(1000, func() { 256 if m[TM(0)] { 257 t.Fatalf("0 is present in the map") 258 } 259 }) 260 if n != 0 { 261 t.Fatalf("want 0 allocs, got %v", n) 262 } 263 } 264