| // Copyright 2023 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package abi |
| |
| type InterfaceSwitch struct { |
| Cache *InterfaceSwitchCache |
| NCases int |
| |
| // Array of NCases elements. |
| // Each case must be a non-empty interface type. |
| Cases [1]*InterfaceType |
| } |
| |
| type InterfaceSwitchCache struct { |
| Mask uintptr // mask for index. Must be a power of 2 minus 1 |
| Entries [1]InterfaceSwitchCacheEntry // Mask+1 entries total |
| } |
| |
| type InterfaceSwitchCacheEntry struct { |
| // type of source value (a *Type) |
| Typ uintptr |
| // case # to dispatch to |
| Case int |
| // itab to use for resulting case variable (a *runtime.itab) |
| Itab uintptr |
| } |
| |
| const go122InterfaceSwitchCache = true |
| |
| func UseInterfaceSwitchCache(goarch string) bool { |
| if !go122InterfaceSwitchCache { |
| return false |
| } |
| // We need an atomic load instruction to make the cache multithreaded-safe. |
| // (AtomicLoadPtr needs to be implemented in cmd/compile/internal/ssa/_gen/ARCH.rules.) |
| switch goarch { |
| case "amd64", "arm64", "loong64", "mips", "mipsle", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x": |
| return true |
| default: |
| return false |
| } |
| } |
| |
| type TypeAssert struct { |
| Cache *TypeAssertCache |
| Inter *InterfaceType |
| CanFail bool |
| } |
| type TypeAssertCache struct { |
| Mask uintptr |
| Entries [1]TypeAssertCacheEntry |
| } |
| type TypeAssertCacheEntry struct { |
| // type of source value (a *runtime._type) |
| Typ uintptr |
| // itab to use for result (a *runtime.itab) |
| // nil if CanFail is set and conversion would fail. |
| Itab uintptr |
| } |