@@ -898,7 +898,7 @@ function _include_from_serialized(pkg::PkgId, path::String, depmods::Vector{Any}
898
898
end
899
899
900
900
@debug " Loading cache file $path for $pkg "
901
- sv = ccall (:jl_restore_incremental , Any, (Cstring, Any), path, depmods)
901
+ sv = ccall (:jl_restore_incremental , Any, (Cstring, Any, Cint ), path, depmods, false )
902
902
if isa (sv, Exception)
903
903
return sv
904
904
end
@@ -973,7 +973,7 @@ function run_package_callbacks(modkey::PkgId)
973
973
end
974
974
975
975
# loads a precompile cache file, after checking stale_cachefile tests
976
- function _tryrequire_from_serialized (modkey:: PkgId , build_id:: UInt64 )
976
+ function _tryrequire_from_serialized (modkey:: PkgId , build_id:: UInt128 )
977
977
assert_havelock (require_lock)
978
978
loaded = nothing
979
979
if root_module_exists (modkey)
@@ -1021,7 +1021,7 @@ function _tryrequire_from_serialized(modkey::PkgId, path::String, sourcepath::St
1021
1021
for i in 1 : length (depmods)
1022
1022
dep = depmods[i]
1023
1023
dep isa Module && continue
1024
- _, depkey, depbuild_id = dep:: Tuple{String, PkgId, UInt64 }
1024
+ _, depkey, depbuild_id = dep:: Tuple{String, PkgId, UInt128 }
1025
1025
@assert root_module_exists (depkey)
1026
1026
dep = root_module (depkey)
1027
1027
depmods[i] = dep
@@ -1052,7 +1052,7 @@ function _tryrequire_from_serialized(pkg::PkgId, path::String)
1052
1052
local depmodnames
1053
1053
io = open (path, " r" )
1054
1054
try
1055
- isvalid_cache_header (io) || return ArgumentError (" Invalid header in cache file $path ." )
1055
+ iszero ( isvalid_cache_header (io)) && return ArgumentError (" Invalid header in cache file $path ." )
1056
1056
depmodnames = parse_cache_header (io)[3 ]
1057
1057
isvalid_file_crc (io) || return ArgumentError (" Invalid checksum in cache file $path ." )
1058
1058
finally
@@ -1074,7 +1074,7 @@ end
1074
1074
1075
1075
# returns `nothing` if require found a precompile cache for this sourcepath, but couldn't load it
1076
1076
# returns the set of modules restored if the cache load succeeded
1077
- @constprop :none function _require_search_from_serialized (pkg:: PkgId , sourcepath:: String , build_id:: UInt64 )
1077
+ @constprop :none function _require_search_from_serialized (pkg:: PkgId , sourcepath:: String , build_id:: UInt128 )
1078
1078
assert_havelock (require_lock)
1079
1079
paths = find_all_in_cache_path (pkg)
1080
1080
for path_to_try in paths:: Vector{String}
@@ -1087,7 +1087,7 @@ end
1087
1087
for i in 1 : length (staledeps)
1088
1088
dep = staledeps[i]
1089
1089
dep isa Module && continue
1090
- modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt64 }
1090
+ modpath, modkey, modbuild_id = dep:: Tuple{String, PkgId, UInt128 }
1091
1091
modpaths = find_all_in_cache_path (modkey)
1092
1092
modfound = false
1093
1093
for modpath_to_try in modpaths:: Vector{String}
@@ -1101,7 +1101,7 @@ end
1101
1101
break
1102
1102
end
1103
1103
if ! modfound
1104
- @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $modbuild_id is missing from the cache."
1104
+ @debug " Rejecting cache file $path_to_try because required dependency $modkey with build ID $( UUID ( modbuild_id)) is missing from the cache."
1105
1105
staledeps = true
1106
1106
break
1107
1107
end
@@ -1153,7 +1153,7 @@ const package_callbacks = Any[]
1153
1153
const include_callbacks = Any[]
1154
1154
1155
1155
# used to optionally track dependencies when requiring a module:
1156
- const _concrete_dependencies = Pair{PkgId,UInt64 }[] # these dependency versions are "set in stone", and the process should try to avoid invalidating them
1156
+ const _concrete_dependencies = Pair{PkgId,UInt128 }[] # these dependency versions are "set in stone", and the process should try to avoid invalidating them
1157
1157
const _require_dependencies = Any[] # a list of (mod, path, mtime) tuples that are the file dependencies of the module currently being precompiled
1158
1158
const _track_dependencies = Ref (false ) # set this to true to track the list of file dependencies
1159
1159
function _include_dependency (mod:: Module , _path:: AbstractString )
@@ -1406,7 +1406,7 @@ function _require(pkg::PkgId, env=nothing)
1406
1406
1407
1407
# attempt to load the module file via the precompile cache locations
1408
1408
if JLOptions (). use_compiled_modules != 0
1409
- m = _require_search_from_serialized (pkg, path, UInt64 (0 ))
1409
+ m = _require_search_from_serialized (pkg, path, UInt128 (0 ))
1410
1410
if m isa Module
1411
1411
return m
1412
1412
end
@@ -1416,7 +1416,7 @@ function _require(pkg::PkgId, env=nothing)
1416
1416
# but it was not handled by the precompile loader, complain
1417
1417
for (concrete_pkg, concrete_build_id) in _concrete_dependencies
1418
1418
if pkg == concrete_pkg
1419
- @warn """ Module $(pkg. name) with build ID $concrete_build_id is missing from the cache.
1419
+ @warn """ Module $(pkg. name) with build ID $(( UUID ( concrete_build_id))) is missing from the cache.
1420
1420
This may mean $pkg does not support precompilation but is imported by a module that does."""
1421
1421
if JLOptions (). incremental != 0
1422
1422
# during incremental precompilation, this should be fail-fast
@@ -1785,9 +1785,13 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
1785
1785
close (tmpio)
1786
1786
p = create_expr_cache (pkg, path, tmppath, concrete_deps, internal_stderr, internal_stdout)
1787
1787
if success (p)
1788
- # append checksum to the end of the .ji file:
1789
- open (tmppath, " a+" ) do f
1790
- write (f, _crc32c (seekstart (f)))
1788
+ # append extra crc to the end of the .ji file:
1789
+ open (tmppath, " r+" ) do f
1790
+ if iszero (isvalid_cache_header (f))
1791
+ error (" Invalid header for $pkg in new cache file $(repr (tmppath)) ." )
1792
+ end
1793
+ seekstart (f)
1794
+ write (f, _crc32c (f))
1791
1795
end
1792
1796
# inherit permission from the source file (and make them writable)
1793
1797
chmod (tmppath, filemode (path) & 0o777 | 0o200 )
@@ -1807,7 +1811,7 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
1807
1811
end
1808
1812
end
1809
1813
1810
- # this is atomic according to POSIX:
1814
+ # this is atomic according to POSIX (not Win32) :
1811
1815
rename (tmppath, cachefile; force= true )
1812
1816
return cachefile
1813
1817
end
@@ -1817,13 +1821,16 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
1817
1821
if p. exitcode == 125
1818
1822
return PrecompilableError ()
1819
1823
else
1820
- error (" Failed to precompile $pkg to $tmppath ." )
1824
+ error (" Failed to precompile $pkg to $( repr ( tmppath)) ." )
1821
1825
end
1822
1826
end
1823
1827
1824
- module_build_id (m:: Module ) = ccall (:jl_module_build_id , UInt64, (Any,), m)
1828
+ function module_build_id (m:: Module )
1829
+ hi, lo = ccall (:jl_module_build_id , NTuple{2 ,UInt64}, (Any,), m)
1830
+ return (UInt128 (hi) << 64 ) | lo
1831
+ end
1825
1832
1826
- isvalid_cache_header (f:: IOStream ) = ( 0 != ccall (:jl_read_verify_header , Cint , (Ptr{Cvoid},), f. ios))
1833
+ isvalid_cache_header (f:: IOStream ) = ccall (:jl_read_verify_header , UInt64 , (Ptr{Cvoid},), f. ios) # returns checksum id or zero
1827
1834
isvalid_file_crc (f:: IOStream ) = (_crc32c (seekstart (f), filesize (f) - 4 ) == read (f, UInt32))
1828
1835
1829
1836
struct CacheHeaderIncludes
@@ -1897,13 +1904,14 @@ function parse_cache_header(f::IO)
1897
1904
totbytes -= 8
1898
1905
@assert totbytes == 0 " header of cache file appears to be corrupt (totbytes == $(totbytes) )"
1899
1906
# read the list of modules that are required to be present during loading
1900
- required_modules = Vector {Pair{PkgId, UInt64 }} ()
1907
+ required_modules = Vector {Pair{PkgId, UInt128 }} ()
1901
1908
while true
1902
1909
n = read (f, Int32)
1903
1910
n == 0 && break
1904
1911
sym = String (read (f, n)) # module name
1905
1912
uuid = UUID ((read (f, UInt64), read (f, UInt64))) # pkg UUID
1906
- build_id = read (f, UInt64) # build id
1913
+ build_id = UInt128 (read (f, UInt64)) << 64
1914
+ build_id |= read (f, UInt64)
1907
1915
push! (required_modules, PkgId (uuid, sym) => build_id)
1908
1916
end
1909
1917
return modules, (includes, requires), required_modules, srctextpos, prefs, prefs_hash
@@ -1912,29 +1920,29 @@ end
1912
1920
function parse_cache_header (cachefile:: String ; srcfiles_only:: Bool = false )
1913
1921
io = open (cachefile, " r" )
1914
1922
try
1915
- ! isvalid_cache_header (io) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1923
+ iszero ( isvalid_cache_header (io) ) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1916
1924
ret = parse_cache_header (io)
1917
1925
srcfiles_only || return ret
1918
- modules , (includes, requires ), required_modules , srctextpos, prefs, prefs_hash = ret
1926
+ _ , (includes, _ ), _ , srctextpos, _ ... = ret
1919
1927
srcfiles = srctext_files (io, srctextpos)
1920
1928
delidx = Int[]
1921
1929
for (i, chi) in enumerate (includes)
1922
1930
chi. filename ∈ srcfiles || push! (delidx, i)
1923
1931
end
1924
1932
deleteat! (includes, delidx)
1925
- return modules, (includes, requires), required_modules, srctextpos, prefs, prefs_hash
1933
+ return ret
1926
1934
finally
1927
1935
close (io)
1928
1936
end
1929
1937
end
1930
1938
1931
1939
1932
1940
1933
- preferences_hash (f:: IO ) = parse_cache_header (f)[end ]
1941
+ preferences_hash (f:: IO ) = parse_cache_header (f)[6 ]
1934
1942
function preferences_hash (cachefile:: String )
1935
1943
io = open (cachefile, " r" )
1936
1944
try
1937
- if ! isvalid_cache_header (io)
1945
+ if iszero ( isvalid_cache_header (io) )
1938
1946
throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1939
1947
end
1940
1948
return preferences_hash (io)
@@ -1945,22 +1953,22 @@ end
1945
1953
1946
1954
1947
1955
function cache_dependencies (f:: IO )
1948
- defs , (includes, requires ), modules, srctextpos, prefs, prefs_hash = parse_cache_header (f)
1956
+ _ , (includes, _ ), modules, _ ... = parse_cache_header (f)
1949
1957
return modules, map (chi -> (chi. filename, chi. mtime), includes) # return just filename and mtime
1950
1958
end
1951
1959
1952
1960
function cache_dependencies (cachefile:: String )
1953
1961
io = open (cachefile, " r" )
1954
1962
try
1955
- ! isvalid_cache_header (io) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1963
+ iszero ( isvalid_cache_header (io) ) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1956
1964
return cache_dependencies (io)
1957
1965
finally
1958
1966
close (io)
1959
1967
end
1960
1968
end
1961
1969
1962
1970
function read_dependency_src (io:: IO , filename:: AbstractString )
1963
- modules, (includes, requires), required_modules, srctextpos, prefs, prefs_hash = parse_cache_header (io)
1971
+ srctextpos = parse_cache_header (io)[ 4 ]
1964
1972
srctextpos == 0 && error (" no source-text stored in cache file" )
1965
1973
seek (io, srctextpos)
1966
1974
return _read_dependency_src (io, filename)
@@ -1983,7 +1991,7 @@ end
1983
1991
function read_dependency_src (cachefile:: String , filename:: AbstractString )
1984
1992
io = open (cachefile, " r" )
1985
1993
try
1986
- ! isvalid_cache_header (io) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1994
+ iszero ( isvalid_cache_header (io) ) && throw (ArgumentError (" Invalid header in cache file $cachefile ." ))
1987
1995
return read_dependency_src (io, filename)
1988
1996
finally
1989
1997
close (io)
@@ -2173,12 +2181,13 @@ get_compiletime_preferences(::Nothing) = String[]
2173
2181
# returns true if it "cachefile.ji" is stale relative to "modpath.jl" and build_id for modkey
2174
2182
# otherwise returns the list of dependencies to also check
2175
2183
@constprop :none function stale_cachefile (modpath:: String , cachefile:: String ; ignore_loaded:: Bool = false )
2176
- return stale_cachefile (PkgId (" " ), UInt64 (0 ), modpath, cachefile; ignore_loaded)
2184
+ return stale_cachefile (PkgId (" " ), UInt128 (0 ), modpath, cachefile; ignore_loaded)
2177
2185
end
2178
- @constprop :none function stale_cachefile (modkey:: PkgId , build_id:: UInt64 , modpath:: String , cachefile:: String ; ignore_loaded:: Bool = false )
2186
+ @constprop :none function stale_cachefile (modkey:: PkgId , build_id:: UInt128 , modpath:: String , cachefile:: String ; ignore_loaded:: Bool = false )
2179
2187
io = open (cachefile, " r" )
2180
2188
try
2181
- if ! isvalid_cache_header (io)
2189
+ checksum = isvalid_cache_header (io)
2190
+ if iszero (checksum)
2182
2191
@debug " Rejecting cache file $cachefile due to it containing an invalid cache header"
2183
2192
return true # invalid cache file
2184
2193
end
@@ -2191,9 +2200,12 @@ end
2191
2200
@debug " Rejecting cache file $cachefile for $modkey since it is for $id instead"
2192
2201
return true
2193
2202
end
2194
- if build_id != UInt64 (0 ) && id. second != build_id
2195
- @debug " Ignoring cache file $cachefile for $modkey since it is does not provide desired build_id"
2196
- return true
2203
+ if build_id != UInt128 (0 )
2204
+ id_build = (UInt128 (checksum) << 64 ) | id. second
2205
+ if id_build != build_id
2206
+ @debug " Ignoring cache file $cachefile for $modkey ($((UUID (id_build))) ) since it is does not provide desired build_id ($((UUID (build_id))) )"
2207
+ return true
2208
+ end
2197
2209
end
2198
2210
id = id. first
2199
2211
modules = Dict {PkgId, UInt64} (modules)
@@ -2233,11 +2245,12 @@ end
2233
2245
for (req_key, req_build_id) in _concrete_dependencies
2234
2246
build_id = get (modules, req_key, UInt64 (0 ))
2235
2247
if build_id != = UInt64 (0 )
2248
+ build_id |= UInt128 (checksum) << 64
2236
2249
if build_id === req_build_id
2237
2250
skip_timecheck = true
2238
2251
break
2239
2252
end
2240
- @debug " Rejecting cache file $cachefile because it provides the wrong build_id (got $build_id ) for $req_key (want $req_build_id )"
2253
+ @debug " Rejecting cache file $cachefile because it provides the wrong build_id (got $(( UUID ( build_id))) ) for $req_key (want $( UUID ( req_build_id)) )"
2241
2254
return true # cachefile doesn't provide the required version of the dependency
2242
2255
end
2243
2256
end
0 commit comments