Skip to content

Commit

Permalink
Additional GC.@ preserve documentation (#35139)
Browse files Browse the repository at this point in the history
(cherry picked from commit 2a7801f)
  • Loading branch information
c42f authored and KristofferC committed Mar 23, 2020
1 parent f1593e1 commit 8ea1225
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions base/gcutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,50 @@ enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0
"""
GC.@preserve x1 x2 ... xn expr
Temporarily protect the given objects from being garbage collected, even if they would
otherwise be unreferenced.
The last argument is the expression during which the object(s) will be preserved.
The previous arguments are the objects to preserve.
Mark the objects `x1, x2, ...` as being *in use* during the evaluation of the
expression `expr`. This is only required in unsafe code where `expr`
*implicitly uses* memory or other resources owned by one of the `x`s.
*Implicit use* of `x` covers any indirect use of resources logically owned by
`x` which the compiler cannot see. Some examples:
* Accessing memory of an object directly via a `Ptr`
* Passing a pointer to `x` to `ccall`
* Using resources of `x` which would be cleaned up in the finalizer.
`@preserve` should generally not have any performance impact in typical use
cases where it briefly extends object lifetime. In implementation, `@preserve`
has effects such as protecting dynamically allocated objects from garbage
collection.
# Examples
When loading from a pointer with `unsafe_load`, the underlying object is
implicitly used, for example `x` is implicitly used by `unsafe_load(p)` in the
following:
```jldoctest
julia> let
x = Ref{Int}(101)
p = Base.unsafe_convert(Ptr{Int}, x)
GC.@preserve x unsafe_load(p)
end
101
```
When passing pointers to `ccall`, the pointed-to object is implicitly used and
should be preserved. (Note however that you should normally just pass `x`
directly to `ccall` which counts as an explicit use.)
```jldoctest
julia> let
x = "Hello"
p = pointer(x)
GC.@preserve x @ccall strlen(p::Cstring)::Cint
# Preferred alternative
@ccall strlen(x::Cstring)::Cint
end
5
```
"""
macro preserve(args...)
syms = args[1:end-1]
Expand Down

0 comments on commit 8ea1225

Please sign in to comment.