Skip to content

Commit 05b6e30

Browse files
committed
Propagate world age bounds from _methods_by_ftype.
1 parent be093cb commit 05b6e30

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

src/cache.jl

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,23 @@ end
4848
function get_world_generator(world::UInt, source, self, ::Type{Type{f}}, ::Type{Type{tt}}) where {f, tt}
4949
@nospecialize
5050

51-
# get a hold of the method and code info of the kernel function
51+
# look up the method
5252
sig = Tuple{f, tt.parameters...}
53-
mthds = _methods_by_ftype(sig, -1, world)
53+
min_world = Ref{UInt}(typemin(UInt))
54+
max_world = Ref{UInt}(typemax(UInt))
55+
has_ambig = Ptr{Int32}(C_NULL) # don't care about ambiguous results
56+
mthds = Base._methods_by_ftype(sig, #=mt=# nothing, #=lim=# -1,
57+
world, #=ambig=# false,
58+
min_world, max_world, has_ambig)
59+
# XXX: use the correct method table to support overlaying kernels
60+
61+
# check the validity of the method matches
5462
method_error = :(throw(MethodError(f, tt, $world)))
5563
mthds === nothing && return _generated_ex(world, source, method_error)
5664
Base.isdispatchtuple(tt) || return _generated_ex(world, source, :(error("$tt is not a dispatch tuple")))
5765
length(mthds) == 1 || return _generated_ex(world, source, method_error)
66+
67+
# look up the method and code instance
5868
mtypes, msp, m = mthds[1]
5969
mi = ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), m, mtypes, msp)
6070
ci = retrieve_code_info(mi, world)::CodeInfo
@@ -66,8 +76,8 @@ function get_world_generator(world::UInt, source, self, ::Type{Type{f}}, ::Type{
6676
resize!(new_ci.linetable, 1) # see note below
6777
empty!(new_ci.ssaflags)
6878
new_ci.ssavaluetypes = 0
69-
new_ci.min_world = world
70-
new_ci.max_world = typemax(UInt)
79+
new_ci.min_world = min_world[]
80+
new_ci.max_world = max_world[]
7181
new_ci.edges = MethodInstance[mi]
7282
# XXX: setting this edge does not give us proper method invalidation, see
7383
# JuliaLang/julia#34962 which demonstrates we also need to "call" the kernel.
@@ -105,14 +115,24 @@ else
105115
function get_world_generator(self, ::Type{Type{f}}, ::Type{Type{tt}}) where {f, tt}
106116
@nospecialize
107117

108-
# get a hold of the method and code info of the kernel function
118+
# look up the method
109119
sig = Tuple{f, tt.parameters...}
110-
# XXX: instead of typemax(UInt) we should use the world-age of the fspec
111-
mthds = _methods_by_ftype(sig, -1, typemax(UInt))
120+
min_world = Ref{UInt}(typemin(UInt))
121+
max_world = Ref{UInt}(typemax(UInt))
122+
has_ambig = Ptr{Int32}(C_NULL) # don't care about ambiguous results
123+
mthds = Base._methods_by_ftype(sig, #=mt=# nothing, #=lim=# -1,
124+
#=world=# typemax(UInt), #=ambig=# false,
125+
min_world, max_world, has_ambig)
126+
# XXX: using world=-1 is wrong, but the current world isn't exposed to this generator
127+
# XXX: use the correct method table to support overlaying kernels
128+
129+
# check the validity of the method matches
112130
method_error = :(throw(MethodError(f, tt)))
113131
mthds === nothing && return method_error
114132
Base.isdispatchtuple(tt) || return(:(error("$tt is not a dispatch tuple")))
115133
length(mthds) == 1 || return method_error
134+
135+
# look up the method and code instance
116136
mtypes, msp, m = mthds[1]
117137
mi = ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), m, mtypes, msp)
118138
ci = retrieve_code_info(mi)::CodeInfo
@@ -129,8 +149,8 @@ function get_world_generator(self, ::Type{Type{f}}, ::Type{Type{tt}}) where {f,
129149
resize!(new_ci.linetable, 1) # see note below
130150
empty!(new_ci.ssaflags)
131151
new_ci.ssavaluetypes = 0
132-
new_ci.min_world = world
133-
new_ci.max_world = typemax(UInt)
152+
new_ci.min_world = min_world[]
153+
new_ci.max_world = max_world[]
134154
new_ci.edges = MethodInstance[mi]
135155
# XXX: setting this edge does not give us proper method invalidation, see
136156
# JuliaLang/julia#34962 which demonstrates we also need to "call" the kernel.

0 commit comments

Comments
 (0)