aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-10 05:15:52 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-10 05:15:52 +0000
commite4876be5f5c5524ea742527100e36c5095181b28 (patch)
treec910fc6515e88a22e58ae52d5a5d7f80e0cfc982 /libgo
parentfe9e1702687db062ad2f13939177e1c5f68c8e05 (diff)
downloadgcc-e4876be5f5c5524ea742527100e36c5095181b28.zip
gcc-e4876be5f5c5524ea742527100e36c5095181b28.tar.gz
gcc-e4876be5f5c5524ea742527100e36c5095181b28.tar.bz2
runtime: noescape some functions/variables
This is in preparation of turning on escape analysis for the runtime. - In gccgo, systemstack is implemented with mcall, which is not go:noescape. Wrap the closure in noescape so the escape analysis does not think it escapes. - Mark some C functions go:noescape. They do not leak arguments. - Use noescape function to make a few local variables' addresses not escape. The escape analysis cannot figure out because they are assigned to pointer indirections. Reviewed-on: https://go-review.googlesource.com/86244 From-SVN: r256418
Diffstat (limited to 'libgo')
-rw-r--r--libgo/go/runtime/panic.go10
-rw-r--r--libgo/go/runtime/proc.go4
-rw-r--r--libgo/go/runtime/signal_gccgo.go8
-rw-r--r--libgo/go/runtime/stubs.go9
-rw-r--r--libgo/go/runtime/traceback_gccgo.go7
5 files changed, 28 insertions, 10 deletions
diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go
index 5cc325f..b2deb6e 100644
--- a/libgo/go/runtime/panic.go
+++ b/libgo/go/runtime/panic.go
@@ -201,7 +201,7 @@ func deferreturn(frame *bool) {
// The gc compiler does this using assembler
// code in jmpdefer.
var fn func(unsafe.Pointer)
- *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
+ *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(noescape(unsafe.Pointer(&pfn)))
fn(d.arg)
}
@@ -264,7 +264,7 @@ func checkdefer(frame *bool) {
var p _panic
p.isforeign = true
p.link = gp._panic
- gp._panic = &p
+ gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
for {
d := gp._defer
if d == nil || d.frame != frame || d.pfn == 0 {
@@ -275,7 +275,7 @@ func checkdefer(frame *bool) {
gp._defer = d.link
var fn func(unsafe.Pointer)
- *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
+ *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(noescape(unsafe.Pointer(&pfn)))
fn(d.arg)
freedefer(d)
@@ -368,7 +368,7 @@ func Goexit() {
d.pfn = 0
var fn func(unsafe.Pointer)
- *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
+ *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(noescape(unsafe.Pointer(&pfn)))
fn(d.arg)
if gp._defer != d {
@@ -491,7 +491,7 @@ func gopanic(e interface{}) {
d._panic = p
var fn func(unsafe.Pointer)
- *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
+ *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(noescape(unsafe.Pointer(&pfn)))
fn(d.arg)
if gp._defer != d {
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 1ea4152..515efaa 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -46,7 +46,11 @@ import (
// C functions for thread and context management.
func newosproc(*m)
+
+//go:noescape
func malg(bool, bool, *unsafe.Pointer, *uintptr) *g
+
+//go:noescape
func resetNewG(*g, *unsafe.Pointer, *uintptr)
func gogo(*g)
func setGContext()
diff --git a/libgo/go/runtime/signal_gccgo.go b/libgo/go/runtime/signal_gccgo.go
index 6fe7ba1..92143ea 100644
--- a/libgo/go/runtime/signal_gccgo.go
+++ b/libgo/go/runtime/signal_gccgo.go
@@ -13,24 +13,31 @@ import (
// Functions for gccgo to support signal handling. In the gc runtime
// these are written in OS-specific files and in assembler.
+//go:noescape
//extern sigaction
func sigaction(signum uint32, act *_sigaction, oact *_sigaction) int32
+//go:noescape
//extern sigprocmask
func sigprocmask(how int32, set *sigset, oldset *sigset) int32
+//go:noescape
//extern sigfillset
func sigfillset(set *sigset) int32
+//go:noescape
//extern sigemptyset
func sigemptyset(set *sigset) int32
+//go:noescape
//extern sigaddset
func c_sigaddset(set *sigset, signum uint32) int32
+//go:noescape
//extern sigdelset
func c_sigdelset(set *sigset, signum uint32) int32
+//go:noescape
//extern sigaltstack
func sigaltstack(ss *_stack_t, oss *_stack_t) int32
@@ -43,6 +50,7 @@ func getpid() _pid_t
//extern kill
func kill(pid _pid_t, sig uint32) int32
+//go:noescape
//extern setitimer
func setitimer(which int32, new *_itimerval, old *_itimerval) int32
diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go
index c454356b..fa3b1ce 100644
--- a/libgo/go/runtime/stubs.go
+++ b/libgo/go/runtime/stubs.go
@@ -60,10 +60,11 @@ func systemstack(fn func()) {
if gp == mp.g0 || gp == mp.gsignal {
fn()
} else if gp == mp.curg {
- mcall(func(origg *g) {
+ fn1 := func(origg *g) {
fn()
gogo(origg)
- })
+ }
+ mcall(*(*func(*g))(noescape(unsafe.Pointer(&fn1))))
} else {
badsystemstack()
}
@@ -160,6 +161,7 @@ func breakpoint()
func asminit() {}
//go:linkname reflectcall reflect.call
+//go:noescape
func reflectcall(fntype *functype, fn *funcval, isInterface, isMethod bool, params, results *unsafe.Pointer)
func procyield(cycles uint32)
@@ -355,7 +357,10 @@ func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
func getSigtramp() uintptr
// The sa_handler field is generally hidden in a union, so use C accessors.
+//go:noescape
func getSigactionHandler(*_sigaction) uintptr
+
+//go:noescape
func setSigactionHandler(*_sigaction, uintptr)
// Retrieve fields from the siginfo_t and ucontext_t pointers passed
diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go
index 79f78d8..8551ec1 100644
--- a/libgo/go/runtime/traceback_gccgo.go
+++ b/libgo/go/runtime/traceback_gccgo.go
@@ -9,7 +9,7 @@ package runtime
import (
"runtime/internal/sys"
- _ "unsafe" // for go:linkname
+ "unsafe"
)
func printcreatedby(gp *g) {
@@ -46,6 +46,7 @@ type location struct {
lineno int
}
+//go:noescape
//extern runtime_callers
func c_callers(skip int32, locbuf *location, max int32, keepThunks bool) int32
@@ -185,7 +186,7 @@ func tracebackothers(me *g) {
if gp != nil && gp != me {
print("\n")
goroutineheader(gp)
- gp.traceback = &tb
+ gp.traceback = (*tracebackg)(noescape(unsafe.Pointer(&tb)))
getTraceback(me, gp)
printtrace(tb.locbuf[:tb.c], nil)
printcreatedby(gp)
@@ -219,7 +220,7 @@ func tracebackothers(me *g) {
print("\tgoroutine in C code; stack unavailable\n")
printcreatedby(gp)
} else {
- gp.traceback = &tb
+ gp.traceback = (*tracebackg)(noescape(unsafe.Pointer(&tb)))
getTraceback(me, gp)
printtrace(tb.locbuf[:tb.c], nil)
printcreatedby(gp)