Skip to content

Commit 8c5d6ac

Browse files
authored
Use the new jl_method_lookup_by_tt API on 1.11. (#550)
1 parent 3146658 commit 8c5d6ac

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

src/jlgen.jl

+31-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ())
1313

1414
export methodinstance
1515

16-
@inline function typed_signature(ft::Type, tt::Type)
16+
@inline function signature_type_by_tt(ft::Type, tt::Type)
1717
u = Base.unwrap_unionall(tt)
1818
return Base.rewrap_unionall(Tuple{ft, u.parameters...}, tt)
1919
end
@@ -49,13 +49,35 @@ end
4949
Look up the method instance that corresponds to invoking the function with type `ft` with
5050
argument typed `tt`. If the `world` argument is specified, the look-up is static and will
5151
always return the same result. If the `world` argument is not specified, the look-up is
52-
dynamic and the returned method instance will automatically be invalidated when a relevant
53-
function is redefined.
52+
dynamic and the returned method instance will depende on the current world age.
53+
54+
This call is highly optimized, and does not need to be cached additionally.
5455
5556
If the method is not found, a `MethodError` is thrown.
5657
"""
58+
methodinstance
59+
60+
# on 1.11 (JuliaLang/julia#52572, merged as part of JuliaLang/julia#52233) we can use
61+
# Julia's cached method lookup to simply look up method instances at run time.
62+
if VERSION >= v"1.11.0-DEV.1552"
63+
64+
# XXX: version of Base.method_instance that uses a function type
65+
function methodinstance(ft, tt, world=tls_world_age())
66+
sig = signature_type_by_tt(ft, tt)
67+
68+
mi = ccall(:jl_method_lookup_by_tt, Any,
69+
(Any, Csize_t, Any),
70+
sig, world, #=method_table=# nothing)
71+
mi === nothing && throw(MethodError(ft, tt, world))
72+
73+
return mi::MethodInstance
74+
end
75+
76+
# on older versions of Julia, the run-time lookup is much slower, so we'll need to cache it
77+
else
78+
5779
function methodinstance(ft::Type, tt::Type, world::Integer)
58-
sig = typed_signature(ft, tt)
80+
sig = signature_type_by_tt(ft, tt)
5981

6082
match, _ = CC._findsup(sig, nothing, world)
6183
match === nothing && throw(MethodError(ft, tt, world))
@@ -65,10 +87,10 @@ function methodinstance(ft::Type, tt::Type, world::Integer)
6587
return mi::MethodInstance
6688
end
6789

68-
if VERSION >= v"1.10.0-DEV.873"
69-
7090
# on 1.10 (JuliaLang/julia#48611) generated functions know which world to generate code for.
7191
# we can use this to cache and automatically invalidate method instance look-ups.
92+
# this isn't perfect, see e.g. JuliaGPU/GPUCompiler.jl#530.
93+
if VERSION >= v"1.10.0-DEV.873"
7294

7395
function methodinstance_generator(world::UInt, source, self, ft::Type, tt::Type)
7496
@nospecialize
@@ -125,15 +147,15 @@ end
125147
$(Expr(:meta, :generated, methodinstance_generator))
126148
end
127149

150+
# on really old versions, we can't cache the run-time lookup
128151
else
129152

130-
# on older versions of Julia we have to fall back to a run-time lookup.
131-
# this is slower, and allocates.
132-
133153
methodinstance(f, tt) = methodinstance(f, tt, tls_world_age())
134154

135155
end
136156

157+
end
158+
137159

138160
## code instance cache
139161

0 commit comments

Comments
 (0)