1// Copyright 2023 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
5package abi
6
7type InterfaceSwitch struct {
8	Cache  *InterfaceSwitchCache
9	NCases int
10
11	// Array of NCases elements.
12	// Each case must be a non-empty interface type.
13	Cases [1]*InterfaceType
14}
15
16type InterfaceSwitchCache struct {
17	Mask    uintptr                      // mask for index. Must be a power of 2 minus 1
18	Entries [1]InterfaceSwitchCacheEntry // Mask+1 entries total
19}
20
21type InterfaceSwitchCacheEntry struct {
22	// type of source value (a *Type)
23	Typ uintptr
24	// case # to dispatch to
25	Case int
26	// itab to use for resulting case variable (a *runtime.itab)
27	Itab uintptr
28}
29
30const go122InterfaceSwitchCache = true
31
32func UseInterfaceSwitchCache(goarch string) bool {
33	if !go122InterfaceSwitchCache {
34		return false
35	}
36	// We need an atomic load instruction to make the cache multithreaded-safe.
37	// (AtomicLoadPtr needs to be implemented in cmd/compile/internal/ssa/_gen/ARCH.rules.)
38	switch goarch {
39	case "amd64", "arm64", "loong64", "mips", "mipsle", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x":
40		return true
41	default:
42		return false
43	}
44}
45
46type TypeAssert struct {
47	Cache   *TypeAssertCache
48	Inter   *InterfaceType
49	CanFail bool
50}
51type TypeAssertCache struct {
52	Mask    uintptr
53	Entries [1]TypeAssertCacheEntry
54}
55type TypeAssertCacheEntry struct {
56	// type of source value (a *runtime._type)
57	Typ uintptr
58	// itab to use for result (a *runtime.itab)
59	// nil if CanFail is set and conversion would fail.
60	Itab uintptr
61}
62