Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

follow up #44448, correct findall/findsup for OverlayMethodTable #44511

Merged
merged 1 commit into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1482,11 +1482,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
nargtype = Tuple{ft, nargtype.parameters...}
argtype = Tuple{ft, argtype.parameters...}
result = findsup(types, method_table(interp))
result === nothing && return CallMeta(Any, false)
match, valid_worlds = result
method = match.method
match, valid_worlds = findsup(types, method_table(interp))
match === nothing && return CallMeta(Any, false)
update_valid_age!(sv, valid_worlds)
method = match.method
(ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
(; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv)
edge !== nothing && add_backedge!(edge::MethodInstance, sv)
Expand Down
46 changes: 25 additions & 21 deletions base/compiler/methodtable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,28 @@ given signature `sig`. If no applicable methods are found, an empty result is
returned. If the number of applicable methods exceeded the specified limit,
`missing` is returned.
"""
function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=typemax(Int))
function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=Int(typemax(Int32)))
return _findall(sig, nothing, table.world, limit)
end

function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int))
function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=Int(typemax(Int32)))
result = _findall(sig, table.mt, table.world, limit)
result === missing && return missing
if !isempty(result)
if all(match->match.fully_covers, result)
# no need to fall back to the internal method table
return result
else
# merge the match results with the internal method table
fallback_result = _findall(sig, nothing, table.world, limit)
return MethodLookupResult(
vcat(result.matches, fallback_result.matches),
WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world),
max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)),
result.ambig | fallback_result.ambig)
end
nr = length(result)
if nr ≥ 1 && result[nr].fully_covers
# no need to fall back to the internal method table
return result
end
# fall back to the internal method table
return _findall(sig, nothing, table.world, limit)
fallback_result = _findall(sig, nothing, table.world, limit)
fallback_result === missing && return missing
# merge the fallback match results with the internal method table
return MethodLookupResult(
vcat(result.matches, fallback_result.matches),
WorldRange(
max(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world),
min(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)),
result.ambig | fallback_result.ambig)
end

function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt, limit::Int)
Expand Down Expand Up @@ -102,17 +101,22 @@ function findsup(@nospecialize(sig::Type), table::InternalMethodTable)
end

function findsup(@nospecialize(sig::Type), table::OverlayMethodTable)
result = _findsup(sig, table.mt, table.world)
result === nothing || return result
return _findsup(sig, nothing, table.world) # fall back to the internal method table
match, valid_worlds = _findsup(sig, table.mt, table.world)
match !== nothing && return match, valid_worlds
# fall back to the internal method table
fallback_match, fallback_valid_worlds = _findsup(sig, nothing, table.world)
return fallback_match, WorldRange(
max(valid_worlds.min_world, fallback_valid_worlds.min_world),
min(valid_worlds.max_world, fallback_valid_worlds.max_world))
end

function _findsup(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt)
min_valid = RefValue{UInt}(typemin(UInt))
max_valid = RefValue{UInt}(typemax(UInt))
result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}),
match = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}),
sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing}
return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[]))
valid_worlds = WorldRange(min_valid[], max_valid[])
return match, valid_worlds
end

isoverlayed(::MethodTableView) = error("unsatisfied MethodTableView interface")
Expand Down
6 changes: 3 additions & 3 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1347,11 +1347,11 @@ end
print_statement_costs(args...; kwargs...) = print_statement_costs(stdout, args...; kwargs...)

function _which(@nospecialize(tt::Type), world=get_world_counter())
result = Core.Compiler._findsup(tt, nothing, world)
if result === nothing
match, _ = Core.Compiler._findsup(tt, nothing, world)
if match === nothing
error("no unique matching method found for the specified argument types")
end
return first(result)::Core.MethodMatch
return match
end

"""
Expand Down