@@ -1231,7 +1231,7 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
12311231 dep = depmods[i]
12321232 dep isa Module && continue
12331233 _, depkey, depbuild_id = dep:: Tuple{String, PkgId, UInt128}
1234- dep = loaded_precompiles[ depkey => depbuild_id]
1234+ dep = something ( maybe_loaded_precompile ( depkey, depbuild_id))
12351235 @assert PkgId (dep) == depkey && module_build_id (dep) === depbuild_id
12361236 depmods[i] = dep
12371237 end
@@ -1337,6 +1337,7 @@ end
13371337
13381338function register_restored_modules (sv:: SimpleVector , pkg:: PkgId , path:: String )
13391339 # This function is also used by PkgCacheInspector.jl
1340+ assert_havelock (require_lock)
13401341 restored = sv[1 ]:: Vector{Any}
13411342 for M in restored
13421343 M = M:: Module
@@ -1345,7 +1346,7 @@ function register_restored_modules(sv::SimpleVector, pkg::PkgId, path::String)
13451346 end
13461347 if parentmodule (M) === M
13471348 push! (loaded_modules_order, M)
1348- loaded_precompiles[pkg => module_build_id (M)] = M
1349+ push! ( get! (Vector{Module}, loaded_precompiles, pkg), M)
13491350 end
13501351 end
13511352
@@ -1943,90 +1944,102 @@ end
19431944 assert_havelock (require_lock)
19441945 paths = find_all_in_cache_path (pkg, DEPOT_PATH )
19451946 newdeps = PkgId[]
1946- for path_to_try in paths:: Vector{String}
1947- staledeps = stale_cachefile (pkg, build_id, sourcepath, path_to_try; reasons, stalecheck)
1948- if staledeps === true
1949- continue
1950- end
1951- try
1952- staledeps, ocachefile, newbuild_id = staledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1953- # finish checking staledeps module graph
1954- for i in eachindex (staledeps)
1955- dep = staledeps[i]
1956- dep isa Module && continue
1957- modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt128}
1958- modpaths = find_all_in_cache_path (modkey, DEPOT_PATH )
1959- for modpath_to_try in modpaths
1960- modstaledeps = stale_cachefile (modkey, modbuild_id, modpath, modpath_to_try; stalecheck)
1961- if modstaledeps === true
1962- continue
1963- end
1964- modstaledeps, modocachepath, _ = modstaledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1965- staledeps[i] = (modpath, modkey, modbuild_id, modpath_to_try, modstaledeps, modocachepath)
1966- @goto check_next_dep
1947+ try_build_ids = UInt128[build_id]
1948+ if build_id == UInt128 (0 )
1949+ let loaded = get (loaded_precompiles, pkg, nothing )
1950+ if loaded != = nothing
1951+ for mod in loaded # try these in reverse original load order to see if one is already valid
1952+ pushfirst! (try_build_ids, module_build_id (mod))
19671953 end
1968- @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $(UUID (modbuild_id)) is missing from the cache."
1969- @goto check_next_path
1970- @label check_next_dep
1971- end
1972- M = get (loaded_precompiles, pkg => newbuild_id, nothing )
1973- if isa (M, Module)
1974- stalecheck && register_root_module (M)
1975- return M
19761954 end
1977- if stalecheck
1978- try
1979- touch (path_to_try) # update timestamp of precompilation file
1980- catch ex # file might be read-only and then we fail to update timestamp, which is fine
1981- ex isa IOError || rethrow ()
1982- end
1955+ end
1956+ end
1957+ for build_id in try_build_ids
1958+ for path_to_try in paths:: Vector{String}
1959+ staledeps = stale_cachefile (pkg, build_id, sourcepath, path_to_try; reasons, stalecheck)
1960+ if staledeps === true
1961+ continue
19831962 end
1984- # finish loading module graph into staledeps
1985- # TODO : call all start_loading calls (in reverse order) before calling any _include_from_serialized, since start_loading will drop the loading lock
1986- for i in eachindex (staledeps)
1987- dep = staledeps[i]
1988- dep isa Module && continue
1989- modpath, modkey, modbuild_id, modcachepath, modstaledeps, modocachepath = dep:: Tuple{String, PkgId, UInt128, String, Vector{Any}, Union{Nothing, String}}
1990- dep = start_loading (modkey, modbuild_id, stalecheck)
1991- while true
1992- if dep isa Module
1993- if PkgId (dep) == modkey && module_build_id (dep) === modbuild_id
1994- break
1995- else
1996- @debug " Rejecting cache file $path_to_try because module $modkey got loaded at a different version than expected."
1997- @goto check_next_path
1963+ try
1964+ staledeps, ocachefile, newbuild_id = staledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1965+ # finish checking staledeps module graph
1966+ for i in eachindex (staledeps)
1967+ dep = staledeps[i]
1968+ dep isa Module && continue
1969+ modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt128}
1970+ modpaths = find_all_in_cache_path (modkey, DEPOT_PATH )
1971+ for modpath_to_try in modpaths
1972+ modstaledeps = stale_cachefile (modkey, modbuild_id, modpath, modpath_to_try; stalecheck)
1973+ if modstaledeps === true
1974+ continue
19981975 end
1976+ modstaledeps, modocachepath, _ = modstaledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1977+ staledeps[i] = (modpath, modkey, modbuild_id, modpath_to_try, modstaledeps, modocachepath)
1978+ @goto check_next_dep
1979+ end
1980+ @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $(UUID (modbuild_id)) is missing from the cache."
1981+ @goto check_next_path
1982+ @label check_next_dep
1983+ end
1984+ M = maybe_loaded_precompile (pkg, newbuild_id)
1985+ if isa (M, Module)
1986+ stalecheck && register_root_module (M)
1987+ return M
1988+ end
1989+ if stalecheck
1990+ try
1991+ touch (path_to_try) # update timestamp of precompilation file
1992+ catch ex # file might be read-only and then we fail to update timestamp, which is fine
1993+ ex isa IOError || rethrow ()
19991994 end
2000- if dep === nothing
2001- try
2002- set_pkgorigin_version_path (modkey, modpath)
2003- dep = _include_from_serialized (modkey, modcachepath, modocachepath, modstaledeps; register = stalecheck)
2004- finally
2005- end_loading (modkey, dep)
1995+ end
1996+ # finish loading module graph into staledeps
1997+ # TODO : call all start_loading calls (in reverse order) before calling any _include_from_serialized, since start_loading will drop the loading lock
1998+ for i in eachindex (staledeps)
1999+ dep = staledeps[i]
2000+ dep isa Module && continue
2001+ modpath, modkey, modbuild_id, modcachepath, modstaledeps, modocachepath = dep:: Tuple{String, PkgId, UInt128, String, Vector{Any}, Union{Nothing, String}}
2002+ dep = start_loading (modkey, modbuild_id, stalecheck)
2003+ while true
2004+ if dep isa Module
2005+ if PkgId (dep) == modkey && module_build_id (dep) === modbuild_id
2006+ break
2007+ else
2008+ @debug " Rejecting cache file $path_to_try because module $modkey got loaded at a different version than expected."
2009+ @goto check_next_path
2010+ end
20062011 end
2007- if ! isa (dep, Module)
2008- @debug " Rejecting cache file $path_to_try because required dependency $modkey failed to load from cache file for $modcachepath ." exception= dep
2009- @goto check_next_path
2010- else
2011- push! (newdeps, modkey)
2012+ if dep === nothing
2013+ try
2014+ set_pkgorigin_version_path (modkey, modpath)
2015+ dep = _include_from_serialized (modkey, modcachepath, modocachepath, modstaledeps; register = stalecheck)
2016+ finally
2017+ end_loading (modkey, dep)
2018+ end
2019+ if ! isa (dep, Module)
2020+ @debug " Rejecting cache file $path_to_try because required dependency $modkey failed to load from cache file for $modcachepath ." exception= dep
2021+ @goto check_next_path
2022+ else
2023+ push! (newdeps, modkey)
2024+ end
20122025 end
20132026 end
2027+ staledeps[i] = dep
20142028 end
2015- staledeps[i] = dep
2016- end
2017- restored = get (loaded_precompiles, pkg => newbuild_id, nothing )
2018- if ! isa (restored, Module)
2019- restored = _include_from_serialized (pkg, path_to_try, ocachefile, staledeps; register = stalecheck)
2020- end
2021- isa (restored, Module) && return restored
2022- @debug " Deserialization checks failed while attempting to load cache from $path_to_try " exception = restored
2023- @label check_next_path
2024- finally
2025- for modkey in newdeps
2026- insert_extension_triggers (modkey)
2027- stalecheck && run_package_callbacks (modkey )
2029+ restored = maybe_loaded_precompile (pkg, newbuild_id)
2030+ if ! isa (restored, Module)
2031+ restored = _include_from_serialized (pkg, path_to_try, ocachefile, staledeps; register = stalecheck )
2032+ end
2033+ isa (restored, Module) && return restored
2034+ @debug " Deserialization checks failed while attempting to load cache from $path_to_try " exception = restored
2035+ @label check_next_path
2036+ finally
2037+ for modkey in newdeps
2038+ insert_extension_triggers (modkey)
2039+ stalecheck && run_package_callbacks (modkey)
2040+ end
2041+ empty! (newdeps )
20282042 end
2029- empty! (newdeps)
20302043 end
20312044 end
20322045 return nothing
@@ -2045,7 +2058,7 @@ function start_loading(modkey::PkgId, build_id::UInt128, stalecheck::Bool)
20452058 loaded = stalecheck ? maybe_root_module (modkey) : nothing
20462059 loaded isa Module && return loaded
20472060 if build_id != UInt128 (0 )
2048- loaded = get (loaded_precompiles, modkey => build_id, nothing )
2061+ loaded = maybe_loaded_precompile ( modkey, build_id )
20492062 loaded isa Module && return loaded
20502063 end
20512064 loading = get (package_locks, modkey, nothing )
@@ -2375,12 +2388,21 @@ const pkgorigins = Dict{PkgId,PkgOrigin}()
23752388
23762389const explicit_loaded_modules = Dict {PkgId,Module} () # Emptied on Julia start
23772390const loaded_modules = Dict {PkgId,Module} () # available to be explicitly loaded
2378- const loaded_precompiles = Dict {Pair{ PkgId,UInt128}, Module} () # extended (complete) list of modules, available to be loaded
2391+ const loaded_precompiles = Dict {PkgId,Vector{ Module} } () # extended (complete) list of modules, available to be loaded
23792392const loaded_modules_order = Vector {Module} ()
23802393const module_keys = IdDict {Module,PkgId} () # the reverse of loaded_modules
23812394
23822395root_module_key (m:: Module ) = @lock require_lock module_keys[m]
23832396
2397+ function maybe_loaded_precompile (key:: PkgId , buildid:: UInt128 )
2398+ assert_havelock (require_lock)
2399+ mods = get (loaded_precompiles, key, nothing )
2400+ mods === nothing && return
2401+ for mod in mods
2402+ module_build_id (mod) == buildid && return mod
2403+ end
2404+ end
2405+
23842406function module_build_id (m:: Module )
23852407 hi, lo = ccall (:jl_module_build_id , NTuple{2 ,UInt64}, (Any,), m)
23862408 return (UInt128 (hi) << 64 ) | lo
@@ -2401,7 +2423,7 @@ end
24012423 end
24022424 end
24032425 end
2404- haskey (loaded_precompiles, key => module_build_id (m)) || push! (loaded_modules_order, m)
2426+ maybe_loaded_precompile (key, module_build_id (m)) === nothing && push! (loaded_modules_order, m)
24052427 loaded_modules[key] = m
24062428 explicit_loaded_modules[key] = m
24072429 module_keys[m] = key
@@ -3781,8 +3803,8 @@ end
37813803 for i in 1 : ndeps
37823804 req_key, req_build_id = required_modules[i]
37833805 # Check if module is already loaded
3784- if ! stalecheck && haskey (loaded_precompiles, req_key => req_build_id)
3785- M = loaded_precompiles[req_key => req_build_id]
3806+ M = stalecheck ? nothing : maybe_loaded_precompile (req_key, req_build_id)
3807+ if M != = nothing
37863808 @assert PkgId (M) == req_key && module_build_id (M) === req_build_id
37873809 depmods[i] = M
37883810 elseif root_module_exists (req_key)
0 commit comments