Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ New library features
* `IOContext` supports a new boolean `hexunsigned` option that allows for
printing unsigned integers in decimal instead of hexadecimal ([#60267]).

* Package precompilation now supports running precompilation in
a background task and has new interactive keyboard controls:
`c` to cleanly cancel immediately, `d` to detach, `i` for a profile peek,
`v` to toggle verbose mode showing elapsed time, CPU%, and memory usage, and `?` for help. ([#60943]).

Standard library changes
------------------------

Expand Down
50 changes: 45 additions & 5 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2856,6 +2856,11 @@ function __require_prelocked(pkg::PkgId, env)

if JLOptions().use_compiled_modules == 1
if !generating_output(#=incremental=#false)
# If a background precompile task is working on this package,
# temporarily monitor it until done, then retry from cache.
if Precompilation.wait_for_pending_package(pkg)
@goto load_from_cache
end
# spawn off a new incremental pre-compile task for recursive `require` calls
loaded = let spec = spec, reasons = reasons, parallel_precompile_attempted = parallel_precompile_attempted
maybe_cachefile_lock(pkg, spec.path) do
Expand Down Expand Up @@ -3441,18 +3446,19 @@ This can be used to reduce package load times. Cache files are stored in
`DEPOT_PATH[1]/compiled`. See [Module initialization and precompilation](@ref)
for important notes.
"""
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(), loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(), loadable_exts::Union{Vector{PkgId},Nothing}=nothing, signal_channel::Union{Channel{Int32},Nothing}=nothing)
@nospecialize internal_stderr internal_stdout
spec = locate_package_load_spec(pkg)
spec === nothing && throw(ArgumentError("$(repr("text/plain", pkg)) not found during precompilation"))
return compilecache(pkg, spec, internal_stderr, internal_stdout; flags, cacheflags, loadable_exts)
return compilecache(pkg, spec, internal_stderr, internal_stdout; flags, cacheflags, loadable_exts, signal_channel)
end

const MAX_NUM_PRECOMPILE_FILES = Ref(10)

function compilecache(pkg::PkgId, spec::PkgLoadSpec, internal_stderr::IO = stderr, internal_stdout::IO = stdout,
keep_loaded_modules::Bool = true; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(),
loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
loadable_exts::Union{Vector{PkgId},Nothing}=nothing, signal_channel::Union{Channel{Int32},Nothing}=nothing,
pid_channel::Union{Channel{Int32},Nothing}=nothing)

@nospecialize internal_stderr internal_stdout
# decide where to put the resulting cache file
Expand Down Expand Up @@ -3483,7 +3489,7 @@ function compilecache(pkg::PkgId, spec::PkgLoadSpec, internal_stderr::IO = stder
else
tmppath_o = nothing
end
local p
local p::Base.Process
try
close(tmpio)
if cache_objects
Expand All @@ -3492,7 +3498,38 @@ function compilecache(pkg::PkgId, spec::PkgLoadSpec, internal_stderr::IO = stder
end
p = create_expr_cache(pkg, spec, tmppath, tmppath_o, concrete_deps, flags, cacheflags, internal_stderr, internal_stdout, loadable_exts)

if success(p)
# Report the PID of the compilation subprocess
if pid_channel !== nothing
try; put!(pid_channel, Int32(getpid(p))); catch; end
end

# Forward signals from the channel to the subprocess
if signal_channel !== nothing
let p = p
Base.errormonitor(Threads.@spawn :samepool begin
for sig in signal_channel
process_running(p) || break
try
kill(p, sig)
catch e
e isa IOError && break
rethrow()
end
end
end)
end
end

local result
try
result = success(p)
finally
if signal_channel !== nothing
close(signal_channel)
end
end

if result
if cache_objects
# Run linker over tmppath_o
Linking.link_image(tmppath_o, tmppath_so)
Expand Down Expand Up @@ -3562,6 +3599,9 @@ function compilecache(pkg::PkgId, spec::PkgLoadSpec, internal_stderr::IO = stder
return cachefile, ocachefile
end
finally
if signal_channel !== nothing
close(signal_channel)
end
rm(tmppath, force=true)
if cache_objects
rm(tmppath_o::String, force=true)
Expand Down
Loading
Loading