Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: KeepAlive causes its argument to escape #19687

Closed
cespare opened this issue Mar 24, 2017 · 3 comments

Comments

Projects
None yet
6 participants
@cespare
Copy link
Contributor

commented Mar 24, 2017

What version of Go are you using (go version)?

I see this on Go 1.8 and also tip. The examples below were run with tip.

What operating system and processor architecture are you using (go env)?

linux/amd64

See original context here: https://groups.google.com/d/msg/golang-nuts/dcjzJy-bSpw/6yntq3OVBQAJ

It seems that calling runtime.KeepAlive causes the argument to escape:

package main

import "runtime"

func f(s string) {
	runtime.KeepAlive(s)
}

func main() {
	f("hello")
}

// ./test.go:5:6: can inline f
// ./test.go:9:6: can inline main
// ./test.go:10:3: inlining call to f
// ./test.go:6:19: s escapes to heap
// ./test.go:5:10: leaking param: s
// ./test.go:10:3: s escapes to heap

Bizarrely, if I change the definition of KeepAlive to give the parameter a name:

//go:noinline
func KeepAlive(v interface{}) {} // instead of func KeepAlive(interface{}) {}

then the argument doesn't escape:

package main

import "runtime"

func f(s string) {
	runtime.KeepAlive(s)
}

func main() {
	f("hello")
}

// ./test.go:5:6: can inline f
// ./test.go:9:6: can inline main
// ./test.go:10:3: inlining call to f
// ./test.go:5:10: f s does not escape
// ./test.go:6:19: f s does not escape
// ./test.go:10:3: main s does not escape

@randall77 @ianlancetaylor

@dmac

This comment has been minimized.

Copy link

commented Mar 24, 2017

Here's a minimal example that I believe exhibits the same issue:

package main

//go:noinline
func foo(*int) {}

func main() {
	n := 1
	foo(&n)
}

// ./test.go:8: &n escapes to heap
// ./test.go:7: moved to heap: n
package main

//go:noinline
func foo(p *int) {}

func main() {
	n := 1
	foo(&n)
}

// ./test.go:4: foo p does not escape
// ./test.go:8: main &n does not escape

@bradfitz bradfitz added this to the Go1.9Maybe milestone Mar 24, 2017

@randall77 randall77 self-assigned this Mar 24, 2017

@josharian

This comment has been minimized.

Copy link
Contributor

commented Mar 24, 2017

@gopherbot

This comment has been minimized.

Copy link

commented Mar 24, 2017

CL https://golang.org/cl/38600 mentions this issue.

@gopherbot gopherbot closed this in a69754e Mar 24, 2017

@golang golang locked and limited conversation to collaborators Mar 24, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.