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

cmd/compile: byte array fields escape to the heap if they are sliced and passed to copy #19723

Closed
davecheney opened this issue Mar 27, 2017 · 3 comments

Comments

@davecheney
Copy link
Contributor

Please answer these questions before submitting your issue. Thanks!

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

go version devel +4909ecc Sun Mar 26 21:29:31 2017 +0000 linux/amd64

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

linux/amd64

What did you do?

package main

type Buf struct {
	buf [100]byte
	off int
}

// Insert inserts b at offset i.
func (a *Buf) Insert(i int, b byte) {
	a.off++
	copy(a.buf[i+1:a.off], a.buf[i:a.off-1])
	a.buf[i] = b
}

func main() {
	var a Buf
	a.Insert(0, 1)
}

What did you expect to see?

a does not escape to the heap

What did you see instead?

./escape.go:9:31: leaking param content: a
./escape.go:9:31: 	from a.buf (dot of pointer) at ./escape.go:11:26
./escape.go:9:31: 	from a.buf (address-of) at ./escape.go:11:30
./escape.go:9:31: 	from a.buf[i:a.off - 1] (slice) at ./escape.go:11:30
./escape.go:9:31: 	from *a.buf[i:a.off - 1] (indirection) at ./escape.go:11:30
./escape.go:9:31: 	from copy(a.buf[i + 1:a.off], a.buf[i:a.off - 1]) (copied slice) at ./escape.go:11:6
@bradfitz
Copy link
Contributor

@brtzsnr @randall77 @dr2chase

@bradfitz bradfitz added this to the Go1.9Maybe milestone Mar 27, 2017
@randall77
Copy link
Contributor

I think you're misinterpreting the escape analysis output. a is not escaping, its content is. Its contents contains no pointers, so that isn't really relevant to a itself escaping.

The assembly output is clear that a is allocated on the stack in main.

Reopen if I'm missing something. Certainly the escape analysis output could be clarified.

@davecheney
Copy link
Contributor Author

@randall77 thanks Keith. I've confirmed that this doesn't allocate. Thanks

lucky(~/src/esc) % go test -bench=.                                                                                                                                                                                                                            
goos: linux
goarch: amd64
pkg: esc
BenchmarkBufInsert-4    100000000               13.7 ns/op             0 B/op          0 allocs/op

@golang golang locked and limited conversation to collaborators Mar 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants