3636function _insert_backedges (edges:: Vector{Any} , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , external:: Bool = false )
3737 for i = 1 : length (edges)
3838 codeinst = edges[i]:: CodeInstance
39- verify_method_graph (codeinst, stack, visiting)
39+ validation_world = get_world_counter ()
40+ verify_method_graph (codeinst, stack, visiting, validation_world)
41+ # After validation, under the world_counter_lock, set max_world to typemax(UInt) for all dependencies
42+ # (recursively). From that point onward the ordinary backedge mechanism is responsible for maintaining
43+ # validity.
44+ @ccall jl_promote_ci_to_current (codeinst:: Any , validation_world:: UInt ):: Cvoid
4045 minvalid = codeinst. min_world
4146 maxvalid = codeinst. max_world
47+ # Finally, if this CI is still valid in some world age and and belongs to an external method(specialization),
48+ # poke it that mi's cache
4249 if maxvalid ≥ minvalid && external
4350 caller = get_ci_mi (codeinst)
4451 @assert isdefined (codeinst, :inferred ) # See #53586, #53109
@@ -54,9 +61,9 @@ function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visi
5461 end
5562end
5663
57- function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} )
64+ function verify_method_graph (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world :: UInt )
5865 @assert isempty (stack); @assert isempty (visiting);
59- child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting)
66+ child_cycle, minworld, maxworld = verify_method (codeinst, stack, visiting, validation_world )
6067 @assert child_cycle == 0
6168 @assert isempty (stack); @assert isempty (visiting);
6269 nothing
6673# - Visit the entire call graph, starting from edges[idx] to determine if that method is valid
6774# - Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable
6875# and slightly modified with an early termination option once the computation reaches its minimum
69- function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} )
76+ function verify_method (codeinst:: CodeInstance , stack:: Vector{CodeInstance} , visiting:: IdDict{CodeInstance,Int} , validation_world :: UInt )
7077 world = codeinst. min_world
7178 let max_valid2 = codeinst. max_world
7279 if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL
7380 return 0 , world, max_valid2
7481 end
7582 end
76- current_world = get_world_counter ()
77- local minworld:: UInt , maxworld:: UInt = 1 , current_world
83+ local minworld:: UInt , maxworld:: UInt = 1 , validation_world
7884 @assert get_ci_mi (codeinst). def isa Method
7985 if haskey (visiting, codeinst)
8086 return visiting[codeinst], minworld, maxworld
@@ -156,7 +162,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
156162 end
157163 callee = edge
158164 local min_valid2:: UInt , max_valid2:: UInt
159- child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting)
165+ child_cycle, min_valid2, max_valid2 = verify_method (callee, stack, visiting, validation_world )
160166 if minworld < min_valid2
161167 minworld = min_valid2
162168 end
@@ -188,16 +194,14 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
188194 if maxworld ≠ 0
189195 @atomic :monotonic child. min_world = minworld
190196 end
191- if maxworld == current_world
197+ @atomic :monotonic child. max_world = maxworld
198+ if maxworld == validation_world && validation_world == get_world_counter ()
192199 Base. Compiler. store_backedges (child, child. edges)
193- @atomic :monotonic child. max_world = typemax (UInt)
194- else
195- @atomic :monotonic child. max_world = maxworld
196200 end
197201 @assert visiting[child] == length (stack) + 1
198202 delete! (visiting, child)
199203 invalidations = _jl_debug_method_invalidation[]
200- if invalidations != = nothing && maxworld < current_world
204+ if invalidations != = nothing && maxworld < validation_world
201205 push! (invalidations, child, " verify_methods" , cause)
202206 end
203207 end
0 commit comments