@@ -1231,7 +1231,7 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
1231
1231
dep = depmods[i]
1232
1232
dep isa Module && continue
1233
1233
_, depkey, depbuild_id = dep:: Tuple{String, PkgId, UInt128}
1234
- dep = loaded_precompiles[ depkey => depbuild_id]
1234
+ dep = something ( maybe_loaded_precompile ( depkey, depbuild_id))
1235
1235
@assert PkgId (dep) == depkey && module_build_id (dep) === depbuild_id
1236
1236
depmods[i] = dep
1237
1237
end
@@ -1337,6 +1337,7 @@ end
1337
1337
1338
1338
function register_restored_modules (sv:: SimpleVector , pkg:: PkgId , path:: String )
1339
1339
# This function is also used by PkgCacheInspector.jl
1340
+ assert_havelock (require_lock)
1340
1341
restored = sv[1 ]:: Vector{Any}
1341
1342
for M in restored
1342
1343
M = M:: Module
@@ -1345,7 +1346,7 @@ function register_restored_modules(sv::SimpleVector, pkg::PkgId, path::String)
1345
1346
end
1346
1347
if parentmodule (M) === M
1347
1348
push! (loaded_modules_order, M)
1348
- loaded_precompiles[pkg => module_build_id (M)] = M
1349
+ push! ( get! (Vector{Module}, loaded_precompiles, pkg), M)
1349
1350
end
1350
1351
end
1351
1352
@@ -1943,90 +1944,102 @@ end
1943
1944
assert_havelock (require_lock)
1944
1945
paths = find_all_in_cache_path (pkg, DEPOT_PATH )
1945
1946
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))
1967
1953
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
1976
1954
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
1983
1962
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
1998
1975
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 ()
1999
1994
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
2006
2011
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
2012
2025
end
2013
2026
end
2027
+ staledeps[i] = dep
2014
2028
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 )
2028
2042
end
2029
- empty! (newdeps)
2030
2043
end
2031
2044
end
2032
2045
return nothing
@@ -2045,7 +2058,7 @@ function start_loading(modkey::PkgId, build_id::UInt128, stalecheck::Bool)
2045
2058
loaded = stalecheck ? maybe_root_module (modkey) : nothing
2046
2059
loaded isa Module && return loaded
2047
2060
if build_id != UInt128 (0 )
2048
- loaded = get (loaded_precompiles, modkey => build_id, nothing )
2061
+ loaded = maybe_loaded_precompile ( modkey, build_id )
2049
2062
loaded isa Module && return loaded
2050
2063
end
2051
2064
loading = get (package_locks, modkey, nothing )
@@ -2375,12 +2388,21 @@ const pkgorigins = Dict{PkgId,PkgOrigin}()
2375
2388
2376
2389
const explicit_loaded_modules = Dict {PkgId,Module} () # Emptied on Julia start
2377
2390
const 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
2379
2392
const loaded_modules_order = Vector {Module} ()
2380
2393
const module_keys = IdDict {Module,PkgId} () # the reverse of loaded_modules
2381
2394
2382
2395
root_module_key (m:: Module ) = @lock require_lock module_keys[m]
2383
2396
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
+
2384
2406
function module_build_id (m:: Module )
2385
2407
hi, lo = ccall (:jl_module_build_id , NTuple{2 ,UInt64}, (Any,), m)
2386
2408
return (UInt128 (hi) << 64 ) | lo
@@ -2401,7 +2423,7 @@ end
2401
2423
end
2402
2424
end
2403
2425
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)
2405
2427
loaded_modules[key] = m
2406
2428
explicit_loaded_modules[key] = m
2407
2429
module_keys[m] = key
@@ -3781,8 +3803,8 @@ end
3781
3803
for i in 1 : ndeps
3782
3804
req_key, req_build_id = required_modules[i]
3783
3805
# 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
3786
3808
@assert PkgId (M) == req_key && module_build_id (M) === req_build_id
3787
3809
depmods[i] = M
3788
3810
elseif root_module_exists (req_key)
0 commit comments