@@ -1232,7 +1232,7 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
1232
1232
dep = depmods[i]
1233
1233
dep isa Module && continue
1234
1234
_, depkey, depbuild_id = dep:: Tuple{String, PkgId, UInt128}
1235
- dep = loaded_precompiles[ depkey => depbuild_id]
1235
+ dep = something ( maybe_loaded_precompile ( depkey, depbuild_id))
1236
1236
@assert PkgId (dep) == depkey && module_build_id (dep) === depbuild_id
1237
1237
depmods[i] = dep
1238
1238
end
@@ -1338,6 +1338,7 @@ end
1338
1338
1339
1339
function register_restored_modules (sv:: SimpleVector , pkg:: PkgId , path:: String )
1340
1340
# This function is also used by PkgCacheInspector.jl
1341
+ assert_havelock (require_lock)
1341
1342
restored = sv[1 ]:: Vector{Any}
1342
1343
for M in restored
1343
1344
M = M:: Module
@@ -1346,7 +1347,7 @@ function register_restored_modules(sv::SimpleVector, pkg::PkgId, path::String)
1346
1347
end
1347
1348
if parentmodule (M) === M
1348
1349
push! (loaded_modules_order, M)
1349
- loaded_precompiles[pkg => module_build_id (M)] = M
1350
+ push! ( get! (Vector{Module}, loaded_precompiles, pkg), M)
1350
1351
end
1351
1352
end
1352
1353
@@ -1962,90 +1963,102 @@ end
1962
1963
assert_havelock (require_lock)
1963
1964
paths = find_all_in_cache_path (pkg, DEPOT_PATH )
1964
1965
newdeps = PkgId[]
1965
- for path_to_try in paths:: Vector{String}
1966
- staledeps = stale_cachefile (pkg, build_id, sourcepath, path_to_try; reasons, stalecheck)
1967
- if staledeps === true
1968
- continue
1969
- end
1970
- try
1971
- staledeps, ocachefile, newbuild_id = staledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1972
- # finish checking staledeps module graph
1973
- for i in eachindex (staledeps)
1974
- dep = staledeps[i]
1975
- dep isa Module && continue
1976
- modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt128}
1977
- modpaths = find_all_in_cache_path (modkey, DEPOT_PATH )
1978
- for modpath_to_try in modpaths
1979
- modstaledeps = stale_cachefile (modkey, modbuild_id, modpath, modpath_to_try; stalecheck)
1980
- if modstaledeps === true
1981
- continue
1982
- end
1983
- modstaledeps, modocachepath, _ = modstaledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1984
- staledeps[i] = (modpath, modkey, modbuild_id, modpath_to_try, modstaledeps, modocachepath)
1985
- @goto check_next_dep
1966
+ try_build_ids = UInt128[build_id]
1967
+ if build_id == UInt128 (0 )
1968
+ let loaded = get (loaded_precompiles, pkg, nothing )
1969
+ if loaded != = nothing
1970
+ for mod in loaded # try these in reverse original load order to see if one is already valid
1971
+ pushfirst! (try_build_ids, module_build_id (mod))
1986
1972
end
1987
- @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $(UUID (modbuild_id)) is missing from the cache."
1988
- @goto check_next_path
1989
- @label check_next_dep
1990
1973
end
1991
- M = get (loaded_precompiles, pkg => newbuild_id, nothing )
1992
- if isa (M, Module)
1993
- stalecheck && register_root_module (M)
1994
- return M
1995
- end
1996
- if stalecheck
1997
- try
1998
- touch (path_to_try) # update timestamp of precompilation file
1999
- catch ex # file might be read-only and then we fail to update timestamp, which is fine
2000
- ex isa IOError || rethrow ()
2001
- end
1974
+ end
1975
+ end
1976
+ for build_id in try_build_ids
1977
+ for path_to_try in paths:: Vector{String}
1978
+ staledeps = stale_cachefile (pkg, build_id, sourcepath, path_to_try; reasons, stalecheck)
1979
+ if staledeps === true
1980
+ continue
2002
1981
end
2003
- # finish loading module graph into staledeps
2004
- # TODO : call all start_loading calls (in reverse order) before calling any _include_from_serialized, since start_loading will drop the loading lock
2005
- for i in eachindex (staledeps)
2006
- dep = staledeps[i]
2007
- dep isa Module && continue
2008
- modpath, modkey, modbuild_id, modcachepath, modstaledeps, modocachepath = dep:: Tuple{String, PkgId, UInt128, String, Vector{Any}, Union{Nothing, String}}
2009
- dep = start_loading (modkey, modbuild_id, stalecheck)
2010
- while true
2011
- if dep isa Module
2012
- if PkgId (dep) == modkey && module_build_id (dep) === modbuild_id
2013
- break
2014
- else
2015
- @debug " Rejecting cache file $path_to_try because module $modkey got loaded at a different version than expected."
2016
- @goto check_next_path
1982
+ try
1983
+ staledeps, ocachefile, newbuild_id = staledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1984
+ # finish checking staledeps module graph
1985
+ for i in eachindex (staledeps)
1986
+ dep = staledeps[i]
1987
+ dep isa Module && continue
1988
+ modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt128}
1989
+ modpaths = find_all_in_cache_path (modkey, DEPOT_PATH )
1990
+ for modpath_to_try in modpaths
1991
+ modstaledeps = stale_cachefile (modkey, modbuild_id, modpath, modpath_to_try; stalecheck)
1992
+ if modstaledeps === true
1993
+ continue
2017
1994
end
1995
+ modstaledeps, modocachepath, _ = modstaledeps:: Tuple{Vector{Any}, Union{Nothing, String}, UInt128}
1996
+ staledeps[i] = (modpath, modkey, modbuild_id, modpath_to_try, modstaledeps, modocachepath)
1997
+ @goto check_next_dep
2018
1998
end
2019
- if dep === nothing
2020
- try
2021
- set_pkgorigin_version_path (modkey, modpath)
2022
- dep = _include_from_serialized (modkey, modcachepath, modocachepath, modstaledeps; register = stalecheck)
2023
- finally
2024
- end_loading (modkey, dep)
1999
+ @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $(UUID (modbuild_id)) is missing from the cache."
2000
+ @goto check_next_path
2001
+ @label check_next_dep
2002
+ end
2003
+ M = maybe_loaded_precompile (pkg, newbuild_id)
2004
+ if isa (M, Module)
2005
+ stalecheck && register_root_module (M)
2006
+ return M
2007
+ end
2008
+ if stalecheck
2009
+ try
2010
+ touch (path_to_try) # update timestamp of precompilation file
2011
+ catch ex # file might be read-only and then we fail to update timestamp, which is fine
2012
+ ex isa IOError || rethrow ()
2013
+ end
2014
+ end
2015
+ # finish loading module graph into staledeps
2016
+ # TODO : call all start_loading calls (in reverse order) before calling any _include_from_serialized, since start_loading will drop the loading lock
2017
+ for i in eachindex (staledeps)
2018
+ dep = staledeps[i]
2019
+ dep isa Module && continue
2020
+ modpath, modkey, modbuild_id, modcachepath, modstaledeps, modocachepath = dep:: Tuple{String, PkgId, UInt128, String, Vector{Any}, Union{Nothing, String}}
2021
+ dep = start_loading (modkey, modbuild_id, stalecheck)
2022
+ while true
2023
+ if dep isa Module
2024
+ if PkgId (dep) == modkey && module_build_id (dep) === modbuild_id
2025
+ break
2026
+ else
2027
+ @debug " Rejecting cache file $path_to_try because module $modkey got loaded at a different version than expected."
2028
+ @goto check_next_path
2029
+ end
2025
2030
end
2026
- if ! isa (dep, Module)
2027
- @debug " Rejecting cache file $path_to_try because required dependency $modkey failed to load from cache file for $modcachepath ." exception= dep
2028
- @goto check_next_path
2029
- else
2030
- push! (newdeps, modkey)
2031
+ if dep === nothing
2032
+ try
2033
+ set_pkgorigin_version_path (modkey, modpath)
2034
+ dep = _include_from_serialized (modkey, modcachepath, modocachepath, modstaledeps; register = stalecheck)
2035
+ finally
2036
+ end_loading (modkey, dep)
2037
+ end
2038
+ if ! isa (dep, Module)
2039
+ @debug " Rejecting cache file $path_to_try because required dependency $modkey failed to load from cache file for $modcachepath ." exception= dep
2040
+ @goto check_next_path
2041
+ else
2042
+ push! (newdeps, modkey)
2043
+ end
2031
2044
end
2032
2045
end
2046
+ staledeps[i] = dep
2033
2047
end
2034
- staledeps[i] = dep
2035
- end
2036
- restored = get (loaded_precompiles, pkg => newbuild_id, nothing )
2037
- if ! isa (restored, Module)
2038
- restored = _include_from_serialized (pkg, path_to_try, ocachefile, staledeps; register = stalecheck)
2039
- end
2040
- isa (restored, Module) && return restored
2041
- @debug " Deserialization checks failed while attempting to load cache from $path_to_try " exception = restored
2042
- @label check_next_path
2043
- finally
2044
- for modkey in newdeps
2045
- insert_extension_triggers (modkey)
2046
- stalecheck && run_package_callbacks (modkey )
2048
+ restored = maybe_loaded_precompile (pkg, newbuild_id)
2049
+ if ! isa (restored, Module)
2050
+ restored = _include_from_serialized (pkg, path_to_try, ocachefile, staledeps; register = stalecheck )
2051
+ end
2052
+ isa (restored, Module) && return restored
2053
+ @debug " Deserialization checks failed while attempting to load cache from $path_to_try " exception = restored
2054
+ @label check_next_path
2055
+ finally
2056
+ for modkey in newdeps
2057
+ insert_extension_triggers (modkey)
2058
+ stalecheck && run_package_callbacks (modkey)
2059
+ end
2060
+ empty! (newdeps )
2047
2061
end
2048
- empty! (newdeps)
2049
2062
end
2050
2063
end
2051
2064
return nothing
@@ -2065,7 +2078,7 @@ function start_loading(modkey::PkgId, build_id::UInt128, stalecheck::Bool)
2065
2078
loaded = stalecheck ? maybe_root_module (modkey) : nothing
2066
2079
loaded isa Module && return loaded
2067
2080
if build_id != UInt128 (0 )
2068
- loaded = get (loaded_precompiles, modkey => build_id, nothing )
2081
+ loaded = maybe_loaded_precompile ( modkey, build_id )
2069
2082
loaded isa Module && return loaded
2070
2083
end
2071
2084
loading = get (package_locks, modkey, nothing )
@@ -2394,13 +2407,22 @@ const pkgorigins = Dict{PkgId,PkgOrigin}()
2394
2407
2395
2408
const explicit_loaded_modules = Dict {PkgId,Module} () # Emptied on Julia start
2396
2409
const loaded_modules = Dict {PkgId,Module} () # available to be explicitly loaded
2397
- const loaded_precompiles = Dict {Pair{ PkgId,UInt128}, Module} () # extended (complete) list of modules, available to be loaded
2410
+ const loaded_precompiles = Dict {PkgId,Vector{ Module} } () # extended (complete) list of modules, available to be loaded
2398
2411
const loaded_modules_order = Vector {Module} ()
2399
2412
const module_keys = IdDict {Module,PkgId} () # the reverse of loaded_modules
2400
2413
2401
2414
is_root_module (m:: Module ) = @lock require_lock haskey (module_keys, m)
2402
2415
root_module_key (m:: Module ) = @lock require_lock module_keys[m]
2403
2416
2417
+ function maybe_loaded_precompile (key:: PkgId , buildid:: UInt128 )
2418
+ assert_havelock (require_lock)
2419
+ mods = get (loaded_precompiles, key, nothing )
2420
+ mods === nothing && return
2421
+ for mod in mods
2422
+ module_build_id (mod) == buildid && return mod
2423
+ end
2424
+ end
2425
+
2404
2426
function module_build_id (m:: Module )
2405
2427
hi, lo = ccall (:jl_module_build_id , NTuple{2 ,UInt64}, (Any,), m)
2406
2428
return (UInt128 (hi) << 64 ) | lo
@@ -2421,7 +2443,7 @@ end
2421
2443
end
2422
2444
end
2423
2445
end
2424
- haskey (loaded_precompiles, key => module_build_id (m)) || push! (loaded_modules_order, m)
2446
+ maybe_loaded_precompile (key, module_build_id (m)) === nothing && push! (loaded_modules_order, m)
2425
2447
loaded_modules[key] = m
2426
2448
explicit_loaded_modules[key] = m
2427
2449
module_keys[m] = key
@@ -3785,8 +3807,8 @@ end
3785
3807
for i in 1 : ndeps
3786
3808
req_key, req_build_id = required_modules[i]
3787
3809
# Check if module is already loaded
3788
- if ! stalecheck && haskey (loaded_precompiles, req_key => req_build_id)
3789
- M = loaded_precompiles[req_key => req_build_id]
3810
+ M = stalecheck ? nothing : maybe_loaded_precompile (req_key, req_build_id)
3811
+ if M != = nothing
3790
3812
@assert PkgId (M) == req_key && module_build_id (M) === req_build_id
3791
3813
depmods[i] = M
3792
3814
elseif root_module_exists (req_key)
0 commit comments