I found this in runtime/chan.go:

// Sends and receives on unbuffered or empty-buffered channels are the
// only operations where one running goroutine writes to the stack of
// another running goroutine. The GC assumes that stack writes only
// happen when the goroutine is running and are only done by that
// goroutine. Using a write barrier is sufficient to make up for
// violating that assumption, but the write barrier has to work.

So keeping a variable local but sharing its address with another goroutine 
opens the possibility of writing to the variable (from the non-owner 
goroutine) which seems to violate the above assumption. Probably too much 
work to implement..

On Saturday, November 21, 2020 at 7:36:54 PM UTC+3 jake...@gmail.com wrote:

> 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/e64a1d69-e0f2-4222-9f30-06497b743c82n%40googlegroups.com.

Reply via email to