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: inaccurate escape to heap message #45269

Open
go101 opened this issue Mar 28, 2021 · 8 comments
Open

cmd/compile: inaccurate escape to heap message #45269

go101 opened this issue Mar 28, 2021 · 8 comments

Comments

@go101
Copy link

@go101 go101 commented Mar 28, 2021

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

$ go version
go version go1.16 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

package main

var i interface{}

func f() {
  type T int
  var a [1<<20]byte
  i = a // a escapes to heap
}

func main(){
  var x int
  println(&x)
  f()
  println(&x)
}

What did you expect to see?

$ go build -gcflags="-m" a.go
# command-line-arguments
./a.go:11:6: can inline main
./a.go:8:5: a copy of a escapes to heap

What did you see instead?

$ go build -gcflags="-m" a.go
# command-line-arguments
./a.go:11:6: can inline main
./a.go:8:5: a escapes to heap
@seankhliao seankhliao changed the title cmd/compile: inaccurate message cmd/compile: inaccurate escape to heap message Mar 28, 2021
@cuiweixie
Copy link
Contributor

@cuiweixie cuiweixie commented Mar 29, 2021

what should we expect to see a copy of a escapes to heap

@go101
Copy link
Author

@go101 go101 commented Mar 29, 2021

From logic, a should not escape to heap. And this gets verified by the fact that the compiler doesn't report escape for line 7.

Maybe nothing needs to change here. The message a escapes to heap for line 8 should be interpreted as a, as a right value, escapes to heap. But a little more accuracy would be better.

@go101
Copy link
Author

@go101 go101 commented Jun 28, 2021

It looks escape analysis misses a escapes to heap message for make(chan bool)

package main

func main() {
	x := new(int)          // new(int) escapes to heap
	c := make(chan bool)   // (missing)
	s := make([]int, 5)    // make([]int, 5) escapes to heap
	m := make(map[int]int) // make(map[int]int) escapes to heap
	go func() {
		*x = 1
		s[0] = 1
		m[1] = 1
		close(c)
	}()
	<-c
	println(*x)
	println(x)
	println(s[0])
	println(m[1])
}

@randall77
Copy link
Contributor

@randall77 randall77 commented Jun 28, 2021

Channels can't be allocated on the stack, so I don't think there's value in tracking their escapiness.

@go101
Copy link
Author

@go101 go101 commented Jun 29, 2021

Reasonable, mainly for sorting purpose in select blocks?

Will a channel used as a FIFO queue in a single goroutine be allocated on heap?

@randall77
Copy link
Contributor

@randall77 randall77 commented Jun 29, 2021

Reasonable, mainly for sorting purpose in select blocks?

That would be one complication of stack allocation, yes.

Will a channel used as a FIFO queue in a single goroutine be allocated on heap?

Yes, currently.

@go101
Copy link
Author

@go101 go101 commented Jul 14, 2021

And this? It looks [N]byte{} doesn't escape.

package main

const N = 100 * 1024 * 1024

var i interface{}
func bar() {
	i = [N]byte{} // [104857600]byte{} escapes to heap
}


func main() {
	run := func(f func(), c chan struct{}) {
		defer close(c)
		var x int
		println(&x) // <address 1>
		f()
		println(&x) // <address 2>
	}

	c2 := make(chan struct{})
	go run(bar, c2)
	<-c2
}

@randall77
Copy link
Contributor

@randall77 randall77 commented Jul 14, 2021

It is stack allocating a big byte array. Not sure why that escape message is there - maybe it refers to the copy that is the backing store for the interface?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants