go/src/internal/abi/switch.go
Keith Randall cbcf8efa5f cmd/compile: use cache in front of type assert runtime call
That way we don't need to call into the runtime for every
type assertion (to an interface type).

name           old time/op  new time/op  delta
TypeAssert-24  3.78ns ± 3%  1.00ns ± 1%  -73.53%  (p=0.000 n=10+8)

Change-Id: I0ba308aaf0f24a5495b4e13c814d35af0c58bfde
Reviewed-on: https://go-review.googlesource.com/c/go/+/529316
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-10-06 17:02:53 +00:00

61 lines
1.6 KiB
Go

// 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
}