Skip to content

Commit abd160d

Browse files
committed
Figure out loading semantics for Compiler
This tries to align the semantics of `using Compiler` with that of all other (upgradable, not-in-the-sysimage) stdlibs by semantically treating the Compiler as a non-loaded stdlib that just happens to already have its `.ji` file included in the sysimage. Then, when you ask it to create a `.ji` file, it simply writes out a stub file that redirects everything to the sysimage. Example: Here we load an unmodified compiler image. Everything is done in 1s and the `Compiler` you get back at toplevel is the same Compiler that Base uses. ``` julia> @time using Compiler ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since pkgimage /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so was not found └ @ Base loading.jl:3945 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_ajVhJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since the flags are mismatched │ requested flags: use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2 [163] │ cache file: use_pkgimages = true, debug_level = 2, check_bounds = 0, inline = true, opt_level = 2 [165] └ @ Base loading.jl:3918 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since pkgimage /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so was not found └ @ Base loading.jl:3945 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_ajVhJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since the flags are mismatched │ requested flags: use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2 [163] │ cache file: use_pkgimages = true, debug_level = 2, check_bounds = 0, inline = true, opt_level = 2 [165] └ @ Base loading.jl:3918 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since pkgimage /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so was not found └ @ Base loading.jl:3945 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_ajVhJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since the flags are mismatched │ requested flags: use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2 [163] │ cache file: use_pkgimages = true, debug_level = 2, check_bounds = 0, inline = true, opt_level = 2 [165] └ @ Base loading.jl:3918 [ Info: Precompiling Compiler [807dbc54-b67e-4c79-8afb-eafe4df6f2e1] (cache misses: mismatched flags (2), missing ocachefile (2)) ┌ Debug: Generating object cache file for Compiler [807dbc54-b67e-4c79-8afb-eafe4df6f2e1] └ @ Base loading.jl:3021 ┌ Debug: Loading object cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so for Compiler [807dbc54-b67e-4c79-8afb-eafe4df6f2e1] └ @ Base loading.jl:1277 1.000245 seconds (507.60 k allocations: 29.245 MiB, 1.68% gc time, 65.46% compilation time) shell> ls -la /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so -rwxrwxr-x 1 keno keno 7112 Nov 1 07:33 /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so julia> Compiler === Base.Compiler true ``` Next, we dev the Compiler from another Julia version. Now it just treats is as a regular package load and generates a 5MB .ji that contains the usual pkgimage. ``` (@v1.12) pkg> dev /home/keno/julia2/stdlib/Compiler Resolving package versions... Updating `~/.julia/environments/v1.12/Project.toml` [807dbc54] + Compiler v0.0.1 `~/julia2/stdlib/Compiler` Updating `~/.julia/environments/v1.12/Manifest.toml` [807dbc54] + Compiler v0.0.1 `~/julia2/stdlib/Compiler` julia> using Compiler ┌ Debug: Rejecting stale cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.ji because file size of /home/keno/julia2/stdlib/Compiler/src/Compiler.jl has changed (file size 5958, before 5949) └ @ Base loading.jl:3875 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_ajVhJ.ji for Base.PkgId(Base.UUID("807dbc54-b67e-4c79-8afb-eafe4df6f2e1"), "Compiler") since the flags are mismatched │ requested flags: use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2 [163] │ cache file: use_pkgimages = true, debug_level = 2, check_bounds = 0, inline = true, opt_level = 2 [165] └ @ Base loading.jl:3918 ┌ Debug: Rejecting stale cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.ji because file size of /home/keno/julia2/stdlib/Compiler/src/Compiler.jl has changed (file size 5958, before 5949) └ @ Base loading.jl:3875 ┌ Debug: Rejecting cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_ajVhJ.ji for Base.PkgId(nothing, "") since the flags are mismatched │ requested flags: use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2 [163] │ cache file: use_pkgimages = true, debug_level = 2, check_bounds = 0, inline = true, opt_level = 2 [165] └ @ Base loading.jl:3918 Precompiling Compiler finished. 1 dependency successfully precompiled in 3 seconds ┌ Debug: Loading object cache file /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so for Compiler [807dbc54-b67e-4c79-8afb-eafe4df6f2e1] └ @ Base loading.jl:1277 shell> ls -la /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so -rwxrwxr-x 1 keno keno 5706792 Nov 1 07:40 /home/keno/.julia/compiled/v1.12/Compiler/DqelA_OpSbJ.so julia> Compiler === Base.Compiler false ```
1 parent 8d08bf2 commit abd160d

File tree

7 files changed

+165
-81
lines changed

7 files changed

+165
-81
lines changed

base/Base_compiler.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ include("ordering.jl")
248248
using .Order
249249

250250
include("coreir.jl")
251+
include("osutils.jl")
251252

252253
include("../stdlib/Compiler/src/Compiler.jl")
253254

base/loading.jl

Lines changed: 94 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,15 +2168,22 @@ const include_callbacks = Any[]
21682168
const _concrete_dependencies = Pair{PkgId,UInt128}[] # these dependency versions are "set in stone", because they are explicitly loaded, and the process should try to avoid invalidating them
21692169
const _require_dependencies = Any[] # a list of (mod, abspath, fsize, hash, mtime) tuples that are the file dependencies of the module currently being precompiled
21702170
const _track_dependencies = Ref(false) # set this to true to track the list of file dependencies
2171-
function _include_dependency(mod::Module, _path::AbstractString; track_content=true,
2172-
path_may_be_dir=false)
2171+
2172+
function _include_dependency(mod::Module, _path::AbstractString; track_content::Bool=true,
2173+
path_may_be_dir::Bool=false)
2174+
_include_dependency!(_require_dependencies, _track_dependencies[], mod, _path, track_content, path_may_be_dir)
2175+
end
2176+
2177+
function _include_dependency!(dep_list::Vector{Any}, track_dependencies::Bool,
2178+
mod::Module, _path::AbstractString,
2179+
track_content::Bool, path_may_be_dir::Bool)
21732180
prev = source_path(nothing)
21742181
if prev === nothing
21752182
path = abspath(_path)
21762183
else
21772184
path = normpath(joinpath(dirname(prev), _path))
21782185
end
2179-
if !_track_dependencies[]
2186+
if !track_dependencies[]
21802187
if !path_may_be_dir && !isfile(path)
21812188
throw(SystemError("opening file $(repr(path))", Libc.ENOENT))
21822189
elseif path_may_be_dir && !Filesystem.isreadable(path)
@@ -2187,9 +2194,9 @@ function _include_dependency(mod::Module, _path::AbstractString; track_content=t
21872194
if track_content
21882195
hash = isdir(path) ? _crc32c(join(readdir(path))) : open(_crc32c, path, "r")
21892196
# use mtime=-1.0 here so that fsize==0 && mtime==0.0 corresponds to a missing include_dependency
2190-
push!(_require_dependencies, (mod, path, filesize(path), hash, -1.0))
2197+
push!(dep_list, (mod, path, filesize(path), hash, -1.0))
21912198
else
2192-
push!(_require_dependencies, (mod, path, UInt64(0), UInt32(0), mtime(path)))
2199+
push!(dep_list, (mod, path, UInt64(0), UInt32(0), mtime(path)))
21932200
end
21942201
end
21952202
end
@@ -2493,7 +2500,21 @@ end
24932500
maybe_root_module(key::PkgId) = @lock require_lock get(loaded_modules, key, nothing)
24942501

24952502
root_module_exists(key::PkgId) = @lock require_lock haskey(loaded_modules, key)
2496-
loaded_modules_array() = @lock require_lock copy(loaded_modules_order)
2503+
function loaded_modules_array()
2504+
@lock require_lock begin
2505+
ret = copy(loaded_modules_order)
2506+
if generating_output(false)
2507+
# If we're generating a non-incremental system image, also add the
2508+
# Compiler to the module list so that we generate native code for it.
2509+
# However, we do not add it to `loaded_modules_order` unless there
2510+
# is a Julia-level dependency on it. The (non-)loadedness of the compiler
2511+
# is an implementation detail and we do not want ordinary pkgimages to
2512+
# acquire a dependency on the Compiler if they do not use it internally.
2513+
push!(ret, Compiler)
2514+
end
2515+
return ret
2516+
end
2517+
end
24972518

24982519
# after unreference_module, a subsequent require call will try to load a new copy of it, if stale
24992520
# reload(m) = (unreference_module(m); require(m))
@@ -3273,6 +3294,10 @@ mutable struct CacheHeaderIncludes
32733294
const modpath::Vector{String} # seemingly not needed in Base, but used by Revise
32743295
end
32753296

3297+
function CacheHeaderIncludes(dep_tuple::Tuple{Module, String, Int64, UInt32, Float64})
3298+
return CacheHeaderIncludes(PkgId(dep_tuple[1]), dep_tuple[2:end]..., String[])
3299+
end
3300+
32763301
function replace_depot_path(path::AbstractString, depots::Vector{String}=normalize_depots_for_relocation())
32773302
for depot in depots
32783303
if startswith(path, string(depot, Filesystem.pathsep())) || path == depot
@@ -3812,6 +3837,56 @@ function list_reasons(reasons::Dict{String,Int})
38123837
end
38133838
list_reasons(::Nothing) = ""
38143839

3840+
function any_includes_stale(includes::Vector{CacheHeaderIncludes}, cachefile::String, reasons::Union{Dict{String,Int},Nothing}=nothing)
3841+
for chi in includes
3842+
f, fsize_req, hash_req, ftime_req = chi.filename, chi.fsize, chi.hash, chi.mtime
3843+
if startswith(f, string("@depot", Filesystem.pathsep()))
3844+
@debug("Rejecting stale cache file $cachefile because its depot could not be resolved")
3845+
record_reason(reasons, "nonresolveable depot")
3846+
return true
3847+
end
3848+
if !ispath(f)
3849+
_f = fixup_stdlib_path(f)
3850+
if _f != f && isfile(_f) && startswith(_f, Sys.STDLIB)
3851+
continue
3852+
end
3853+
@debug "Rejecting stale cache file $cachefile because file $f does not exist"
3854+
record_reason(reasons, "missing sourcefile")
3855+
return true
3856+
end
3857+
if ftime_req >= 0.0
3858+
# this is an include_dependency for which we only recorded the mtime
3859+
ftime = mtime(f)
3860+
is_stale = ( ftime != ftime_req ) &&
3861+
( ftime != floor(ftime_req) ) && # Issue #13606, PR #13613: compensate for Docker images rounding mtimes
3862+
( ftime != ceil(ftime_req) ) && # PR: #47433 Compensate for CirceCI's truncating of timestamps in its caching
3863+
( ftime != trunc(ftime_req, digits=6) ) && # Issue #20837, PR #20840: compensate for GlusterFS truncating mtimes to microseconds
3864+
( ftime != 1.0 ) && # PR #43090: provide compatibility with Nix mtime.
3865+
!( 0 < (ftime_req - ftime) < 1e-6 ) # PR #45552: Compensate for Windows tar giving mtimes that may be incorrect by up to one microsecond
3866+
if is_stale
3867+
@debug "Rejecting stale cache file $cachefile because mtime of include_dependency $f has changed (mtime $ftime, before $ftime_req)"
3868+
record_reason(reasons, "include_dependency mtime change")
3869+
return true
3870+
end
3871+
else
3872+
fstat = stat(f)
3873+
fsize = filesize(fstat)
3874+
if fsize != fsize_req
3875+
@debug "Rejecting stale cache file $cachefile because file size of $f has changed (file size $fsize, before $fsize_req)"
3876+
record_reason(reasons, "include_dependency fsize change")
3877+
return true
3878+
end
3879+
hash = isdir(fstat) ? _crc32c(join(readdir(f))) : open(_crc32c, f, "r")
3880+
if hash != hash_req
3881+
@debug "Rejecting stale cache file $cachefile because hash of $f has changed (hash $hash, before $hash_req)"
3882+
record_reason(reasons, "include_dependency fhash change")
3883+
return true
3884+
end
3885+
end
3886+
end
3887+
return false
3888+
end
3889+
38153890
# returns true if it "cachefile.ji" is stale relative to "modpath.jl" and build_id for modkey
38163891
# otherwise returns the list of dependencies to also check
38173892
@constprop :none function stale_cachefile(modpath::String, cachefile::String; ignore_loaded::Bool = false, requested_flags::CacheFlags=CacheFlags(), reasons=nothing)
@@ -3971,51 +4046,8 @@ end
39714046
return true
39724047
end
39734048
end
3974-
for chi in includes
3975-
f, fsize_req, hash_req, ftime_req = chi.filename, chi.fsize, chi.hash, chi.mtime
3976-
if startswith(f, string("@depot", Filesystem.pathsep()))
3977-
@debug("Rejecting stale cache file $cachefile because its depot could not be resolved")
3978-
record_reason(reasons, "nonresolveable depot")
3979-
return true
3980-
end
3981-
if !ispath(f)
3982-
_f = fixup_stdlib_path(f)
3983-
if _f != f && isfile(_f) && startswith(_f, Sys.STDLIB)
3984-
continue
3985-
end
3986-
@debug "Rejecting stale cache file $cachefile because file $f does not exist"
3987-
record_reason(reasons, "missing sourcefile")
3988-
return true
3989-
end
3990-
if ftime_req >= 0.0
3991-
# this is an include_dependency for which we only recorded the mtime
3992-
ftime = mtime(f)
3993-
is_stale = ( ftime != ftime_req ) &&
3994-
( ftime != floor(ftime_req) ) && # Issue #13606, PR #13613: compensate for Docker images rounding mtimes
3995-
( ftime != ceil(ftime_req) ) && # PR: #47433 Compensate for CirceCI's truncating of timestamps in its caching
3996-
( ftime != trunc(ftime_req, digits=6) ) && # Issue #20837, PR #20840: compensate for GlusterFS truncating mtimes to microseconds
3997-
( ftime != 1.0 ) && # PR #43090: provide compatibility with Nix mtime.
3998-
!( 0 < (ftime_req - ftime) < 1e-6 ) # PR #45552: Compensate for Windows tar giving mtimes that may be incorrect by up to one microsecond
3999-
if is_stale
4000-
@debug "Rejecting stale cache file $cachefile because mtime of include_dependency $f has changed (mtime $ftime, before $ftime_req)"
4001-
record_reason(reasons, "include_dependency mtime change")
4002-
return true
4003-
end
4004-
else
4005-
fstat = stat(f)
4006-
fsize = filesize(fstat)
4007-
if fsize != fsize_req
4008-
@debug "Rejecting stale cache file $cachefile because file size of $f has changed (file size $fsize, before $fsize_req)"
4009-
record_reason(reasons, "include_dependency fsize change")
4010-
return true
4011-
end
4012-
hash = isdir(fstat) ? _crc32c(join(readdir(f))) : open(_crc32c, f, "r")
4013-
if hash != hash_req
4014-
@debug "Rejecting stale cache file $cachefile because hash of $f has changed (hash $hash, before $hash_req)"
4015-
record_reason(reasons, "include_dependency fhash change")
4016-
return true
4017-
end
4018-
end
4049+
if any_includes_stale(includes, cachefile, reasons)
4050+
return true
40194051
end
40204052
end
40214053

@@ -4138,3 +4170,14 @@ precompile(include_package_for_output, (PkgId, String, Vector{String}, Vector{St
41384170
precompile(include_package_for_output, (PkgId, String, Vector{String}, Vector{String}, Vector{String}, typeof(_concrete_dependencies), String)) || @assert false
41394171
precompile(create_expr_cache, (PkgId, String, String, String, typeof(_concrete_dependencies), Cmd, IO, IO)) || @assert false
41404172
precompile(create_expr_cache, (PkgId, String, String, Nothing, typeof(_concrete_dependencies), Cmd, IO, IO)) || @assert false
4173+
4174+
is_core_or_base(mod::Module) = mod === Core || mod === Base
4175+
function prepare_compiler_stub_image!()
4176+
ccall(:jl_add_to_module_init_list, Cvoid, (Any,), Compiler)
4177+
# Drop any dependencies on loaded modules. We know Base.Compiler only depends
4178+
# on very basic `Base` functionality, so we don't want to pick up dependencies
4179+
# on other stdlibs that may be loaded.
4180+
filter!(p->is_core_or_base(p.second), loaded_modules)
4181+
register_root_module(Compiler)
4182+
filter!(is_core_or_base, loaded_modules_order)
4183+
end

contrib/generate_precompile.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ generate_precompile_statements() = try # Make sure `ansi_enablecursor` is printe
359359
eval(PrecompileStagingArea, :(const $(Symbol(_mod)) = $_mod))
360360
end
361361
end
362+
eval(PrecompileStagingArea, :(const Compiler = Base.Compiler))
362363

363364
n_succeeded = 0
364365
# Make statements unique

src/module.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,7 @@ JL_DLLEXPORT jl_uuid_t jl_module_uuid(jl_module_t* m) { return m->uuid; }
11821182

11831183
// TODO: make this part of the module constructor and read-only?
11841184
JL_DLLEXPORT void jl_set_module_uuid(jl_module_t *m, jl_uuid_t uuid) { m->uuid = uuid; }
1185+
JL_DLLEXPORT void jl_set_module_parent(jl_module_t *m, jl_module_t *parent) { m->parent = parent; }
11851186

11861187
int jl_is_submodule(jl_module_t *child, jl_module_t *parent) JL_NOTSAFEPOINT
11871188
{
@@ -1214,15 +1215,20 @@ JL_DLLEXPORT void jl_clear_implicit_imports(jl_module_t *m)
12141215
JL_UNLOCK(&m->lock);
12151216
}
12161217

1218+
JL_DLLEXPORT void jl_add_to_module_init_list(jl_value_t *mod)
1219+
{
1220+
if (jl_module_init_order == NULL)
1221+
jl_module_init_order = jl_alloc_vec_any(0);
1222+
jl_array_ptr_1d_push(jl_module_init_order, mod);
1223+
}
1224+
12171225
JL_DLLEXPORT void jl_init_restored_module(jl_value_t *mod)
12181226
{
12191227
if (!jl_generating_output() || jl_options.incremental) {
12201228
jl_module_run_initializer((jl_module_t*)mod);
12211229
}
12221230
else {
1223-
if (jl_module_init_order == NULL)
1224-
jl_module_init_order = jl_alloc_vec_any(0);
1225-
jl_array_ptr_1d_push(jl_module_init_order, mod);
1231+
jl_add_to_module_init_list(mod);
12261232
}
12271233
}
12281234

src/precompile_utils.c

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ static void *jl_precompile(int all)
281281
return native_code;
282282
}
283283

284+
static int suppress_precompile = 0;
285+
JL_DLLEXPORT void jl_suppress_precompile(int suppress)
286+
{
287+
suppress_precompile = suppress;
288+
}
289+
284290
static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_methods, jl_array_t *new_ext_cis)
285291
{
286292
if (!worklist)
@@ -289,34 +295,36 @@ static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_met
289295
// type signatures that were inferred but haven't been compiled
290296
jl_array_t *m = jl_alloc_vec_any(0);
291297
JL_GC_PUSH1(&m);
292-
size_t i, n = jl_array_nrows(worklist);
293-
for (i = 0; i < n; i++) {
294-
jl_module_t *mod = (jl_module_t*)jl_array_ptr_ref(worklist, i);
295-
assert(jl_is_module(mod));
296-
foreach_mtable_in_module(mod, precompile_enq_all_specializations_, m);
297-
}
298-
n = jl_array_nrows(extext_methods);
299-
for (i = 0; i < n; i++) {
300-
jl_method_t *method = (jl_method_t*)jl_array_ptr_ref(extext_methods, i);
301-
assert(jl_is_method(method));
302-
jl_value_t *specializations = jl_atomic_load_relaxed(&method->specializations);
303-
if (!jl_is_svec(specializations)) {
304-
precompile_enq_specialization_((jl_method_instance_t*)specializations, m);
298+
if (!suppress_precompile) {
299+
size_t i, n = jl_array_nrows(worklist);
300+
for (i = 0; i < n; i++) {
301+
jl_module_t *mod = (jl_module_t*)jl_array_ptr_ref(worklist, i);
302+
assert(jl_is_module(mod));
303+
foreach_mtable_in_module(mod, precompile_enq_all_specializations_, m);
305304
}
306-
else {
307-
size_t j, l = jl_svec_len(specializations);
308-
for (j = 0; j < l; j++) {
309-
jl_value_t *mi = jl_svecref(specializations, j);
310-
if (mi != jl_nothing)
311-
precompile_enq_specialization_((jl_method_instance_t*)mi, m);
305+
n = jl_array_nrows(extext_methods);
306+
for (i = 0; i < n; i++) {
307+
jl_method_t *method = (jl_method_t*)jl_array_ptr_ref(extext_methods, i);
308+
assert(jl_is_method(method));
309+
jl_value_t *specializations = jl_atomic_load_relaxed(&method->specializations);
310+
if (!jl_is_svec(specializations)) {
311+
precompile_enq_specialization_((jl_method_instance_t*)specializations, m);
312+
}
313+
else {
314+
size_t j, l = jl_svec_len(specializations);
315+
for (j = 0; j < l; j++) {
316+
jl_value_t *mi = jl_svecref(specializations, j);
317+
if (mi != jl_nothing)
318+
precompile_enq_specialization_((jl_method_instance_t*)mi, m);
319+
}
312320
}
313321
}
314-
}
315-
if (new_ext_cis) {
316-
n = jl_array_nrows(new_ext_cis);
317-
for (i = 0; i < n; i++) {
318-
jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i);
319-
precompile_enq_specialization_(ci->def, m);
322+
if (new_ext_cis) {
323+
n = jl_array_nrows(new_ext_cis);
324+
for (i = 0; i < n; i++) {
325+
jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i);
326+
precompile_enq_specialization_(ci->def, m);
327+
}
320328
}
321329
}
322330
void *native_code = jl_precompile_(m, 1);

stdlib/Compiler/src/Compiler.jl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3+
# When generating an incremental precompile file, we first check whether we
4+
# already have a copy of this *exact* code in the system image. If so, we
5+
# simply generates a pkgimage that has the dependency edges we recorded in
6+
# the system image and simply returns that copy of the compiler. If not,
7+
# we proceed to load/precompile this as an ordinary package.
8+
if isdefined(Base, :generating_output) && Base.generating_output(true) &&
9+
!Base.any_includes_stale(
10+
map(Base.CacheHeaderIncludes, Base._compiler_require_dependencies),
11+
"sysimg", nothing)
12+
13+
Base.prepare_compiler_stub_image!()
14+
append!(Base._require_dependencies, Base._compiler_require_dependencies)
15+
# There isn't much point in precompiling native code - downstream users will
16+
# specialize their own versions of the compiler code and we don't activate
17+
# the compiler by default anyway, so let's save ourselves some disk space.
18+
ccall(:jl_suppress_precompile, Cvoid, (Cint,), 1)
319

4-
baremodule Compiler
20+
else
21+
22+
@eval baremodule Compiler
23+
24+
# Needs to match UUID defined in Project.toml
25+
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler,
26+
(0x807dbc54_b67e_4c79, 0x8afb_eafe4df6f2e1))
27+
ccall(:jl_set_module_parent, Cvoid, (Any, Any), Compiler, Compiler)
528

629
using Core.Intrinsics, Core.IR
730

@@ -136,3 +159,5 @@ include("optimize.jl")
136159
include("bootstrap.jl")
137160

138161
end
162+
163+
end

sysimage.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ COMPILER_SRCS := $(addprefix $(JULIAHOME)/, \
5555
base/traits.jl \
5656
base/refvalue.jl \
5757
base/tuple.jl)
58-
COMPILER_SRCS += $(shell find $(JULIAHOME)/base/compiler -name \*.jl)
58+
COMPILER_SRCS += $(shell find $(JULIAHOME)/stdlib/Compiler/src -name \*.jl)
5959
# sort these to remove duplicates
6060
BASE_SRCS := $(sort $(shell find $(JULIAHOME)/base -name \*.jl -and -not -name sysimg.jl) \
6161
$(shell find $(BUILDROOT)/base -name \*.jl -and -not -name sysimg.jl))

0 commit comments

Comments
 (0)