Does `GC.@preserve a b` preserves the location of `a` and `b`

I am using GC.@preserve in my code as follows

GC.@preserve missing_bytes res begin
    src_ptr = Ptr{UInt8}(pointer(missing_bytes))
    dest_ptr = Ptr{UInt8}(pointer(res, res_len+1)) + from - 1
    # copy content over
    unsafe_copyto!(dest_ptr, src_ptr, res_len)
end

I am getting an error, but I want to check my understanding. In the code above, I wanted to copy some memory over from one location to another. So to do that I don’t want the memory location to change, so I preserve missing_bytes and res so that their memory location will not change for duration of the begin and end block. Is my understand correct? So if the code fails, it must be because of either

  1. my operation is illegal
  2. There is Julia bug (highly unlikely)

and I can rule the data having moved location while that code is running causing issues. Right?

GC.@preserve, or the GC in general does nothing about the “location” of variables/arrays, it makes sure the object is valid and all derived pointer from it are valid unless explicitly invalidated otherwise, for example, if you push an element to an array. For well defined object the use of GC.@preserve looks correct assuming no race or other undefined behavior (e.g. out of bound access).

2 Likes

If res_len is the length of res, do you mean to be point to its end?

I am looking at Vector{Union{Missing, T}}. The missing indicators are located past the T values, hence looking past that in this is the right way to go.

1 Like

so basically it just ensures my pointer calls will return the location I wanted. Anyway, have not encountered any memory crashes after I fixed the bugs, so my understanding of GC.@preserve, although wrong didn’t lead me astray.

I’m pretty sure it may not be there. There could be gap in between. (Also I thought there’s a function to give you it’s location so you don’t need to do it yourself)

1 Like

Oh! I need to find it. If you can recall what it is please do let me know! It’s worked for me so far.

I found some info here but it doesn’t exactly tell me a a function to find it https://docs.julialang.org/en/v1/devdocs/isbitsunionarrays/

See implementation of https://github.com/JuliaLang/julia/blob/853fe04e303621a7d11db980905ab26979b8b1fc/base/array.jl#L286

I see it. It’s hard to interpret how I can use it in practice.

My use case is that I know where the missing are but the data I want to copy are not in the form of a complete Vector{Union{Missing, T}}. But code just shows how to use them with Vector{Union{T, Missing}} which is via a ccall to jl_array_typetagdata. So I can’t go deeper into jl_array_typetagdata.

What else do you want to interpret? You are asking about a function to get the location of the tags and jl_array_typetagdata is the answer.

I see. I misinterpreted it! I thought it was the code to move the vectors but it’s actually the code that returns the location.