-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathinvalidations.jl
69 lines (65 loc) · 2.31 KB
/
invalidations.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""
@recompile_invalidations begin
using PkgA
⋮
end
Recompile any invalidations that occur within the given expression. This is generally intended to be used
by users in creating "Startup" packages to ensure that the code compiled by package authors is not invalidated.
"""
macro recompile_invalidations(expr)
# use QuoteNode instead of esc(Expr(:quote)) so that $ is not permitted as usual (instead of having this macro work like `@eval`)
return :(recompile_invalidations($__module__, $(QuoteNode(expr))))
end
function recompile_invalidations(__module__::Module, @nospecialize expr)
list = ccall(:jl_debug_method_invalidation, Any, (Cint,), 1)
try
Core.eval(__module__, expr)
finally
ccall(:jl_debug_method_invalidation, Any, (Cint,), 0)
end
if ccall(:jl_generating_output, Cint, ()) == 1
foreach(precompile_mi, invalidation_leaves(list))
end
nothing
end
function invalidation_leaves(invlist)
umis = Set{Core.MethodInstance}()
# `queued` is a queue of length 0 or 1 of invalidated MethodInstances.
# We wait to read the `depth` to find out if it's a leaf.
queued, depth = nothing, 0
function cachequeued(item, nextdepth)
if queued !== nothing && nextdepth <= depth
push!(umis, queued)
end
queued, depth = item, nextdepth
end
i, ilast = firstindex(invlist), lastindex(invlist)
while i <= ilast
item = invlist[i]
if isa(item, Core.MethodInstance)
if i < lastindex(invlist)
nextitem = invlist[i+1]
if nextitem == "invalidate_mt_cache"
cachequeued(nothing, 0)
i += 2
continue
end
if nextitem ∈ ("jl_method_table_disable", "jl_method_table_insert", "verify_methods")
cachequeued(nothing, 0)
push!(umis, item)
end
if isa(nextitem, Integer)
cachequeued(item, nextitem)
i += 2
continue
end
end
end
if (isa(item, Method) || isa(item, Type)) && queued !== nothing
push!(umis, queued)
queued, depth = nothing, 0
end
i += 1
end
return umis
end