Skip to content

Commit 8ea1225

Browse files
c42fKristofferC
authored andcommitted
Additional GC.@ preserve documentation (#35139)
(cherry picked from commit 2a7801f)
1 parent f1593e1 commit 8ea1225

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

base/gcutils.jl

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,50 @@ enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0
8383
"""
8484
GC.@preserve x1 x2 ... xn expr
8585
86-
Temporarily protect the given objects from being garbage collected, even if they would
87-
otherwise be unreferenced.
88-
89-
The last argument is the expression during which the object(s) will be preserved.
90-
The previous arguments are the objects to preserve.
86+
Mark the objects `x1, x2, ...` as being *in use* during the evaluation of the
87+
expression `expr`. This is only required in unsafe code where `expr`
88+
*implicitly uses* memory or other resources owned by one of the `x`s.
89+
90+
*Implicit use* of `x` covers any indirect use of resources logically owned by
91+
`x` which the compiler cannot see. Some examples:
92+
* Accessing memory of an object directly via a `Ptr`
93+
* Passing a pointer to `x` to `ccall`
94+
* Using resources of `x` which would be cleaned up in the finalizer.
95+
96+
`@preserve` should generally not have any performance impact in typical use
97+
cases where it briefly extends object lifetime. In implementation, `@preserve`
98+
has effects such as protecting dynamically allocated objects from garbage
99+
collection.
100+
101+
# Examples
102+
103+
When loading from a pointer with `unsafe_load`, the underlying object is
104+
implicitly used, for example `x` is implicitly used by `unsafe_load(p)` in the
105+
following:
106+
107+
```jldoctest
108+
julia> let
109+
x = Ref{Int}(101)
110+
p = Base.unsafe_convert(Ptr{Int}, x)
111+
GC.@preserve x unsafe_load(p)
112+
end
113+
101
114+
```
115+
116+
When passing pointers to `ccall`, the pointed-to object is implicitly used and
117+
should be preserved. (Note however that you should normally just pass `x`
118+
directly to `ccall` which counts as an explicit use.)
119+
120+
```jldoctest
121+
julia> let
122+
x = "Hello"
123+
p = pointer(x)
124+
GC.@preserve x @ccall strlen(p::Cstring)::Cint
125+
# Preferred alternative
126+
@ccall strlen(x::Cstring)::Cint
127+
end
128+
5
129+
```
91130
"""
92131
macro preserve(args...)
93132
syms = args[1:end-1]

0 commit comments

Comments
 (0)