It isn't just inlining that affects closures.

Most programming languages with closures use several closure
representations at the same time. The compiler picks among them depending
on which representation gives the best program efficiency at runtime and
depending on what information they statically know about the program at
compile time. This makes your question inherently hard to answer precisely
because the representation can change quite a lot even with small changes
to the program text.

However, the original rules apply for the GC: roots are given as the global
variables plus each pointer off of the stacks of the goroutines. Following
these pointers transitively through the heap defines data which is live and
thus not collectable. The compiler is responsible to make sure that this is
an invariant when it compiles a closure. It must also follow the rules of a
program stack: if a variable escapes its deallocation on the stack, that
variable must be moved somewhere safe, typically the heap.

In short: the GC essentially proposes a contract/invariant/protocol. If the
compiler abides by that contract, it can do whatever it wants within the
limits of what the contract says.

On Wed, Mar 22, 2017 at 3:41 PM T L <tapir....@gmail.com> wrote:

>
>
> On Wednesday, March 22, 2017 at 10:38:32 PM UTC+8, T L wrote:
>
>
>
> On Wednesday, March 22, 2017 at 7:49:39 PM UTC+8, Dave Cheney wrote:
>
> Well, that program isn't that simple because of the closure, but also
> because it contains a data race
>
> Something like this is easier to reason about
>
> var x *int
>
> func main() {
>         var a int
>         x = &a
>         fmt.Println(*x)
> }
>
>
> or like this, :D
>
>     package main
>
>     func f(*int){
>         var b int
>         // avoid f to be inlined.
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>         b++
>     }
>
>     func main() {
>          var a int
>          f(&a) // &a escapes to heap
>     }
>
>
>
>
> a simpler one
>
>     package main
>
>     func f(*int){
>         for 1 < 0 {} // avoid f to be inlined.
>
>     }
>
>     func main() {
>          var a int
>          f(&a) // &a escapes to heap
>     }
>
>
> On Wednesday, 22 March 2017 21:59:17 UTC+11, T L wrote:
>
>
>
> On Wednesday, March 22, 2017 at 6:40:53 PM UTC+8, Jesse McNelis wrote:
>
> On Wed, Mar 22, 2017 at 8:51 PM, T L <tapi...@gmail.com> wrote:
> >
> >  More accurately, I think it should be: from the POV of a programmer,
> it's
> > globals, and things reachable from each goroutine.
> >
>
> The only way to reach a value is through a variable in scope and the
> only variables in scope are global or on the stack.
>
> 'heap pointers of local allocated memory blocks' are stored where ever
> you put them, but you can only put them in places you can find by
> using global or local stack variables.
>
>
> So for this simple program:
>
> func main() {
>     var a int
>     go func() { // new goroutine
>         a++
>     }()
>
>     // ...
> }
>
> a will be allocated on heap.
> a is referenced by both stack of main and the new goroutine?
> how is it referenced, the pointer of a's memory block is stored in both
> stacks?
>
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to