@@ -26,20 +26,20 @@ function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{
26
26
# determine which CodeInstance objects are still valid in our image
27
27
# to enable any applicable new codes
28
28
backedges_only = unsafe_load (cglobal (:jl_first_image_replacement_world , UInt)) == typemax (UInt)
29
- methods_with_invalidated_source = Base. scan_new_methods (extext_methods, internal_methods, backedges_only)
29
+ Base. scan_new_methods! (extext_methods, internal_methods, backedges_only)
30
30
stack = CodeInstance[]
31
31
visiting = IdDict {CodeInstance,Int} ()
32
- _insert_backedges (edges, stack, visiting, methods_with_invalidated_source )
32
+ _insert_backedges (edges, stack, visiting)
33
33
if ext_ci_list != = nothing
34
- _insert_backedges (ext_ci_list, stack, visiting, methods_with_invalidated_source, #= external=# true )
34
+ _insert_backedges (ext_ci_list, stack, visiting, #= external=# true )
35
35
end
36
36
end
37
37
38
- function _insert_backedges (edges:: Vector{Any} , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , external:: Bool = false )
38
+ function _insert_backedges (edges:: Vector{Any} , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , external:: Bool = false )
39
39
for i = 1 : length (edges)
40
40
codeinst = edges[i]:: CodeInstance
41
41
validation_world = get_world_counter ()
42
- verify_method_graph (codeinst, stack, visiting, mwis, validation_world)
42
+ verify_method_graph (codeinst, stack, visiting, validation_world)
43
43
# After validation, under the world_counter_lock, set max_world to typemax(UInt) for all dependencies
44
44
# (recursively). From that point onward the ordinary backedge mechanism is responsible for maintaining
45
45
# validity.
@@ -63,16 +63,14 @@ function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visi
63
63
end
64
64
end
65
65
66
- function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , validation_world:: UInt )
66
+ function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world:: UInt )
67
67
@assert isempty (stack); @assert isempty (visiting);
68
- child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting, mwis, validation_world)
68
+ child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting, validation_world)
69
69
@assert child_cycle == 0
70
70
@assert isempty (stack); @assert isempty (visiting);
71
71
nothing
72
72
end
73
73
74
- get_require_world () = unsafe_load (cglobal (:jl_require_world , UInt))
75
-
76
74
function gen_staged_sig (def:: Method , mi:: MethodInstance )
77
75
isdefined (def, :generator ) || return nothing
78
76
isdispatchtuple (mi. specTypes) || return nothing
122
120
# - Visit the entire call graph, starting from edges[idx] to determine if that method is valid
123
121
# - Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable
124
122
# and slightly modified with an early termination option once the computation reaches its minimum
125
- function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , mwis :: IdSet{Method} , validation_world:: UInt )
123
+ function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world:: UInt )
126
124
world = codeinst. min_world
127
125
let max_valid2 = codeinst. max_world
128
126
if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL
@@ -136,13 +134,13 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
136
134
end
137
135
138
136
# Implicitly referenced bindings in the current module do not get explicit edges.
139
- # If they were invalidated, they'll be in `mwis` . If they weren't, they imply a minworld
137
+ # If they were invalidated, they'll have the flag set in did_scan_source . If they weren't, they imply a minworld
140
138
# of `get_require_world`. In principle, this is only required for methods that do reference
141
139
# an implicit globalref. However, we already don't perform this validation for methods that
142
140
# don't have any (implicit or explicit) edges at all. The remaining corner case (some explicit,
143
141
# but no implicit edges) is rare and there would be little benefit to lower the minworld for it
144
142
# in any case, so we just always use `get_require_world` here.
145
- local minworld:: UInt , maxworld:: UInt = get_require_world (), validation_world
143
+ local minworld:: UInt , maxworld:: UInt = Base . get_require_world (), validation_world
146
144
if haskey (visiting, codeinst)
147
145
return visiting[codeinst], minworld, maxworld
148
146
end
@@ -152,7 +150,11 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
152
150
# TODO JL_TIMING(VERIFY_IMAGE, VERIFY_Methods)
153
151
callees = codeinst. edges
154
152
# Check for invalidation of the implicit edges from GlobalRef in the Method source
155
- if def in mwis
153
+ if (def. did_scan_source & 0x1 ) == 0x0
154
+ backedges_only = unsafe_load (cglobal (:jl_first_image_replacement_world , UInt)) == typemax (UInt)
155
+ Base. scan_new_method! (def, backedges_only)
156
+ end
157
+ if (def. did_scan_source & 0x4 ) != 0x0
156
158
maxworld = 0
157
159
invalidations = _jl_debug_method_invalidation[]
158
160
if invalidations != = nothing
@@ -162,7 +164,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
162
164
# verify current edges
163
165
if isempty (callees)
164
166
# quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL)
165
- elseif maxworld == get_require_world ()
167
+ elseif maxworld == Base . get_require_world ()
166
168
# if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either
167
169
else
168
170
j = 1
@@ -240,7 +242,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
240
242
end
241
243
callee = edge
242
244
local min_valid2:: UInt , max_valid2:: UInt
243
- child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting, mwis, validation_world)
245
+ child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting, validation_world)
244
246
if minworld < min_valid2
245
247
minworld = min_valid2
246
248
end
0 commit comments