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.