Commit fc37eba1 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent 701982f1
...@@ -1135,8 +1135,13 @@ esctag(EscState *e, Node *func) ...@@ -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 { ...@@ -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 ( ...@@ -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 ( ...@@ -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 ( ...@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment