Skip to content

Commit b7b79eb

Browse files
authored
Break dependency between loading and Core.Compiler (#56186)
This code was originally added in df81bf9 where Core.Compiler would keep an array of all the things it inferred, which could then be provieded to the runtime to be included in the package image. In 113efb6 keeping the array itself became a runtime service for locking considerations. As a result, the role of Core.Compiler here is a bit weird. It has the enable switch and the GC root, but all the actual state is being managed by the runtime. It would be desirable to remove the Core.Compiler reference, so that loading.jl can function even if `Core.Compiler` does not exist (which is in theory supposed to be possible, even though we currently never run in such a configuration; that said, post trimming one might imagine useful instances of such a setup). To do this, put the runtime fully in charge of managing this array. Core.Compiler will call the callback unconditionally for all newly inferred cis and the runtime can decide whether to save it or not. Extracted from #56128
1 parent c07a40f commit b7b79eb

File tree

4 files changed

+19
-14
lines changed

4 files changed

+19
-14
lines changed

base/compiler/cicache.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ end
1313

1414
function setindex!(cache::InternalCodeCache, ci::CodeInstance, mi::MethodInstance)
1515
@assert ci.owner === cache.owner
16+
m = mi.def
17+
if isa(m, Method) && m.module != Core
18+
ccall(:jl_push_newly_inferred, Cvoid, (Any,), ci)
19+
end
1620
ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, ci)
1721
return cache
1822
end

base/compiler/typeinfer.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3-
# Tracking of newly-inferred CodeInstances during precompilation
4-
const track_newly_inferred = RefValue{Bool}(false)
5-
const newly_inferred = CodeInstance[]
6-
73
"""
84
The module `Core.Compiler.Timings` provides a simple implementation of nested timers that
95
can be used to measure the exclusive time spent inferring each method instance that is
@@ -264,12 +260,6 @@ function cache_result!(interp::AbstractInterpreter, result::InferenceResult)
264260

265261
if cache_results
266262
code_cache(interp)[mi] = result.ci
267-
if track_newly_inferred[]
268-
m = mi.def
269-
if isa(m, Method) && m.module != Core
270-
ccall(:jl_push_newly_inferred, Cvoid, (Any,), result.ci)
271-
end
272-
end
273263
end
274264
return cache_results
275265
end

base/loading.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2900,6 +2900,9 @@ function load_path_setup_code(load_path::Bool=true)
29002900
return code
29012901
end
29022902

2903+
# Const global for GC root
2904+
const newly_inferred = CodeInstance[]
2905+
29032906
# this is called in the external process that generates precompiled package files
29042907
function include_package_for_output(pkg::PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String},
29052908
concrete_deps::typeof(_concrete_dependencies), source::Union{Nothing,String})
@@ -2919,19 +2922,23 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
29192922
task_local_storage()[:SOURCE_PATH] = source
29202923
end
29212924

2922-
ccall(:jl_set_newly_inferred, Cvoid, (Any,), Core.Compiler.newly_inferred)
2923-
Core.Compiler.track_newly_inferred.x = true
2925+
ccall(:jl_set_newly_inferred, Cvoid, (Any,), newly_inferred)
29242926
try
29252927
Base.include(Base.__toplevel__, input)
29262928
catch ex
29272929
precompilableerror(ex) || rethrow()
29282930
@debug "Aborting `create_expr_cache'" exception=(ErrorException("Declaration of __precompile__(false) not allowed"), catch_backtrace())
29292931
exit(125) # we define status = 125 means PrecompileableError
29302932
finally
2931-
Core.Compiler.track_newly_inferred.x = false
2933+
ccall(:jl_set_newly_inferred, Cvoid, (Any,), nothing)
29322934
end
29332935
# check that the package defined the expected module so we can give a nice error message if not
29342936
Base.check_package_module_loaded(pkg)
2937+
2938+
# Re-populate the runtime's newly-inferred array, which will be included
2939+
# in the output. We removed it above to avoid including any code we may
2940+
# have compiled for error handling and validation.
2941+
ccall(:jl_set_newly_inferred, Cvoid, (Any,), newly_inferred)
29352942
end
29362943

29372944
function check_package_module_loaded(pkg::PkgId)

src/staticdata_utils.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,16 @@ extern jl_mutex_t world_counter_lock;
9191
// This gets called as the first step of Base.include_package_for_output
9292
JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t* _newly_inferred)
9393
{
94-
assert(_newly_inferred == NULL || jl_is_array(_newly_inferred));
94+
assert(_newly_inferred == NULL || _newly_inferred == jl_nothing || jl_is_array(_newly_inferred));
95+
if (_newly_inferred == jl_nothing)
96+
_newly_inferred = NULL;
9597
newly_inferred = (jl_array_t*) _newly_inferred;
9698
}
9799

98100
JL_DLLEXPORT void jl_push_newly_inferred(jl_value_t* ci)
99101
{
102+
if (!newly_inferred)
103+
return;
100104
JL_LOCK(&newly_inferred_mutex);
101105
size_t end = jl_array_nrows(newly_inferred);
102106
jl_array_grow_end(newly_inferred, 1);

0 commit comments

Comments
 (0)