Skip to content

Commit e2c8809

Browse files
authored
Disambiguate get_world_counter and get_inference_world (#53088)
Add brief docs to `Base.get_world_counter` and add `Base.tls_wold_age`. Furthermore to disambiguate `get_world_counter` from the inference world rename the abstract interpreter accessor to `get_inference_world`
1 parent d24316a commit e2c8809

File tree

15 files changed

+47
-26
lines changed

15 files changed

+47
-26
lines changed

base/boot.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ struct Pair{A, B}
958958
end
959959

960960
function _hasmethod(@nospecialize(tt)) # this function has a special tfunc
961-
world = ccall(:jl_get_tls_world_age, UInt, ())
961+
world = ccall(:jl_get_tls_world_age, UInt, ()) # tls_world_age()
962962
return Intrinsics.not_int(ccall(:jl_gf_invoke_lookup, Any, (Any, Any, UInt), tt, nothing, world) === nothing)
963963
end
964964

base/compiler/abstractinterpretation.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ function edge_matches_sv(interp::AbstractInterpreter, frame::AbsIntState,
681681
# necessary in order to retrieve this field from the generated `CodeInfo`, if it exists.
682682
# The other `CodeInfo`s we inspect will already have this field inflated, so we just
683683
# access it directly instead (to avoid regeneration).
684-
world = get_world_counter(interp)
684+
world = get_inference_world(interp)
685685
callee_method2 = method_for_inference_heuristics(method, sig, sparams, world) # Union{Method, Nothing}
686686

687687
inf_method2 = method_for_inference_limit_heuristics(frame) # limit only if user token match
@@ -935,7 +935,7 @@ function concrete_eval_call(interp::AbstractInterpreter,
935935
pushfirst!(args, f, invokecall.types)
936936
f = invoke
937937
end
938-
world = get_world_counter(interp)
938+
world = get_inference_world(interp)
939939
edge = result.edge::MethodInstance
940940
value = try
941941
Core._call_in_world_total(world, f, args...)

base/compiler/inferencestate.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,10 @@ mutable struct InferenceState
277277
function InferenceState(result::InferenceResult, src::CodeInfo, cache_mode::UInt8,
278278
interp::AbstractInterpreter)
279279
linfo = result.linfo
280-
world = get_world_counter(interp)
280+
world = get_inference_world(interp)
281+
if world == typemax(UInt)
282+
error("Entering inference from a generated function with an invalid world")
283+
end
281284
def = linfo.def
282285
mod = isa(def, Method) ? def.module : def
283286
sptypes = sptypes_from_meth_instance(linfo)
@@ -487,7 +490,7 @@ end
487490

488491
function InferenceState(result::InferenceResult, cache_mode::UInt8, interp::AbstractInterpreter)
489492
# prepare an InferenceState object for inferring lambda
490-
world = get_world_counter(interp)
493+
world = get_inference_world(interp)
491494
src = retrieve_code_info(result.linfo, world)
492495
src === nothing && return nothing
493496
maybe_validate_code(result.linfo, src, "lowered")

base/compiler/optimize.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function InliningState(sv::InferenceState, interp::AbstractInterpreter)
134134
return InliningState(edges, sv.world, interp)
135135
end
136136
function InliningState(interp::AbstractInterpreter)
137-
return InliningState(Any[], get_world_counter(interp), interp)
137+
return InliningState(Any[], get_inference_world(interp), interp)
138138
end
139139

140140
# get `code_cache(::AbstractInterpreter)` from `state::InliningState`
@@ -193,7 +193,7 @@ function OptimizationState(linfo::MethodInstance, src::CodeInfo, interp::Abstrac
193193
return OptimizationState(linfo, src, nothing, stmt_info, mod, sptypes, slottypes, inlining, cfg, unreachable, bb_vartables, false)
194194
end
195195
function OptimizationState(linfo::MethodInstance, interp::AbstractInterpreter)
196-
world = get_world_counter(interp)
196+
world = get_inference_world(interp)
197197
src = retrieve_code_info(linfo, world)
198198
src === nothing && return nothing
199199
return OptimizationState(linfo, src, interp)

base/compiler/ssair/irinterp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function concrete_eval_invoke(interp::AbstractInterpreter,
1717
if (is_foldable(effects) && is_all_const_arg(argtypes, #=start=#1) &&
1818
(is_nonoverlayed(interp) || is_nonoverlayed(effects)))
1919
args = collect_const_args(argtypes, #=start=#1)
20-
value = let world = get_world_counter(interp)
20+
value = let world = get_inference_world(interp)
2121
try
2222
Core._call_in_world_total(world, args...)
2323
catch

base/compiler/typeinfer.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance)
10301030
end
10311031
end
10321032
if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 && !generating_output(#=incremental=#false)
1033-
return retrieve_code_info(mi, get_world_counter(interp))
1033+
return retrieve_code_info(mi, get_inference_world(interp))
10341034
end
10351035
lock_mi_inference(interp, mi)
10361036
result = InferenceResult(mi, typeinf_lattice(interp))
@@ -1094,7 +1094,7 @@ function typeinf_ext_toplevel(interp::AbstractInterpreter, mi::MethodInstance)
10941094
end
10951095

10961096
function return_type(@nospecialize(f), t::DataType) # this method has a special tfunc
1097-
world = ccall(:jl_get_tls_world_age, UInt, ())
1097+
world = tls_world_age()
10981098
args = Any[_return_type, NativeInterpreter(world), Tuple{Core.Typeof(f), t.parameters...}]
10991099
return ccall(:jl_call_in_typeinf_world, Any, (Ptr{Ptr{Cvoid}}, Cint), args, length(args))
11001100
end
@@ -1104,7 +1104,7 @@ function return_type(@nospecialize(f), t::DataType, world::UInt)
11041104
end
11051105

11061106
function return_type(t::DataType)
1107-
world = ccall(:jl_get_tls_world_age, UInt, ())
1107+
world = tls_world_age()
11081108
return return_type(t, world)
11091109
end
11101110

@@ -1122,7 +1122,7 @@ function _return_type(interp::AbstractInterpreter, t::DataType)
11221122
rt = builtin_tfunction(interp, f, args, nothing)
11231123
rt = widenconst(rt)
11241124
else
1125-
for match in _methods_by_ftype(t, -1, get_world_counter(interp))::Vector
1125+
for match in _methods_by_ftype(t, -1, get_inference_world(interp))::Vector
11261126
ty = typeinf_type(interp, match::MethodMatch)
11271127
ty === nothing && return Any
11281128
rt = tmerge(rt, ty)

base/compiler/types.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ If `interp::NewInterpreter` is an `AbstractInterpreter`, it is expected to provi
1212
the following methods to satisfy the `AbstractInterpreter` API requirement:
1313
- `InferenceParams(interp::NewInterpreter)` - return an `InferenceParams` instance
1414
- `OptimizationParams(interp::NewInterpreter)` - return an `OptimizationParams` instance
15-
- `get_world_counter(interp::NewInterpreter)` - return the world age for this interpreter
15+
- `get_inference_world(interp::NewInterpreter)` - return the world age for this interpreter
1616
- `get_inference_cache(interp::NewInterpreter)` - return the local inference cache
1717
- `code_cache(interp::NewInterpreter)` - return the global inference cache
1818
"""
@@ -402,9 +402,9 @@ end
402402
# Quickly and easily satisfy the AbstractInterpreter API contract
403403
InferenceParams(interp::NativeInterpreter) = interp.inf_params
404404
OptimizationParams(interp::NativeInterpreter) = interp.opt_params
405-
get_world_counter(interp::NativeInterpreter) = interp.world
405+
get_inference_world(interp::NativeInterpreter) = interp.world
406406
get_inference_cache(interp::NativeInterpreter) = interp.inf_cache
407-
code_cache(interp::NativeInterpreter) = WorldView(GLOBAL_CI_CACHE, get_world_counter(interp))
407+
code_cache(interp::NativeInterpreter) = WorldView(GLOBAL_CI_CACHE, get_inference_world(interp))
408408

409409
"""
410410
already_inferred_quick_test(::AbstractInterpreter, ::MethodInstance)
@@ -458,7 +458,7 @@ Returns a method table this `interp` uses for method lookup.
458458
External `AbstractInterpreter` can optionally return `OverlayMethodTable` here
459459
to incorporate customized dispatches for the overridden methods.
460460
"""
461-
method_table(interp::AbstractInterpreter) = InternalMethodTable(get_world_counter(interp))
461+
method_table(interp::AbstractInterpreter) = InternalMethodTable(get_inference_world(interp))
462462
method_table(interp::NativeInterpreter) = interp.method_table
463463

464464
"""

base/reflection.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,7 @@ function code_lowered(@nospecialize(f), @nospecialize(t=Tuple); generated::Bool=
11231123
throw(ArgumentError("'debuginfo' must be either :source or :none"))
11241124
end
11251125
world = get_world_counter()
1126+
world == typemax(UInt) && error("code reflection cannot be used from generated functions")
11261127
return map(method_instances(f, t, world)) do m
11271128
if generated && hasgenerator(m)
11281129
if may_invoke_generator(m)
@@ -2329,6 +2330,7 @@ end
23292330

23302331
function hasmethod(f, t, kwnames::Tuple{Vararg{Symbol}}; world::UInt=get_world_counter())
23312332
@nospecialize
2333+
world == typemax(UInt) && error("code reflection cannot be used from generated functions")
23322334
isempty(kwnames) && return hasmethod(f, t; world)
23332335
t = to_tuple_type(t)
23342336
ft = Core.Typeof(f)
@@ -2550,8 +2552,22 @@ min_world(m::Core.CodeInstance) = m.min_world
25502552
max_world(m::Core.CodeInstance) = m.max_world
25512553
min_world(m::Core.CodeInfo) = m.min_world
25522554
max_world(m::Core.CodeInfo) = m.max_world
2555+
2556+
"""
2557+
get_world_counter()
2558+
2559+
Returns the current maximum world-age counter. This counter is global and monotonically
2560+
increasing.
2561+
"""
25532562
get_world_counter() = ccall(:jl_get_world_counter, UInt, ())
25542563

2564+
"""
2565+
tls_world_age()
2566+
2567+
Returns the world the [current_task()](@ref) is executing within.
2568+
"""
2569+
tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ())
2570+
25552571
"""
25562572
propertynames(x, private=false)
25572573

src/gf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ jl_code_info_t *jl_type_infer(jl_method_instance_t *mi, size_t world, int force)
373373
#ifdef _OS_WINDOWS_
374374
DWORD last_error = GetLastError();
375375
#endif
376+
int last_pure = ct->ptls->in_pure_callback;
377+
ct->ptls->in_pure_callback = 0;
376378
size_t last_age = ct->world_age;
377379
ct->world_age = jl_typeinf_world;
378380
mi->inInference = 1;
@@ -409,6 +411,7 @@ jl_code_info_t *jl_type_infer(jl_method_instance_t *mi, size_t world, int force)
409411
}
410412
ct->world_age = last_age;
411413
ct->reentrant_timing -= 0b10;
414+
ct->ptls->in_pure_callback = last_pure;
412415
mi->inInference = 0;
413416
#ifdef _OS_WINDOWS_
414417
SetLastError(last_error);

stdlib/REPL/src/REPLCompletions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ struct REPLInterpreter <: CC.AbstractInterpreter
567567
end
568568
CC.InferenceParams(interp::REPLInterpreter) = interp.inf_params
569569
CC.OptimizationParams(interp::REPLInterpreter) = interp.opt_params
570-
CC.get_world_counter(interp::REPLInterpreter) = interp.world
570+
CC.get_inference_world(interp::REPLInterpreter) = interp.world
571571
CC.get_inference_cache(interp::REPLInterpreter) = interp.inf_cache
572572
CC.code_cache(interp::REPLInterpreter) = CC.WorldView(interp.code_cache, CC.WorldRange(interp.world))
573573
CC.get(wvc::CC.WorldView{REPLInterpreterCache}, mi::MethodInstance, default) = get(wvc.cache.dict, mi, default)

0 commit comments

Comments
 (0)