|
2 | 2 |
|
3 | 3 | using ..Compiler.Base
|
4 | 4 | using ..Compiler: _findsup, store_backedges, JLOptions, get_world_counter,
|
5 |
| - _methods_by_ftype, get_methodtable, get_ci_mi, should_instrument, |
| 5 | + _methods_by_ftype, get_methodtable, get_ci_mi, ci_has_abi, should_instrument, |
6 | 6 | morespecific, RefValue, get_require_world, Vector, IdDict
|
7 | 7 | using .Core: CodeInstance, MethodInstance
|
8 | 8 |
|
|
69 | 69 | # Restore backedges to external targets
|
70 | 70 | # `edges` = [caller1, ...], the list of worklist-owned code instances internally
|
71 | 71 | # `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally
|
72 |
| -function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{Any}}, extext_methods::Vector{Any}, internal_methods::Vector{Any}) |
| 72 | +function insert_backedges(ext_ci_list::Union{Nothing,Vector{Any}}, internal_methods::Vector{Any}) |
73 | 73 | # determine which CodeInstance objects are still valid in our image
|
74 | 74 | # to enable any applicable new codes
|
75 | 75 | backedges_only = unsafe_load(cglobal(:jl_first_image_replacement_world, UInt)) == typemax(UInt)
|
76 |
| - scan_new_methods!(extext_methods, internal_methods, backedges_only) |
| 76 | + scan_new_methods!(internal_methods, backedges_only) |
77 | 77 | workspace = VerifyMethodWorkspace()
|
78 |
| - _insert_backedges(edges, workspace) |
| 78 | + scan_new_code!(internal_methods, workspace) |
79 | 79 | if ext_ci_list !== nothing
|
80 |
| - _insert_backedges(ext_ci_list, workspace, #=external=#true) |
| 80 | + insert_ext_cache(ext_ci_list) |
81 | 81 | end
|
| 82 | + nothing |
82 | 83 | end
|
83 | 84 |
|
84 |
| -function _insert_backedges(edges::Vector{Any}, workspace::VerifyMethodWorkspace, external::Bool=false) |
85 |
| - for i = 1:length(edges) |
86 |
| - codeinst = edges[i]::CodeInstance |
| 85 | +function scan_new_code!(internal_methods::Vector{Any}, workspace::VerifyMethodWorkspace) |
| 86 | + for i = 1:length(internal_methods) |
| 87 | + codeinst = internal_methods[i] |
| 88 | + codeinst isa CodeInstance || continue |
| 89 | + # codeinst.owner === nothing || continue |
87 | 90 | validation_world = get_world_counter()
|
88 | 91 | verify_method_graph(codeinst, validation_world, workspace)
|
89 | 92 | # After validation, under the world_counter_lock, set max_world to typemax(UInt) for all dependencies
|
90 | 93 | # (recursively). From that point onward the ordinary backedge mechanism is responsible for maintaining
|
91 | 94 | # validity.
|
92 | 95 | @ccall jl_promote_ci_to_current(codeinst::Any, validation_world::UInt)::Cvoid
|
| 96 | + end |
| 97 | +end |
| 98 | + |
| 99 | +function insert_ext_cache(edges::Vector{Any}) |
| 100 | + for i = 1:length(edges) |
| 101 | + codeinst = edges[i]::CodeInstance |
93 | 102 | minvalid = codeinst.min_world
|
94 | 103 | maxvalid = codeinst.max_world
|
95 | 104 | # Finally, if this CI is still valid in some world age and belongs to an external method(specialization),
|
96 |
| - # poke it that mi's cache |
97 |
| - if maxvalid ≥ minvalid && external |
| 105 | + # poke it in that mi's cache, unless there is already one there that has an invoke pointer |
| 106 | + if maxvalid ≥ minvalid |
98 | 107 | caller = get_ci_mi(codeinst)
|
99 | 108 | @assert isdefined(codeinst, :inferred) # See #53586, #53109
|
100 | 109 | inferred = @ccall jl_rettype_inferred(
|
101 | 110 | codeinst.owner::Any, caller::Any, minvalid::UInt, maxvalid::UInt)::Any
|
102 |
| - if inferred !== nothing |
| 111 | + if inferred !== nothing && (ci_has_abi(inferred::CodeInstance) || !ci_has_abi(codeinst)) |
103 | 112 | # We already got a code instance for this world age range from
|
104 | 113 | # somewhere else - we don't need this one.
|
105 | 114 | else
|
@@ -658,7 +667,7 @@ function verify_invokesig(@nospecialize(invokesig), expected::Method, world::UIn
|
658 | 667 | end
|
659 | 668 |
|
660 | 669 | # Wrapper to call insert_backedges in typeinf_world for external calls
|
661 |
| -function insert_backedges_typeinf(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{Any}}, extext_methods::Vector{Any}, internal_methods::Vector{Any}) |
662 |
| - args = Any[insert_backedges, edges, ext_ci_list, extext_methods, internal_methods] |
| 670 | +function insert_backedges_typeinf(ext_ci_list::Union{Nothing,Vector{Any}}, internal_methods::Vector{Any}) |
| 671 | + args = Any[insert_backedges, ext_ci_list, internal_methods] |
663 | 672 | return ccall(:jl_call_in_typeinf_world, Any, (Ptr{Any}, Cint), args, length(args))
|
664 | 673 | end
|
0 commit comments