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
This commit is contained in:
parent
fe9e170268
commit
e4876be5f5
@ -1,4 +1,4 @@
|
||||
8e20ba6b6c4906f2f0be4b0a1515d11e0f41fb29
|
||||
5cae6a4e0849a3586ee7ce9c915c1520a17db982
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user