]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: mark arguments to Syscall as noescape
authorDmitriy Vyukov <dvyukov@google.com>
Fri, 17 Jan 2014 16:18:37 +0000 (20:18 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Fri, 17 Jan 2014 16:18:37 +0000 (20:18 +0400)
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

src/cmd/gc/esc.c
src/pkg/syscall/dll_windows.go
src/pkg/syscall/syscall_linux_386.go
src/pkg/syscall/syscall_plan9.go
src/pkg/syscall/syscall_unix.go

index b84b66ef14f7e582bdcb73f64eaba7ad4f3272e1..c8fbae31b6b3003fbb666c634da23deb427d693c 100644 (file)
@@ -1135,8 +1135,13 @@ esctag(EscState *e, Node *func)
        if(func->nbody == nil) {
                if(func->noescape) {
                        for(t=getinargx(func->type)->type; t; t=t->down)
-                               if(haspointers(t->type))
-                                       t->note = mktag(EscNone);
+                               // Mark all arguments, not only pointers,
+                               // 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;
        }
index d29e9921cf7eebe63af4790acfe1dca8c26c477b..ef91d922f6e718d442813bd029c31be664710210 100644 (file)
@@ -20,11 +20,31 @@ type DLLError struct {
 func (e *DLLError) Error() string { return e.Msg }
 
 // 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)
+
+//go:noescape
+
 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)
+
+//go:noescape
+
 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 loadlibrary(filename *uint16) (handle uintptr, err Errno)
 func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
 
index a61695676f98b101783f2675420b8f44db052ad8..1947acf280deb04e7f40258c9459ca5d7a6420a1 100644 (file)
@@ -169,7 +169,16 @@ const (
        _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)
+
+//go:noescape
+
 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) {
index 2e1c064c46a5b65541344add12f814579eb434ae..267035375940ab3f45ac0ab8a26a8fc6ddd1594e 100644 (file)
@@ -51,9 +51,24 @@ var (
 // creation of IPv6 sockets to return EAFNOSUPPORT.
 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)
+
+//go:noescape
+
 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)
+
+//go:noescape
+
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
 
 func atoi(b []byte) (n uint) {
index 6455dc29c5093ef8f3cde673f7db4ae877d32533..f09051c68787fa0f1c44a18c5af9cd9f0121decd 100644 (file)
@@ -23,9 +23,24 @@ const (
        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)
+
+//go:noescape
+
 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)
+
+//go:noescape
+
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
 // Mmap manager, for use by operating system-specific implementations.