github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/iface_test.go (about) 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 type T8 uint8 33 type T16 uint16 34 type T32 uint32 35 type T64 uint64 36 type Tstr string 37 type Tslice []byte 38 39 func (T8) Method1() {} 40 func (T16) Method1() {} 41 func (T32) Method1() {} 42 func (T64) Method1() {} 43 func (Tstr) Method1() {} 44 func (Tslice) Method1() {} 45 46 var ( 47 e any 48 e_ any 49 i1 I1 50 i2 I2 51 ts TS 52 tm TM 53 tl TL 54 ok bool 55 ) 56 57 // Issue 9370 58 func TestCmpIfaceConcreteAlloc(t *testing.T) { 59 if runtime.Compiler != "gc" { 60 t.Skip("skipping on non-gc compiler") 61 } 62 63 n := testing.AllocsPerRun(1, func() { 64 _ = e == ts 65 _ = i1 == ts 66 _ = e == 1 67 }) 68 69 if n > 0 { 70 t.Fatalf("iface cmp allocs=%v; want 0", n) 71 } 72 } 73 74 func BenchmarkEqEfaceConcrete(b *testing.B) { 75 for i := 0; i < b.N; i++ { 76 _ = e == ts 77 } 78 } 79 80 func BenchmarkEqIfaceConcrete(b *testing.B) { 81 for i := 0; i < b.N; i++ { 82 _ = i1 == ts 83 } 84 } 85 86 func BenchmarkNeEfaceConcrete(b *testing.B) { 87 for i := 0; i < b.N; i++ { 88 _ = e != ts 89 } 90 } 91 92 func BenchmarkNeIfaceConcrete(b *testing.B) { 93 for i := 0; i < b.N; i++ { 94 _ = i1 != ts 95 } 96 } 97 98 func BenchmarkConvT2EByteSized(b *testing.B) { 99 b.Run("bool", func(b *testing.B) { 100 for i := 0; i < b.N; i++ { 101 e = yes 102 } 103 }) 104 b.Run("uint8", func(b *testing.B) { 105 for i := 0; i < b.N; i++ { 106 e = eight8 107 } 108 }) 109 } 110 111 func BenchmarkConvT2ESmall(b *testing.B) { 112 for i := 0; i < b.N; i++ { 113 e = ts 114 } 115 } 116 117 func BenchmarkConvT2EUintptr(b *testing.B) { 118 for i := 0; i < b.N; i++ { 119 e = tm 120 } 121 } 122 123 func BenchmarkConvT2ELarge(b *testing.B) { 124 for i := 0; i < b.N; i++ { 125 e = tl 126 } 127 } 128 129 func BenchmarkConvT2ISmall(b *testing.B) { 130 for i := 0; i < b.N; i++ { 131 i1 = ts 132 } 133 } 134 135 func BenchmarkConvT2IUintptr(b *testing.B) { 136 for i := 0; i < b.N; i++ { 137 i1 = tm 138 } 139 } 140 141 func BenchmarkConvT2ILarge(b *testing.B) { 142 for i := 0; i < b.N; i++ { 143 i1 = tl 144 } 145 } 146 147 func BenchmarkConvI2E(b *testing.B) { 148 i2 = tm 149 for i := 0; i < b.N; i++ { 150 e = i2 151 } 152 } 153 154 func BenchmarkConvI2I(b *testing.B) { 155 i2 = tm 156 for i := 0; i < b.N; i++ { 157 i1 = i2 158 } 159 } 160 161 func BenchmarkAssertE2T(b *testing.B) { 162 e = tm 163 for i := 0; i < b.N; i++ { 164 tm = e.(TM) 165 } 166 } 167 168 func BenchmarkAssertE2TLarge(b *testing.B) { 169 e = tl 170 for i := 0; i < b.N; i++ { 171 tl = e.(TL) 172 } 173 } 174 175 func BenchmarkAssertE2I(b *testing.B) { 176 e = tm 177 for i := 0; i < b.N; i++ { 178 i1 = e.(I1) 179 } 180 } 181 182 func BenchmarkAssertI2T(b *testing.B) { 183 i1 = tm 184 for i := 0; i < b.N; i++ { 185 tm = i1.(TM) 186 } 187 } 188 189 func BenchmarkAssertI2I(b *testing.B) { 190 i1 = tm 191 for i := 0; i < b.N; i++ { 192 i2 = i1.(I2) 193 } 194 } 195 196 func BenchmarkAssertI2E(b *testing.B) { 197 i1 = tm 198 for i := 0; i < b.N; i++ { 199 e = i1.(any) 200 } 201 } 202 203 func BenchmarkAssertE2E(b *testing.B) { 204 e = tm 205 for i := 0; i < b.N; i++ { 206 e_ = e 207 } 208 } 209 210 func BenchmarkAssertE2T2(b *testing.B) { 211 e = tm 212 for i := 0; i < b.N; i++ { 213 tm, ok = e.(TM) 214 } 215 } 216 217 func BenchmarkAssertE2T2Blank(b *testing.B) { 218 e = tm 219 for i := 0; i < b.N; i++ { 220 _, ok = e.(TM) 221 } 222 } 223 224 func BenchmarkAssertI2E2(b *testing.B) { 225 i1 = tm 226 for i := 0; i < b.N; i++ { 227 e, ok = i1.(any) 228 } 229 } 230 231 func BenchmarkAssertI2E2Blank(b *testing.B) { 232 i1 = tm 233 for i := 0; i < b.N; i++ { 234 _, ok = i1.(any) 235 } 236 } 237 238 func BenchmarkAssertE2E2(b *testing.B) { 239 e = tm 240 for i := 0; i < b.N; i++ { 241 e_, ok = e.(any) 242 } 243 } 244 245 func BenchmarkAssertE2E2Blank(b *testing.B) { 246 e = tm 247 for i := 0; i < b.N; i++ { 248 _, ok = e.(any) 249 } 250 } 251 252 func TestNonEscapingConvT2E(t *testing.T) { 253 m := make(map[any]bool) 254 m[42] = true 255 if !m[42] { 256 t.Fatalf("42 is not present in the map") 257 } 258 if m[0] { 259 t.Fatalf("0 is present in the map") 260 } 261 262 n := testing.AllocsPerRun(1000, func() { 263 if m[0] { 264 t.Fatalf("0 is present in the map") 265 } 266 }) 267 if n != 0 { 268 t.Fatalf("want 0 allocs, got %v", n) 269 } 270 } 271 272 func TestNonEscapingConvT2I(t *testing.T) { 273 m := make(map[I1]bool) 274 m[TM(42)] = true 275 if !m[TM(42)] { 276 t.Fatalf("42 is not present in the map") 277 } 278 if m[TM(0)] { 279 t.Fatalf("0 is present in the map") 280 } 281 282 n := testing.AllocsPerRun(1000, func() { 283 if m[TM(0)] { 284 t.Fatalf("0 is present in the map") 285 } 286 }) 287 if n != 0 { 288 t.Fatalf("want 0 allocs, got %v", n) 289 } 290 } 291 292 func TestZeroConvT2x(t *testing.T) { 293 tests := []struct { 294 name string 295 fn func() 296 }{ 297 {name: "E8", fn: func() { e = eight8 }}, // any byte-sized value does not allocate 298 {name: "E16", fn: func() { e = zero16 }}, // zero values do not allocate 299 {name: "E32", fn: func() { e = zero32 }}, 300 {name: "E64", fn: func() { e = zero64 }}, 301 {name: "Estr", fn: func() { e = zerostr }}, 302 {name: "Eslice", fn: func() { e = zeroslice }}, 303 {name: "Econstflt", fn: func() { e = 99.0 }}, // constants do not allocate 304 {name: "Econststr", fn: func() { e = "change" }}, 305 {name: "I8", fn: func() { i1 = eight8I }}, 306 {name: "I16", fn: func() { i1 = zero16I }}, 307 {name: "I32", fn: func() { i1 = zero32I }}, 308 {name: "I64", fn: func() { i1 = zero64I }}, 309 {name: "Istr", fn: func() { i1 = zerostrI }}, 310 {name: "Islice", fn: func() { i1 = zerosliceI }}, 311 } 312 313 for _, test := range tests { 314 t.Run(test.name, func(t *testing.T) { 315 n := testing.AllocsPerRun(1000, test.fn) 316 if n != 0 { 317 t.Errorf("want zero allocs, got %v", n) 318 } 319 }) 320 } 321 } 322 323 var ( 324 eight8 uint8 = 8 325 eight8I T8 = 8 326 yes bool = true 327 328 zero16 uint16 = 0 329 zero16I T16 = 0 330 one16 uint16 = 1 331 thousand16 uint16 = 1000 332 333 zero32 uint32 = 0 334 zero32I T32 = 0 335 one32 uint32 = 1 336 thousand32 uint32 = 1000 337 338 zero64 uint64 = 0 339 zero64I T64 = 0 340 one64 uint64 = 1 341 thousand64 uint64 = 1000 342 343 zerostr string = "" 344 zerostrI Tstr = "" 345 nzstr string = "abc" 346 347 zeroslice []byte = nil 348 zerosliceI Tslice = nil 349 nzslice []byte = []byte("abc") 350 351 zerobig [512]byte 352 nzbig [512]byte = [512]byte{511: 1} 353 ) 354 355 func BenchmarkConvT2Ezero(b *testing.B) { 356 b.Run("zero", func(b *testing.B) { 357 b.Run("16", func(b *testing.B) { 358 for i := 0; i < b.N; i++ { 359 e = zero16 360 } 361 }) 362 b.Run("32", func(b *testing.B) { 363 for i := 0; i < b.N; i++ { 364 e = zero32 365 } 366 }) 367 b.Run("64", func(b *testing.B) { 368 for i := 0; i < b.N; i++ { 369 e = zero64 370 } 371 }) 372 b.Run("str", func(b *testing.B) { 373 for i := 0; i < b.N; i++ { 374 e = zerostr 375 } 376 }) 377 b.Run("slice", func(b *testing.B) { 378 for i := 0; i < b.N; i++ { 379 e = zeroslice 380 } 381 }) 382 b.Run("big", func(b *testing.B) { 383 for i := 0; i < b.N; i++ { 384 e = zerobig 385 } 386 }) 387 }) 388 b.Run("nonzero", func(b *testing.B) { 389 b.Run("str", func(b *testing.B) { 390 for i := 0; i < b.N; i++ { 391 e = nzstr 392 } 393 }) 394 b.Run("slice", func(b *testing.B) { 395 for i := 0; i < b.N; i++ { 396 e = nzslice 397 } 398 }) 399 b.Run("big", func(b *testing.B) { 400 for i := 0; i < b.N; i++ { 401 e = nzbig 402 } 403 }) 404 }) 405 b.Run("smallint", func(b *testing.B) { 406 b.Run("16", func(b *testing.B) { 407 for i := 0; i < b.N; i++ { 408 e = one16 409 } 410 }) 411 b.Run("32", func(b *testing.B) { 412 for i := 0; i < b.N; i++ { 413 e = one32 414 } 415 }) 416 b.Run("64", func(b *testing.B) { 417 for i := 0; i < b.N; i++ { 418 e = one64 419 } 420 }) 421 }) 422 b.Run("largeint", func(b *testing.B) { 423 b.Run("16", func(b *testing.B) { 424 for i := 0; i < b.N; i++ { 425 e = thousand16 426 } 427 }) 428 b.Run("32", func(b *testing.B) { 429 for i := 0; i < b.N; i++ { 430 e = thousand32 431 } 432 }) 433 b.Run("64", func(b *testing.B) { 434 for i := 0; i < b.N; i++ { 435 e = thousand64 436 } 437 }) 438 }) 439 }