@@ -49,6 +49,7 @@ type InferenceState
4949
5050 # info on the state of inference and the linfo
5151 linfo:: LambdaInfo
52+ world:: UInt
5253 nargs:: Int
5354 stmt_types:: Vector{Any}
5455 # return type
@@ -75,7 +76,7 @@ type InferenceState
7576 optimize:: Bool
7677 inferred:: Bool
7778
78- function InferenceState (linfo:: LambdaInfo , optimize:: Bool )
79+ function InferenceState (linfo:: LambdaInfo , world :: UInt , optimize:: Bool )
7980 @assert isa (linfo. code,Array{Any,1 })
8081 nslots = length (linfo. slotnames)
8182 nl = label_counter (linfo. code)+ 1
@@ -155,7 +156,7 @@ type InferenceState
155156 inmodule = isdefined (linfo, :def ) ? linfo. def. module : current_module () # toplevel thunks are inferred in the current module
156157 frame = new (
157158 sp, nl, Dict {SSAValue, Bool} (), inmodule, 0 , false ,
158- linfo, la, s, Union{}, W, n,
159+ linfo, world, la, s, Union{}, W, n,
159160 cur_hand, handler_at, n_handlers,
160161 ssavalue_uses, ssavalue_init,
161162 ObjectIdDict (), # Dict{InferenceState, Vector{LineNum}}(),
@@ -607,14 +608,14 @@ function invoke_tfunc(f::ANY, types::ANY, argtype::ANY, sv::InferenceState)
607608 ft = type_typeof (f)
608609 types = Tuple{ft, types. parameters... }
609610 argtype = Tuple{ft, argtype. parameters... }
610- entry = ccall (:jl_gf_invoke_lookup , Any, (Any,), types)
611+ entry = ccall (:jl_gf_invoke_lookup , Any, (Any, UInt ), types, sv . world )
611612 if is (entry, nothing )
612613 return Any
613614 end
614615 meth = entry. func
615616 (ti, env) = ccall (:jl_match_method , Any, (Any, Any, Any),
616617 argtype, meth. sig, meth. tvars):: SimpleVector
617- return typeinf_edge (meth:: Method , ti, env, sv)[2 ]
618+ return typeinf_edge (meth:: Method , ti, env, sv, sv . world )[2 ]
618619end
619620
620621function tuple_tfunc (argtype:: ANY )
@@ -842,7 +843,7 @@ function abstract_call_gf_by_type(f::ANY, argtype::ANY, sv)
842843 end
843844 end
844845 # print(m,"\n")
845- (_tree, rt) = typeinf_edge (method, sig, m[2 ], sv)
846+ (_tree, rt) = typeinf_edge (method, sig, m[2 ], sv, sv . world )
846847 rettype = tmerge (rettype, rt)
847848 if is (rettype,Any)
848849 break
@@ -1384,9 +1385,9 @@ function newvar!(sv::InferenceState, typ)
13841385end
13851386
13861387# create a specialized LambdaInfo from a method
1387- function specialize_method (method:: Method , types:: ANY , sp:: SimpleVector , cached)
1388+ function specialize_method (method:: Method , types:: ANY , sp:: SimpleVector , cached, world )
13881389 if cached
1389- return ccall (:jl_specializations_get_linfo , Ref{LambdaInfo}, (Any, Any, Any), method, types, sp)
1390+ return ccall (:jl_specializations_get_linfo , Ref{LambdaInfo}, (Any, Any, Any, UInt ), method, types, sp, world )
13901391 else
13911392 return ccall (:jl_get_specialized , Ref{LambdaInfo}, (Any, Any, Any), method, types, sp)
13921393 end
@@ -1408,16 +1409,24 @@ function unshare_linfo!(li::LambdaInfo)
14081409end
14091410
14101411# ### entry points for inferring a LambdaInfo given a type signature ####
1411- function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool , optimize:: Bool , cached:: Bool , caller)
1412+ let _min_age = Symbol (" min-age" ), _max_age = Symbol (" max-age" )
1413+ global min_age (m:: Method ) = getfield (m, _min_age) % UInt
1414+ global max_age (m:: Method ) = getfield (m, _max_age) % UInt
1415+ end
1416+ function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool , optimize:: Bool , cached:: Bool , caller, world:: UInt )
14121417 local code = nothing
14131418 local frame = nothing
1419+ if world < min_age (method) || world > max_age (method)
1420+ ccall (:jl_breakpoint , Void, (Any,), (method, world))
1421+ return (nothing , Union{}, false )
1422+ end
14141423 if isa (caller, LambdaInfo)
14151424 code = caller
14161425 elseif cached
14171426 # check cached specializations
14181427 # for an existing result stored there
14191428 if ! is (method. specializations, nothing )
1420- code = ccall (:jl_specializations_lookup , Any, (Any, Any), method, atypes)
1429+ code = ccall (:jl_specializations_lookup , Any, (Any, Any, UInt ), method, atypes, world )
14211430 if isa (code, Void)
14221431 # something completely new
14231432 elseif isa (code, LambdaInfo)
@@ -1479,12 +1488,12 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14791488 end
14801489 try
14811490 # user code might throw errors – ignore them
1482- linfo = specialize_method (method, atypes, sparams, cached)
1491+ linfo = specialize_method (method, atypes, sparams, cached, world )
14831492 catch
14841493 return (nothing , Any, false )
14851494 end
14861495 else
1487- linfo = specialize_method (method, atypes, sparams, cached)
1496+ linfo = specialize_method (method, atypes, sparams, cached, world )
14881497 end
14891498
14901499 if linfo. inInference
@@ -1503,7 +1512,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15031512 else
15041513 # inference not started yet, make a new frame for a new lambda
15051514 linfo. inInference = true
1506- frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), optimize)
1515+ frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), world, optimize)
15071516 end
15081517 frame = frame:: InferenceState
15091518
@@ -1527,24 +1536,25 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15271536 return (frame. linfo, frame. bestguess, frame. inferred)
15281537end
15291538
1530- function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , caller)
1531- return typeinf_edge (method, atypes, sparams, false , true , true , caller)
1539+ world_counter () = ccall (:jl_get_world_counter , UInt, ())
1540+ function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , caller:: InferenceState , world:: UInt )
1541+ return typeinf_edge (method, atypes, sparams, false , true , true , caller, world)
15321542end
15331543function typeinf (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool = false )
1534- return typeinf_edge (method, atypes, sparams, needtree, true , true , nothing )
1544+ return typeinf_edge (method, atypes, sparams, needtree, true , true , nothing , world_counter () )
15351545end
15361546# compute an inferred (optionally optimized) AST without global effects (i.e. updating the cache)
15371547function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: ANY ; optimize:: Bool = true )
1538- return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing )
1548+ return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing , world_counter () )
15391549end
15401550function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: SimpleVector , optimize:: Bool )
1541- return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing )
1551+ return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing , world_counter () )
15421552end
1543- function typeinf_ext (linfo:: LambdaInfo )
1553+ function typeinf_ext (linfo:: LambdaInfo , world :: UInt )
15441554 if isdefined (linfo, :def )
15451555 # method lambda - infer this specialization via the method cache
1546- (code, _t, _ ) = typeinf_edge (linfo. def, linfo. specTypes, linfo. sparam_vals, true , true , true , linfo)
1547- if code. inferred && linfo != = code
1556+ (code, _t, inferred ) = typeinf_edge (linfo. def, linfo. specTypes, linfo. sparam_vals, true , true , true , linfo, world )
1557+ if inferred && code. inferred && linfo != = code
15481558 # This case occurs when the IR for a function has been deleted.
15491559 # `code` will be a newly-created LambdaInfo, and we need to copy its
15501560 # contents to the existing one to copy the info to the method cache.
@@ -1564,7 +1574,7 @@ function typeinf_ext(linfo::LambdaInfo)
15641574 else
15651575 # toplevel lambda - infer directly
15661576 linfo. inInference = true
1567- frame = InferenceState (linfo, true )
1577+ frame = InferenceState (linfo, world, true )
15681578 typeinf_loop (frame)
15691579 @assert frame. inferred # TODO : deal with this better
15701580 return linfo
@@ -2342,7 +2352,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
23422352 end
23432353 function invoke_NF ()
23442354 # converts a :call to :invoke
2345- cache_linfo = ccall (:jl_get_spec_lambda , Any, (Any,), atype_unlimited)
2355+ cache_linfo = ccall (:jl_get_spec_lambda , Any, (Any, UInt ), atype_unlimited, sv . world )
23462356 if cache_linfo != = nothing
23472357 e. head = :invoke
23482358 unshift! (e. args, cache_linfo)
0 commit comments