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

Projects
None yet
4 participants
@davecheney
Copy link
Contributor

commented Mar 27, 2017

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

This comment has been minimized.

Copy link
Member

commented Mar 27, 2017

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

@randall77

This comment has been minimized.

Copy link
Contributor

commented Mar 27, 2017

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.

@randall77 randall77 closed this Mar 27, 2017

@davecheney

This comment has been minimized.

Copy link
Contributor Author

commented Mar 27, 2017

@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.
You can’t perform that action at this time.