mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Make SyscallTable.lookup be a fixed-size array rather than a slice.
Same for `SyscallFlagsTable.enable`. This avoids a few extra memory reads during syscall execution, at the expense of holding two slightly-larger-than-necessary-in-practice lookup arrays in memory. Syscall latency overhead should be improved very slightly. PiperOrigin-RevId: 419898650
This commit is contained in:
committed by
gVisor bot
parent
496ba59add
commit
d057161dc8
@@ -25,12 +25,14 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// maxSyscallNum is the highest supported syscall number.
|
||||
//
|
||||
// The types below create fast lookup slices for all syscalls. This maximum
|
||||
// serves as a sanity check that we don't allocate huge slices for a very large
|
||||
// syscall. This is checked during registration.
|
||||
const maxSyscallNum = 2000
|
||||
const (
|
||||
// maxSyscallNum is the highest supported syscall number.
|
||||
//
|
||||
// The types below create fast lookup slices for all syscalls. This maximum
|
||||
// serves as a sanity check that we don't allocate huge slices for a very large
|
||||
// syscall. This is checked during registration.
|
||||
maxSyscallNum = 2000
|
||||
)
|
||||
|
||||
// SyscallSupportLevel is a syscall support levels.
|
||||
type SyscallSupportLevel int
|
||||
@@ -119,7 +121,7 @@ type SyscallFlagsTable struct {
|
||||
//
|
||||
// missing syscalls have the same value in enable as missingEnable to
|
||||
// avoid an extra branch in Word.
|
||||
enable []uint32
|
||||
enable [maxSyscallNum + 1]uint32
|
||||
|
||||
// missingEnable contains the enable bits for missing syscalls.
|
||||
missingEnable uint32
|
||||
@@ -128,8 +130,7 @@ type SyscallFlagsTable struct {
|
||||
// Init initializes the struct, with all syscalls in table set to enable.
|
||||
//
|
||||
// max is the largest syscall number in table.
|
||||
func (e *SyscallFlagsTable) init(table map[uintptr]Syscall, max uintptr) {
|
||||
e.enable = make([]uint32, max+1)
|
||||
func (e *SyscallFlagsTable) init(table map[uintptr]Syscall) {
|
||||
for num := range table {
|
||||
e.enable[num] = syscallPresent
|
||||
}
|
||||
@@ -137,7 +138,7 @@ func (e *SyscallFlagsTable) init(table map[uintptr]Syscall, max uintptr) {
|
||||
|
||||
// Word returns the enable bitfield for sysno.
|
||||
func (e *SyscallFlagsTable) Word(sysno uintptr) uint32 {
|
||||
if sysno < uintptr(len(e.enable)) {
|
||||
if sysno <= maxSyscallNum {
|
||||
return atomic.LoadUint32(&e.enable[sysno])
|
||||
}
|
||||
|
||||
@@ -239,7 +240,7 @@ type SyscallTable struct {
|
||||
|
||||
// lookup is a fixed-size array that holds the syscalls (indexed by
|
||||
// their numbers). It is used for fast look ups.
|
||||
lookup []SyscallFn
|
||||
lookup [maxSyscallNum + 1]SyscallFn
|
||||
|
||||
// Emulate is a collection of instruction addresses to emulate. The
|
||||
// keys are addresses, and the values are system call numbers.
|
||||
@@ -319,24 +320,20 @@ func (s *SyscallTable) Init() {
|
||||
s.Emulate = make(map[hostarch.Addr]uintptr)
|
||||
}
|
||||
|
||||
max := s.MaxSysno() // Checked during RegisterSyscallTable.
|
||||
|
||||
// Initialize the fast-lookup table.
|
||||
s.lookup = make([]SyscallFn, max+1)
|
||||
for num, sc := range s.Table {
|
||||
s.lookup[num] = sc.Fn
|
||||
}
|
||||
|
||||
// Initialize all features.
|
||||
s.FeatureEnable.init(s.Table, max)
|
||||
s.FeatureEnable.init(s.Table)
|
||||
}
|
||||
|
||||
// Lookup returns the syscall implementation, if one exists.
|
||||
func (s *SyscallTable) Lookup(sysno uintptr) SyscallFn {
|
||||
if sysno < uintptr(len(s.lookup)) {
|
||||
if sysno <= maxSyscallNum {
|
||||
return s.lookup[sysno]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user