Skip to content

Commit dacd16f

Browse files
authored
reflection: use a real world for lookups (#43695)
1 parent 7e5f691 commit dacd16f

File tree

6 files changed

+21
-18
lines changed

6 files changed

+21
-18
lines changed

base/reflection.jl

+9-8
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ function methods(@nospecialize(f), @nospecialize(t),
980980
throw(ArgumentError("argument is not a generic function"))
981981
end
982982
t = to_tuple_type(t)
983-
world = typemax(UInt)
983+
world = get_world_counter()
984984
# Lack of specialization => a comprehension triggers too many invalidations via _collect, so collect the methods manually
985985
ms = Method[]
986986
for m in _methods(f, t, -1, world)::Vector
@@ -995,7 +995,7 @@ methods(f::Core.Builtin) = MethodList(Method[], typeof(f).name.mt)
995995

996996
function methods_including_ambiguous(@nospecialize(f), @nospecialize(t))
997997
tt = signature_type(f, t)
998-
world = typemax(UInt)
998+
world = get_world_counter()
999999
min = RefValue{UInt}(typemin(UInt))
10001000
max = RefValue{UInt}(typemax(UInt))
10011001
ms = _methods_by_ftype(tt, nothing, -1, world, true, min, max, Ptr{Int32}(C_NULL))
@@ -1069,7 +1069,7 @@ _uncompressed_ir(ci::Core.CodeInstance, s::Array{UInt8,1}) = ccall(:jl_uncompres
10691069
const uncompressed_ast = uncompressed_ir
10701070
const _uncompressed_ast = _uncompressed_ir
10711071

1072-
function method_instances(@nospecialize(f), @nospecialize(t), world::UInt = typemax(UInt))
1072+
function method_instances(@nospecialize(f), @nospecialize(t), world::UInt=get_world_counter())
10731073
tt = signature_type(f, t)
10741074
results = Core.MethodInstance[]
10751075
for match in _methods_by_ftype(tt, -1, world)::Vector
@@ -1429,7 +1429,7 @@ function parentmodule(@nospecialize(f), @nospecialize(types))
14291429
end
14301430

14311431
"""
1432-
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=typemax(UInt)) -> Bool
1432+
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool
14331433
14341434
Determine whether the given generic function has a method matching the given
14351435
`Tuple` of argument types with the upper bound of world age given by `world`.
@@ -1464,13 +1464,13 @@ julia> hasmethod(g, Tuple{}, (:a, :b, :c, :d)) # g accepts arbitrary kwargs
14641464
true
14651465
```
14661466
"""
1467-
function hasmethod(@nospecialize(f), @nospecialize(t); world=typemax(UInt))
1467+
function hasmethod(@nospecialize(f), @nospecialize(t); world::UInt=get_world_counter())
14681468
t = to_tuple_type(t)
14691469
t = signature_type(f, t)
14701470
return ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), t, world) !== nothing
14711471
end
14721472

1473-
function hasmethod(@nospecialize(f), @nospecialize(t), kwnames::Tuple{Vararg{Symbol}}; world=typemax(UInt))
1473+
function hasmethod(@nospecialize(f), @nospecialize(t), kwnames::Tuple{Vararg{Symbol}}; world::UInt=get_world_counter())
14741474
# TODO: this appears to be doing the wrong queries
14751475
hasmethod(f, t, world=world) || return false
14761476
isempty(kwnames) && return true
@@ -1501,7 +1501,7 @@ function bodyfunction(basemethod::Method)
15011501
# %1 = mkw(kwvalues..., #self#, args...)
15021502
# return %1
15031503
# where `mkw` is the name of the "active" keyword body-function.
1504-
ast = Base.uncompressed_ast(basemethod)
1504+
ast = uncompressed_ast(basemethod)
15051505
f = nothing
15061506
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
15071507
callexpr = ast.code[end-1]
@@ -1570,10 +1570,11 @@ function isambiguous(m1::Method, m2::Method; ambiguous_bottom::Bool=false)
15701570
if !ambiguous_bottom
15711571
has_bottom_parameter(ti) && return false
15721572
end
1573+
world = get_world_counter()
15731574
min = UInt[typemin(UInt)]
15741575
max = UInt[typemax(UInt)]
15751576
has_ambig = Int32[0]
1576-
ms = _methods_by_ftype(ti, nothing, -1, typemax(UInt), true, min, max, has_ambig)::Vector
1577+
ms = _methods_by_ftype(ti, nothing, -1, world, true, min, max, has_ambig)::Vector
15771578
has_ambig[] == 0 && return false
15781579
if !ambiguous_bottom
15791580
filter!(ms) do m::Core.MethodMatch

stdlib/InteractiveUtils/src/codeview.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ function _dump_function(@nospecialize(f), @nospecialize(t), native::Bool, wrappe
149149
throw(ArgumentError("argument is not a generic function"))
150150
end
151151
# get the MethodInstance for the method match
152-
world = typemax(UInt)
152+
world = Base.get_world_counter()
153153
match = Base._which(signature_type(f, t), world)
154154
linfo = Core.Compiler.specialize_method(match)
155155
# get the code for it

stdlib/Test/src/Test.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -1704,9 +1704,10 @@ function detect_ambiguities(mods::Module...;
17041704
function examine(mt::Core.MethodTable)
17051705
for m in Base.MethodList(mt)
17061706
is_in_mods(m.module, recursive, mods) || continue
1707-
ambig = Int32[0]
1708-
ms = Base._methods_by_ftype(m.sig, nothing, -1, typemax(UInt), true, UInt[typemin(UInt)], UInt[typemax(UInt)], ambig)
1709-
ambig[1] == 0 && continue
1707+
world = Base.get_world_counter()
1708+
ambig = Ref{Int32}(0)
1709+
ms = Base._methods_by_ftype(m.sig, nothing, -1, world, true, Ref(typemin(UInt)), Ref(typemax(UInt)), ambig)
1710+
ambig[] == 0 && continue
17101711
isa(ms, Bool) && continue
17111712
for match2 in ms
17121713
match2 = match2::Core.MethodMatch
@@ -1761,7 +1762,8 @@ function detect_unbound_args(mods...;
17611762
if Base.isvatuple(tuple_sig)
17621763
params = tuple_sig.parameters[1:(end - 1)]
17631764
tuple_sig = Base.rewrap_unionall(Tuple{params...}, m.sig)
1764-
mf = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tuple_sig, typemax(UInt))
1765+
world = Base.get_world_counter()
1766+
mf = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tuple_sig, world)
17651767
if mf !== nothing && mf !== m && mf.sig <: tuple_sig
17661768
continue
17671769
end

test/compiler/contextual.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,13 @@ end
159159

160160
end
161161

162-
methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, nothing, 1, typemax(UInt))
162+
methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, nothing, 1, Base.get_world_counter())
163163
@test only(methods).method.module === Base.Math
164164

165-
methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, OverlayModule.mt, 1, typemax(UInt))
165+
methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, OverlayModule.mt, 1, Base.get_world_counter())
166166
@test only(methods).method.module === OverlayModule
167167

168-
methods = Base._methods_by_ftype(Tuple{typeof(sin), Int}, OverlayModule.mt, 1, typemax(UInt))
168+
methods = Base._methods_by_ftype(Tuple{typeof(sin), Int}, OverlayModule.mt, 1, Base.get_world_counter())
169169
@test isempty(methods)
170170

171171
# precompilation

test/compiler/inference.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ function get_linfo(@nospecialize(f), @nospecialize(t))
12321232
throw(ArgumentError("argument is not a generic function"))
12331233
end
12341234
# get the MethodInstance for the method match
1235-
match = Base._which(Base.signature_type(f, t), typemax(UInt))
1235+
match = Base._which(Base.signature_type(f, t), Base.get_world_counter())
12361236
precompile(match.spec_types)
12371237
return Core.Compiler.specialize_method(match)
12381238
end

test/compiler/validation.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function f22938(a, b, x...)
1919
end
2020

2121
msig = Tuple{typeof(f22938),Int,Int,Int,Int}
22-
world = typemax(UInt)
22+
world = Base.get_world_counter()
2323
match = Base._methods_by_ftype(msig, -1, world)[]
2424
mi = Core.Compiler.specialize_method(match)
2525
c0 = Core.Compiler.retrieve_code_info(mi)

0 commit comments

Comments
 (0)