@@ -13,7 +13,7 @@ tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ())
13
13
14
14
export methodinstance
15
15
16
- @inline function typed_signature (ft:: Type , tt:: Type )
16
+ @inline function signature_type_by_tt (ft:: Type , tt:: Type )
17
17
u = Base. unwrap_unionall (tt)
18
18
return Base. rewrap_unionall (Tuple{ft, u. parameters... }, tt)
19
19
end
49
49
Look up the method instance that corresponds to invoking the function with type `ft` with
50
50
argument typed `tt`. If the `world` argument is specified, the look-up is static and will
51
51
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.
54
55
55
56
If the method is not found, a `MethodError` is thrown.
56
57
"""
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
+
57
79
function methodinstance (ft:: Type , tt:: Type , world:: Integer )
58
- sig = typed_signature (ft, tt)
80
+ sig = signature_type_by_tt (ft, tt)
59
81
60
82
match, _ = CC. _findsup (sig, nothing , world)
61
83
match === nothing && throw (MethodError (ft, tt, world))
@@ -65,10 +87,10 @@ function methodinstance(ft::Type, tt::Type, world::Integer)
65
87
return mi:: MethodInstance
66
88
end
67
89
68
- if VERSION >= v " 1.10.0-DEV.873"
69
-
70
90
# on 1.10 (JuliaLang/julia#48611) generated functions know which world to generate code for.
71
91
# 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"
72
94
73
95
function methodinstance_generator (world:: UInt , source, self, ft:: Type , tt:: Type )
74
96
@nospecialize
@@ -125,15 +147,15 @@ end
125
147
$ (Expr (:meta , :generated , methodinstance_generator))
126
148
end
127
149
150
+ # on really old versions, we can't cache the run-time lookup
128
151
else
129
152
130
- # on older versions of Julia we have to fall back to a run-time lookup.
131
- # this is slower, and allocates.
132
-
133
153
methodinstance (f, tt) = methodinstance (f, tt, tls_world_age ())
134
154
135
155
end
136
156
157
+ end
158
+
137
159
138
160
# # code instance cache
139
161
0 commit comments