@@ -17,20 +17,20 @@ function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{
17
17
# determine which CodeInstance objects are still valid in our image
18
18
# to enable any applicable new codes
19
19
backedges_only = unsafe_load (cglobal (:jl_first_image_replacement_world , UInt)) == typemax (UInt)
20
- methods_with_invalidated_source = Base. scan_new_methods (extext_methods, internal_methods, backedges_only)
20
+ Base. scan_new_methods! (extext_methods, internal_methods, backedges_only)
21
21
stack = CodeInstance[]
22
22
visiting = IdDict {CodeInstance,Int} ()
23
- _insert_backedges (edges, stack, visiting, methods_with_invalidated_source )
23
+ _insert_backedges (edges, stack, visiting)
24
24
if ext_ci_list != = nothing
25
- _insert_backedges (ext_ci_list, stack, visiting, methods_with_invalidated_source, #= external=# true )
25
+ _insert_backedges (ext_ci_list, stack, visiting, #= external=# true )
26
26
end
27
27
end
28
28
29
- function _insert_backedges (edges:: Vector{Any} , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , external:: Bool = false )
29
+ function _insert_backedges (edges:: Vector{Any} , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , external:: Bool = false )
30
30
for i = 1 : length (edges)
31
31
codeinst = edges[i]:: CodeInstance
32
32
validation_world = get_world_counter ()
33
- verify_method_graph (codeinst, stack, visiting, mwis, validation_world)
33
+ verify_method_graph (codeinst, stack, visiting, validation_world)
34
34
# After validation, under the world_counter_lock, set max_world to typemax(UInt) for all dependencies
35
35
# (recursively). From that point onward the ordinary backedge mechanism is responsible for maintaining
36
36
# validity.
@@ -54,16 +54,14 @@ function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visi
54
54
end
55
55
end
56
56
57
- function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , validation_world:: UInt )
57
+ function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world:: UInt )
58
58
@assert isempty (stack); @assert isempty (visiting);
59
- child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting, mwis, validation_world)
59
+ child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting, validation_world)
60
60
@assert child_cycle == 0
61
61
@assert isempty (stack); @assert isempty (visiting);
62
62
nothing
63
63
end
64
64
65
- get_require_world () = unsafe_load (cglobal (:jl_require_world , UInt))
66
-
67
65
function gen_staged_sig (def:: Method , mi:: MethodInstance )
68
66
isdefined (def, :generator ) || return nothing
69
67
isdispatchtuple (mi. specTypes) || return nothing
113
111
# - Visit the entire call graph, starting from edges[idx] to determine if that method is valid
114
112
# - Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable
115
113
# and slightly modified with an early termination option once the computation reaches its minimum
116
- function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , validation_world:: UInt )
114
+ function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world:: UInt )
117
115
world = codeinst. min_world
118
116
let max_valid2 = codeinst. max_world
119
117
if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL
@@ -127,13 +125,13 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
127
125
end
128
126
129
127
# Implicitly referenced bindings in the current module do not get explicit edges.
130
- # If they were invalidated, they'll be in `mwis` . If they weren't, they imply a minworld
128
+ # If they were invalidated, they'll have the flag set in did_scan_source . If they weren't, they imply a minworld
131
129
# of `get_require_world`. In principle, this is only required for methods that do reference
132
130
# an implicit globalref. However, we already don't perform this validation for methods that
133
131
# don't have any (implicit or explicit) edges at all. The remaining corner case (some explicit,
134
132
# but no implicit edges) is rare and there would be little benefit to lower the minworld for it
135
133
# in any case, so we just always use `get_require_world` here.
136
- local minworld:: UInt , maxworld:: UInt = get_require_world (), validation_world
134
+ local minworld:: UInt , maxworld:: UInt = Base . get_require_world (), validation_world
137
135
if haskey (visiting, codeinst)
138
136
return visiting[codeinst], minworld, maxworld
139
137
end
@@ -143,7 +141,11 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
143
141
# TODO JL_TIMING(VERIFY_IMAGE, VERIFY_Methods)
144
142
callees = codeinst. edges
145
143
# Check for invalidation of the implicit edges from GlobalRef in the Method source
146
- if def in mwis
144
+ if (def. did_scan_source & 0x1 ) == 0x0
145
+ backedges_only = unsafe_load (cglobal (:jl_first_image_replacement_world , UInt)) == typemax (UInt)
146
+ Base. scan_new_method! (def, backedges_only)
147
+ end
148
+ if (def. did_scan_source & 0x4 ) != 0x0
147
149
maxworld = 0
148
150
invalidations = _jl_debug_method_invalidation[]
149
151
if invalidations != = nothing
@@ -153,7 +155,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
153
155
# verify current edges
154
156
if isempty (callees)
155
157
# quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL)
156
- elseif maxworld == get_require_world ()
158
+ elseif maxworld == Base . get_require_world ()
157
159
# if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either
158
160
else
159
161
j = 1
@@ -231,7 +233,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
231
233
end
232
234
callee = edge
233
235
local min_valid2:: UInt , max_valid2:: UInt
234
- child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting, mwis, validation_world)
236
+ child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting, validation_world)
235
237
if minworld < min_valid2
236
238
minworld = min_valid2
237
239
end
0 commit comments