Skip to content

Commit 04e2b85

Browse files
committed
Propagate world age bounds from _methods_by_ftype.
1 parent be093cb commit 04e2b85

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

src/cache.jl

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,29 @@ 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 = if VERSION >= v"1.7.0-DEV.1297"
57+
Base._methods_by_ftype(sig, #=mt=# nothing, #=lim=# -1,
58+
world, #=ambig=# false,
59+
min_world, max_world, has_ambig)
60+
# XXX: use the correct method table to support overlaying kernels
61+
else
62+
Base._methods_by_ftype(sig, #=lim=# -1,
63+
world, #=ambig=# false,
64+
min_world, max_world, has_ambig)
65+
end
66+
67+
# check the validity of the method matches
5468
method_error = :(throw(MethodError(f, tt, $world)))
5569
mthds === nothing && return _generated_ex(world, source, method_error)
5670
Base.isdispatchtuple(tt) || return _generated_ex(world, source, :(error("$tt is not a dispatch tuple")))
5771
length(mthds) == 1 || return _generated_ex(world, source, method_error)
72+
73+
# look up the method and code instance
5874
mtypes, msp, m = mthds[1]
5975
mi = ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), m, mtypes, msp)
6076
ci = retrieve_code_info(mi, world)::CodeInfo
@@ -66,8 +82,8 @@ function get_world_generator(world::UInt, source, self, ::Type{Type{f}}, ::Type{
6682
resize!(new_ci.linetable, 1) # see note below
6783
empty!(new_ci.ssaflags)
6884
new_ci.ssavaluetypes = 0
69-
new_ci.min_world = world
70-
new_ci.max_world = typemax(UInt)
85+
new_ci.min_world = min_world[]
86+
new_ci.max_world = max_world[]
7187
new_ci.edges = MethodInstance[mi]
7288
# XXX: setting this edge does not give us proper method invalidation, see
7389
# JuliaLang/julia#34962 which demonstrates we also need to "call" the kernel.
@@ -105,14 +121,30 @@ else
105121
function get_world_generator(self, ::Type{Type{f}}, ::Type{Type{tt}}) where {f, tt}
106122
@nospecialize
107123

108-
# get a hold of the method and code info of the kernel function
124+
# look up the method
109125
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))
126+
min_world = Ref{UInt}(typemin(UInt))
127+
max_world = Ref{UInt}(typemax(UInt))
128+
has_ambig = Ptr{Int32}(C_NULL) # don't care about ambiguous results
129+
mthds = if VERSION >= v"1.7.0-DEV.1297"
130+
Base._methods_by_ftype(sig, #=mt=# nothing, #=lim=# -1,
131+
#=world=# typemax(UInt), #=ambig=# false,
132+
min_world, max_world, has_ambig)
133+
# XXX: use the correct method table to support overlaying kernels
134+
else
135+
Base._methods_by_ftype(sig, #=lim=# -1,
136+
#=world=# typemax(UInt), #=ambig=# false,
137+
min_world, max_world, has_ambig)
138+
end
139+
# XXX: using world=-1 is wrong, but the current world isn't exposed to this generator
140+
141+
# check the validity of the method matches
112142
method_error = :(throw(MethodError(f, tt)))
113143
mthds === nothing && return method_error
114144
Base.isdispatchtuple(tt) || return(:(error("$tt is not a dispatch tuple")))
115145
length(mthds) == 1 || return method_error
146+
147+
# look up the method and code instance
116148
mtypes, msp, m = mthds[1]
117149
mi = ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), m, mtypes, msp)
118150
ci = retrieve_code_info(mi)::CodeInfo
@@ -129,8 +161,8 @@ function get_world_generator(self, ::Type{Type{f}}, ::Type{Type{tt}}) where {f,
129161
resize!(new_ci.linetable, 1) # see note below
130162
empty!(new_ci.ssaflags)
131163
new_ci.ssavaluetypes = 0
132-
new_ci.min_world = world
133-
new_ci.max_world = typemax(UInt)
164+
new_ci.min_world = min_world[]
165+
new_ci.max_world = max_world[]
134166
new_ci.edges = MethodInstance[mi]
135167
# XXX: setting this edge does not give us proper method invalidation, see
136168
# JuliaLang/julia#34962 which demonstrates we also need to "call" the kernel.

0 commit comments

Comments
 (0)