# Does \`GC.@preserve\` also prevent instruction re-ordering?

**URL:** https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313
**Category:** General Usage
**Created:** [February 28, 2019, 5:29pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313 "2019-02-28T17:29:53Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [February 28, 2019, 5:29pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/1 "2019-02-28T17:29:53Z")

</div>

does `GC.@preserve` also prevent the compiler re-ordering instructions? e.g. I have a C wrapper right now that is more or less:

```julia
obj = MyObjWithStorage()
client = getstorage(obj)
usedata(client)

```

where `getstorage` puts some pointers in `client` that point to data in `obj`, as well as some dynamically-allocated data that `obj` manages. Julia doesn’t know about these pointers so it thinks it can free up `obj` after its last usage, which then breaks `usedata` because the data is no longer valid. I’ve used `GC.@preserve` to fix this:

```julia
obj = MyObjWithStorage()
client = getstorage(obj)
GC.@preserve obj begin
    usedata(client)
end

```

This seems to fix the issue. Now I want to add an explicit `close` method to free up the dynamic data, so it’ll look more like

```julia
MyObjWithStorage() do obj
    client = getstorage(obj)
    GC.@preserve obj begin
        usedata(client)
    end
end

```

(where the `do` blockwill call `close(obj)` at the end and free up the `malloc`ed memory)

So I guess my question here is 2-fold:

1. do I even need the `GC.@preserve` in this case, given that `usedata` is within the `do` block?
2. if I _do_ need the `GC.@preserve`, am I also guaranteed that the compiler won’t try to move the `usedata` call outside the `do` block, given that Julia doesn’t know that `client` depends on `obj`?

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [February 28, 2019, 5:39pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/2 "2019-02-28T17:39:17Z")

</div>

To clarify, the `do` block should end up being basically the following (assuming the block function gets inlined):

```julia
obj = MyObjWithStorage()
try
    client = getstorage(obj)
    GC.@preserve obj begin
        usedata(client)
    end
finally
    close(obj)
end

```

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [February 28, 2019, 6:14pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/3 "2019-02-28T18:14:02Z")

</div>

> [@ssfrr](#):
>
> do I even need the `GC.@preserve` in this case, given that `usedata` is within the `do` block?

Yes. Unless the do block caller provides the `GC.@preserve`.

> [@ssfrr](#):
>
> try to move the `usedata` call outside the `do` block

That will never happen in a way you can observe. Execution order is an well defined observable of your program while memory management is not so even though the compiler can do whatever it want with the memory it has no such freedom with the execution order. OTOH, if the definition of `userdata` and `closer` down to the basic operations are all known to the compiler, it is certainly allowed to do whatever reordering it want if it can proof that such transformation won’t affect the result.

So no you don’t get any guarantee about the ordering but you’ll never see any effect caused by it.

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [March 1, 2019, 1:57am UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/4 "2019-03-01T01:57:00Z")

</div>

So in the case where the `close(obj)` call follows the `usedata(client)` (like in the `do` block) then I shouldn’t need the `GC.@preserve` because the GC will always wait until after the `close` call, right?

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [March 1, 2019, 2:34am UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/5 "2019-03-01T02:34:42Z")

</div>

No, by which I mean that statement is wrong and you need it.

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [March 1, 2019, 1:17pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/6 "2019-03-01T13:17:10Z")

</div>

Ah, I must still be confused then. For the code:

```julia
obj = MyObjWithStorage()
try
    client = getstorage(obj)
    usedata(client)
finally
    close(obj)
end

```

the `close(obj)` call (which presumably is doing something that requires a reference to `obj`) will always happen after `usedata(client)`, so doesn’t that mean that `obj` will not be GC’ed for the duration of `usedata(client)`?

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [March 1, 2019, 1:35pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/7 "2019-03-01T13:35:11Z")

</div>

No. As long as the compiler can do what you ask it to do in `close`, it doesn’t have to keep the object alive.

And in the end, what do you want to do? The `GC.@preserve` has almost no overhead (and in this case probably actually no overhead), unlike `try-catch-finally`. Why do you really want to get rid of it? As I said, if you don’t want to use it in the user code, just preserve it before passing it to the callback.

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [March 1, 2019, 1:41pm UTC](https://discourse.julialang.org/t/does-gc-preserve-also-prevent-instruction-re-ordering/21313/8 "2019-03-01T13:41:31Z")

</div>

Thanks for the clarification. The primary goal is to make sure I use `GC.@preserve` when I need to so things don’t crash. My secondary goal is to have a good understanding of when I need it so I don’t end up just sprinkling it randomly. Obv. it’s better to be conservative and `preserve` when in doubt, but also seems like a good test for my mental model of what the compiler is allowed to do.
