mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
syscall: mark arguments to Syscall as noescape
Heap arguments to "async" syscalls will break when/if we have moving GC anyway. With this change is must not break until moving GC, because a user must reference the object in Go to preserve liveness. Otherwise the code is broken already. Reduces number of leaked params from 125 to 36 on linux. R=golang-codereviews, mikioh.mikioh, bradfitz CC=cshapiro, golang-codereviews, khr, rsc https://golang.org/cl/45930043
This commit is contained in:
parent
701982f173
commit
fc37eba149
5 changed files with 66 additions and 2 deletions
|
|
@ -1135,8 +1135,13 @@ esctag(EscState *e, Node *func)
|
||||||
if(func->nbody == nil) {
|
if(func->nbody == nil) {
|
||||||
if(func->noescape) {
|
if(func->noescape) {
|
||||||
for(t=getinargx(func->type)->type; t; t=t->down)
|
for(t=getinargx(func->type)->type; t; t=t->down)
|
||||||
if(haspointers(t->type))
|
// Mark all arguments, not only pointers,
|
||||||
t->note = mktag(EscNone);
|
// to support the following use case.
|
||||||
|
// Syscall package converts all pointers to uintptr
|
||||||
|
// when calls asm-implemented Syscall function:
|
||||||
|
//
|
||||||
|
// Syscall(SYS_FOO, uintptr(unsafe.Pointer(p)), 0, 0)
|
||||||
|
t->note = mktag(EscNone);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,31 @@ type DLLError struct {
|
||||||
func (e *DLLError) Error() string { return e.Msg }
|
func (e *DLLError) Error() string { return e.Msg }
|
||||||
|
|
||||||
// Implemented in ../runtime/syscall_windows.goc.
|
// Implemented in ../runtime/syscall_windows.goc.
|
||||||
|
|
||||||
|
// Pointers passed to syscalls must not escape (be accessed by OS after the syscall returns).
|
||||||
|
// For heap objects this will break when/if we have moving GC.
|
||||||
|
// And for other objects (global, C allocated) go:noescape has no effect.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
func loadlibrary(filename *uint16) (handle uintptr, err Errno)
|
func loadlibrary(filename *uint16) (handle uintptr, err Errno)
|
||||||
func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
|
func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,16 @@ const (
|
||||||
_SENDMMSG = 20
|
_SENDMMSG = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Pointers passed to syscalls must not escape (be accessed by OS after the syscall returns).
|
||||||
|
// For heap objects this will break when/if we have moving GC.
|
||||||
|
// And for other objects (global, C allocated) go:noescape has no effect.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
|
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
|
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
|
||||||
|
|
||||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
|
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,24 @@ var (
|
||||||
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||||
var SocketDisableIPv6 bool
|
var SocketDisableIPv6 bool
|
||||||
|
|
||||||
|
// Pointers passed to syscalls must not escape (be accessed by OS after the syscall returns).
|
||||||
|
// For heap objects this will break when/if we have moving GC.
|
||||||
|
// And for other objects (global, C allocated) go:noescape has no effect.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
|
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||||
|
|
||||||
func atoi(b []byte) (n uint) {
|
func atoi(b []byte) (n uint) {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,24 @@ const (
|
||||||
netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
|
netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Pointers passed to syscalls must not escape (be accessed by OS after the syscall returns).
|
||||||
|
// For heap objects this will break when/if we have moving GC.
|
||||||
|
// And for other objects (global, C allocated) go:noescape has no effect.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
// Mmap manager, for use by operating system-specific implementations.
|
// Mmap manager, for use by operating system-specific implementations.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue