Skip to content

Commit e46f627

Browse files
maleadtBioTurboNick
authored andcommitted
Simplify the GC.gc interface. (JuliaLang#34303)
(cherry picked from commit b0ed147)
1 parent 7b1f512 commit e46f627

File tree

1 file changed

+165
-165
lines changed

1 file changed

+165
-165
lines changed

base/gcutils.jl

Lines changed: 165 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,165 @@
1-
# This file is a part of Julia. License is MIT: https://julialang.org/license
2-
3-
==(w::WeakRef, v::WeakRef) = isequal(w.value, v.value)
4-
==(w::WeakRef, v) = isequal(w.value, v)
5-
==(w, v::WeakRef) = isequal(w, v.value)
6-
7-
"""
8-
finalizer(f, x)
9-
10-
Register a function `f(x)` to be called when there are no program-accessible references to
11-
`x`, and return `x`. The type of `x` must be a `mutable struct`, otherwise the behavior of
12-
this function is unpredictable.
13-
14-
`f` must not cause a task switch, which excludes most I/O operations such as `println`.
15-
Using the `@async` macro (to defer context switching to outside of the finalizer) or
16-
`ccall` to directly invoke IO functions in C may be helpful for debugging purposes.
17-
18-
# Examples
19-
```julia
20-
finalizer(my_mutable_struct) do x
21-
@async println("Finalizing \$x.")
22-
end
23-
24-
finalizer(my_mutable_struct) do x
25-
ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.", repr(x))
26-
end
27-
```
28-
"""
29-
function finalizer(@nospecialize(f), @nospecialize(o))
30-
if !ismutable(o)
31-
error("objects of type ", typeof(o), " cannot be finalized")
32-
end
33-
ccall(:jl_gc_add_finalizer_th, Cvoid, (Ptr{Cvoid}, Any, Any),
34-
Core.getptls(), o, f)
35-
return o
36-
end
37-
38-
function finalizer(f::Ptr{Cvoid}, o::T) where T
39-
@_inline_meta
40-
if !ismutable(o)
41-
error("objects of type ", typeof(o), " cannot be finalized")
42-
end
43-
ccall(:jl_gc_add_ptr_finalizer, Cvoid, (Ptr{Cvoid}, Any, Ptr{Cvoid}),
44-
Core.getptls(), o, f)
45-
return o
46-
end
47-
48-
"""
49-
finalize(x)
50-
51-
Immediately run finalizers registered for object `x`.
52-
"""
53-
finalize(@nospecialize(o)) = ccall(:jl_finalize_th, Cvoid, (Ptr{Cvoid}, Any,),
54-
Core.getptls(), o)
55-
56-
"""
57-
Base.GC
58-
59-
Module with garbage collection utilities.
60-
"""
61-
module GC
62-
63-
# mirrored from julia.h
64-
const GC_AUTO = 0
65-
const GC_FULL = 1
66-
const GC_INCREMENTAL = 2
67-
68-
"""
69-
GC.gc([full=true])
70-
71-
Perform garbage collection. The argument `full` determines the kind of
72-
collection: A full collection (default) sweeps all objects, which makes the
73-
next GC scan much slower, while an incremental collection may only sweep
74-
so-called young objects.
75-
76-
!!! warning
77-
Excessive use will likely lead to poor performance.
78-
"""
79-
gc(full::Bool=true) =
80-
ccall(:jl_gc_collect, Cvoid, (Cint,), full ? GC_FULL : GC_INCREMENTAL)
81-
82-
"""
83-
GC.enable(on::Bool)
84-
85-
Control whether garbage collection is enabled using a boolean argument (`true` for enabled,
86-
`false` for disabled). Return previous GC state.
87-
88-
!!! warning
89-
Disabling garbage collection should be used only with caution, as it can cause memory
90-
use to grow without bound.
91-
"""
92-
enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0
93-
94-
"""
95-
GC.@preserve x1 x2 ... xn expr
96-
97-
Mark the objects `x1, x2, ...` as being *in use* during the evaluation of the
98-
expression `expr`. This is only required in unsafe code where `expr`
99-
*implicitly uses* memory or other resources owned by one of the `x`s.
100-
101-
*Implicit use* of `x` covers any indirect use of resources logically owned by
102-
`x` which the compiler cannot see. Some examples:
103-
* Accessing memory of an object directly via a `Ptr`
104-
* Passing a pointer to `x` to `ccall`
105-
* Using resources of `x` which would be cleaned up in the finalizer.
106-
107-
`@preserve` should generally not have any performance impact in typical use
108-
cases where it briefly extends object lifetime. In implementation, `@preserve`
109-
has effects such as protecting dynamically allocated objects from garbage
110-
collection.
111-
112-
# Examples
113-
114-
When loading from a pointer with `unsafe_load`, the underlying object is
115-
implicitly used, for example `x` is implicitly used by `unsafe_load(p)` in the
116-
following:
117-
118-
```jldoctest
119-
julia> let
120-
x = Ref{Int}(101)
121-
p = Base.unsafe_convert(Ptr{Int}, x)
122-
GC.@preserve x unsafe_load(p)
123-
end
124-
101
125-
```
126-
127-
When passing pointers to `ccall`, the pointed-to object is implicitly used and
128-
should be preserved. (Note however that you should normally just pass `x`
129-
directly to `ccall` which counts as an explicit use.)
130-
131-
```jldoctest
132-
julia> let
133-
x = "Hello"
134-
p = pointer(x)
135-
GC.@preserve x @ccall strlen(p::Cstring)::Cint
136-
# Preferred alternative
137-
@ccall strlen(x::Cstring)::Cint
138-
end
139-
5
140-
```
141-
"""
142-
macro preserve(args...)
143-
syms = args[1:end-1]
144-
for x in syms
145-
isa(x, Symbol) || error("Preserved variable must be a symbol")
146-
end
147-
esc(Expr(:gc_preserve, args[end], syms...))
148-
end
149-
150-
"""
151-
GC.safepoint()
152-
153-
Inserts a point in the program where garbage collection may run.
154-
This can be useful in rare cases in multi-threaded programs where some threads
155-
are allocating memory (and hence may need to run GC) but other threads are doing
156-
only simple operations (no allocation, task switches, or I/O).
157-
Calling this function periodically in non-allocating threads allows garbage
158-
collection to run.
159-
160-
!!! compat "Julia 1.4"
161-
This function is available as of Julia 1.4.
162-
"""
163-
safepoint() = ccall(:jl_gc_safepoint, Cvoid, ())
164-
165-
end # module GC
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
==(w::WeakRef, v::WeakRef) = isequal(w.value, v.value)
4+
==(w::WeakRef, v) = isequal(w.value, v)
5+
==(w, v::WeakRef) = isequal(w, v.value)
6+
7+
"""
8+
finalizer(f, x)
9+
10+
Register a function `f(x)` to be called when there are no program-accessible references to
11+
`x`, and return `x`. The type of `x` must be a `mutable struct`, otherwise the behavior of
12+
this function is unpredictable.
13+
14+
`f` must not cause a task switch, which excludes most I/O operations such as `println`.
15+
Using the `@async` macro (to defer context switching to outside of the finalizer) or
16+
`ccall` to directly invoke IO functions in C may be helpful for debugging purposes.
17+
18+
# Examples
19+
```julia
20+
finalizer(my_mutable_struct) do x
21+
@async println("Finalizing \$x.")
22+
end
23+
24+
finalizer(my_mutable_struct) do x
25+
ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.", repr(x))
26+
end
27+
```
28+
"""
29+
function finalizer(@nospecialize(f), @nospecialize(o))
30+
if !ismutable(o)
31+
error("objects of type ", typeof(o), " cannot be finalized")
32+
end
33+
ccall(:jl_gc_add_finalizer_th, Cvoid, (Ptr{Cvoid}, Any, Any),
34+
Core.getptls(), o, f)
35+
return o
36+
end
37+
38+
function finalizer(f::Ptr{Cvoid}, o::T) where T
39+
@_inline_meta
40+
if !ismutable(o)
41+
error("objects of type ", typeof(o), " cannot be finalized")
42+
end
43+
ccall(:jl_gc_add_ptr_finalizer, Cvoid, (Ptr{Cvoid}, Any, Ptr{Cvoid}),
44+
Core.getptls(), o, f)
45+
return o
46+
end
47+
48+
"""
49+
finalize(x)
50+
51+
Immediately run finalizers registered for object `x`.
52+
"""
53+
finalize(@nospecialize(o)) = ccall(:jl_finalize_th, Cvoid, (Ptr{Cvoid}, Any,),
54+
Core.getptls(), o)
55+
56+
"""
57+
Base.GC
58+
59+
Module with garbage collection utilities.
60+
"""
61+
module GC
62+
63+
# mirrored from julia.h
64+
const GC_AUTO = 0
65+
const GC_FULL = 1
66+
const GC_INCREMENTAL = 2
67+
68+
"""
69+
GC.gc([full=true])
70+
71+
Perform garbage collection. The argument `full` determines the kind of
72+
collection: A full collection (default) sweeps all objects, which makes the
73+
next GC scan much slower, while an incremental collection may only sweep
74+
so-called young objects.
75+
76+
!!! warning
77+
Excessive use will likely lead to poor performance.
78+
"""
79+
gc(full::Bool=true) =
80+
ccall(:jl_gc_collect, Cvoid, (Cint,), full ? GC_FULL : GC_INCREMENTAL)
81+
82+
"""
83+
GC.enable(on::Bool)
84+
85+
Control whether garbage collection is enabled using a boolean argument (`true` for enabled,
86+
`false` for disabled). Return previous GC state.
87+
88+
!!! warning
89+
Disabling garbage collection should be used only with caution, as it can cause memory
90+
use to grow without bound.
91+
"""
92+
enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0
93+
94+
"""
95+
GC.@preserve x1 x2 ... xn expr
96+
97+
Mark the objects `x1, x2, ...` as being *in use* during the evaluation of the
98+
expression `expr`. This is only required in unsafe code where `expr`
99+
*implicitly uses* memory or other resources owned by one of the `x`s.
100+
101+
*Implicit use* of `x` covers any indirect use of resources logically owned by
102+
`x` which the compiler cannot see. Some examples:
103+
* Accessing memory of an object directly via a `Ptr`
104+
* Passing a pointer to `x` to `ccall`
105+
* Using resources of `x` which would be cleaned up in the finalizer.
106+
107+
`@preserve` should generally not have any performance impact in typical use
108+
cases where it briefly extends object lifetime. In implementation, `@preserve`
109+
has effects such as protecting dynamically allocated objects from garbage
110+
collection.
111+
112+
# Examples
113+
114+
When loading from a pointer with `unsafe_load`, the underlying object is
115+
implicitly used, for example `x` is implicitly used by `unsafe_load(p)` in the
116+
following:
117+
118+
```jldoctest
119+
julia> let
120+
x = Ref{Int}(101)
121+
p = Base.unsafe_convert(Ptr{Int}, x)
122+
GC.@preserve x unsafe_load(p)
123+
end
124+
101
125+
```
126+
127+
When passing pointers to `ccall`, the pointed-to object is implicitly used and
128+
should be preserved. (Note however that you should normally just pass `x`
129+
directly to `ccall` which counts as an explicit use.)
130+
131+
```jldoctest
132+
julia> let
133+
x = "Hello"
134+
p = pointer(x)
135+
GC.@preserve x @ccall strlen(p::Cstring)::Cint
136+
# Preferred alternative
137+
@ccall strlen(x::Cstring)::Cint
138+
end
139+
5
140+
```
141+
"""
142+
macro preserve(args...)
143+
syms = args[1:end-1]
144+
for x in syms
145+
isa(x, Symbol) || error("Preserved variable must be a symbol")
146+
end
147+
esc(Expr(:gc_preserve, args[end], syms...))
148+
end
149+
150+
"""
151+
GC.safepoint()
152+
153+
Inserts a point in the program where garbage collection may run.
154+
This can be useful in rare cases in multi-threaded programs where some threads
155+
are allocating memory (and hence may need to run GC) but other threads are doing
156+
only simple operations (no allocation, task switches, or I/O).
157+
Calling this function periodically in non-allocating threads allows garbage
158+
collection to run.
159+
160+
!!! compat "Julia 1.4"
161+
This function is available as of Julia 1.4.
162+
"""
163+
safepoint() = ccall(:jl_gc_safepoint, Cvoid, ())
164+
165+
end # module GC

0 commit comments

Comments
 (0)