-
Notifications
You must be signed in to change notification settings - Fork 18k
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: unexpected heap allocation passing pointer to non-escaping closure #14699
Comments
@dr2chase time for your explainer to shine! |
That'd be great - there are some more cases in the linked package |
Short answer is loop nesting depth -- assigning in-loop mem to outside-loop data results in escape |
That can't be it, this still allocs: diff --git a/alloc_tests/alloc_test.go b/alloc_tests/alloc_test.go
index a8bc976..a8ccabb 100644
--- a/alloc_tests/alloc_test.go
+++ b/alloc_tests/alloc_test.go
@@ -27,10 +27,10 @@ func BenchmarkClosurePtrFromScope(b *testing.B) {
}
func BenchmarkClosurePtrFromArg(b *testing.B) {
- inc := func(k *int) {
- *k++
- }
for j := 0; j < b.N; j++ {
+ inc := func(k *int) {
+ *k++
+ }
var i int // does escape
inc(&i)
} |
Much simpler answer: indirect call. Escape analysis knows nothing about any constants that you might propagate, such as function bodies. That's something that would be nice to do in the future, but right now, it's thoroughly upstream of SSA (yes, I know this is annoying).
But, what do you think of the explainer? |
Not sure I follow. Maybe an explanation why 👍 on the explainer (ran across it on multiple occasions). It'd be interesting to be able to use the output for code highlighting - the only missing part is giving not online line numbers, but also a char range in that line if that's possible. (something like |
Having the explainer explain negatives is a bit more work. In this case, &i is not a parameter to an indirect call, so it is okay. SSA is very much (right now) a back-end-only phase, run well after escape analysis decisions have been made. Indirect calls are treated like they are radioactive, but we can still see that the closure itself doesn't escape, nor does it assign to globals. |
@dr2chase Thanks. I'm still not really following what's going on, but I think I can just look at your explainer (which presumably would give me some ideas about what the corresponding SSA for the above example looks like). Do you have its source online somewhere? Also, no point in keeping this issue open, correct? |
The explainer is now in pre-1.7. Build with -gcflags '-m -m' and you'll get explanations. The code for the explainer is interspersed through esc.go, which runs upstream of SSA. And there's no point keeping this open now, you are correct. |
Excellent, thanks again. On Wed, Mar 30, 2016 at 11:11 PM dr2chase notifications@github.com wrote:
|
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?1.6
What operating system and processor architecture are you using (
go env
)?darwin
What did you do?
See https://github.com/tschottdorf/goplay/tree/master/alloc_tests
What did you expect to see?
I'd expect i to not be allocated on the heap. The following very similar examples keep it on the stack:
What did you see instead?
i
escapes to the heap.cc @tamird
The text was updated successfully, but these errors were encountered: