For me, the example you gave of sorty is a strong argument against adding 
go:local. If I understand correctly, using go:local, if a variable marked 
this way actually does escape it would cause undefined behavior, possibly 
in unrelated code. This is the type of bug that is very, very hard to find 
and fix. Using your example of  ./sortyI8.go:319:2 
<https://github.com/jfcg/sorty/blob/e4fb296daf1d90037d59f553a340a86f2deab93a/sortyI8.go#L319>,
 
if I were doing a code review, or reading the code later, it would take a 
minute to realize that the intent was for sv, and especially sv.done not to 
live past the end of the function. But then, as a reviewer, I would want to 
make sure that was actually the case. Turns out sv, and its members are 
used in a tangled web of function calls and goroutines, some of which are 
multiple layers deep. I gave up trying to track all of it after about 12 
code jumps in my browser. One of the benefits of go, and the "go style" is 
that it should be easy to read and understand. 

I'm not saying that there is no benefit to adding something like go:local, 
just that the bar would be very, very high in my opinion.  

On Saturday, November 21, 2020 at 10:26:16 AM UTC-5 jfcg...@gmail.com wrote:

> In sorty <https://github.com/jfcg/sorty> (commit e4fb296daf1d90037d) I 
> see:
>
> $ go build -gcflags -m |& grep -i heap
> ./sortyI8.go:319:2: moved to heap: sv
> ./sortyU8.go:319:2: moved to heap: sv
> ./sortyF4.go:319:2: moved to heap: sv
> ./sortyF8.go:319:2: moved to heap: sv
> ./sortyI4.go:319:2: moved to heap: sv
> ./sortyLsw.go:338:2: moved to heap: sv
> ./sortyS.go:319:2: moved to heap: sv
> ./sortyU4.go:319:2: moved to heap: sv
>
> Local variable sv for synchronization (that I know would be safe to stay 
> local like the simplified example) escapes to heap. It is the one and only 
> thing that escapes to heap and I want to get rid of it with something like 
> *go:local* :)
> On Saturday, November 21, 2020 at 5:10:46 PM UTC+3 Ian Lance Taylor wrote:
>
>> On Sat, Nov 21, 2020 at 12:11 AM jfcg...@gmail.com <jfcg...@gmail.com> 
>> wrote: 
>> > 
>> > I have the following: 
>> > 
>> > package myf 
>> > 
>> > func F1(x *int, ch chan bool) { 
>> > *x += 1 
>> > ch <- false 
>> > } 
>> > 
>> > func F2() { 
>> > var x int 
>> > ch := make(chan bool) // or with buffer 
>> > go F1(&x, ch) 
>> > <-ch 
>> > } 
>> > 
>> > I get this when I build with go 1.15.5 via go build -gcflags '-m -m' : 
>> > 
>> > 3:6: can inline F1 with cost 7 as: func(*int, chan bool) { *x += 1; ch 
>> <- false } 
>> > 8:6: cannot inline F2: unhandled op GO 
>> > 3:9: x does not escape 
>> > 3:17: ch does not escape 
>> > 9:6: x escapes to heap: 
>> > 9:6: flow: {heap} = &x: 
>> > 9:6: from &x (address-of) at ./heap.go:11:8 
>> > 9:6: from F1(&x, ch) (call parameter) at ./heap.go:11:7 
>> > 9:6: moved to heap: x 
>> > 
>> > So x is allocated on the heap and needs gc when F2() returns. I know 
>> F2() will wait for F1() and passing &x is safe if it was local. So how can 
>> I tell this to go compiler and avoid allocation/gc costs? Do we need a new 
>> go:local directive to mark such variables? 
>>
>>
>> It would help to have a more realistic example. I don't yet see any 
>> reason why people would write code like this, so it doesn't seem worth 
>> optimizing. 
>>
>> If something like this is worth optimizing, the first thing to look 
>> into would be whether the compiler's escape analysis can improve to 
>> handle that case. A go:local directive seems very easy to misuse, and 
>> doesn't seem like a good fit for the Go language. 
>>
>> Ian 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/00ded9c0-90fb-48f4-864f-3183cedde07cn%40googlegroups.com.

Reply via email to