@@ -58,9 +58,10 @@ function _include_from_serialized(content::Vector{UInt8})
58
58
end
59
59
60
60
# returns an array of modules loaded, or nothing if failed
61
- function _require_from_serialized (node:: Int , path_to_try:: ByteString , toplevel_load:: Bool )
61
+ function _require_from_serialized (node:: Int , mod :: Symbol , path_to_try:: ByteString , toplevel_load:: Bool )
62
62
restored = nothing
63
63
if toplevel_load && myid () == 1 && nprocs () > 1
64
+ recompile_stale (mod, path_to_try)
64
65
# broadcast top-level import/using from node 1 (only)
65
66
if node == myid ()
66
67
content = open (readbytes, path_to_try)
@@ -78,6 +79,7 @@ function _require_from_serialized(node::Int, path_to_try::ByteString, toplevel_l
78
79
end
79
80
end
80
81
elseif node == myid ()
82
+ myid () == 1 && recompile_stale (mod, path_to_try)
81
83
restored = ccall (:jl_restore_incremental , Any, (Ptr{Uint8},), path_to_try)
82
84
else
83
85
content = remotecall_fetch (node, open, readbytes, path_to_try)
89
91
90
92
function _require_from_serialized (node:: Int , mod:: Symbol , toplevel_load:: Bool )
91
93
paths = @fetchfrom node find_all_in_cache_path (mod)
94
+ sort! (paths, by= mtime, rev= true ) # try newest cachefiles first
92
95
for path_to_try in paths
93
- restored = _require_from_serialized (node, path_to_try, toplevel_load)
96
+ restored = _require_from_serialized (node, mod, path_to_try, toplevel_load)
94
97
if restored === nothing
95
98
warn (" deserialization checks failed while attempting to load cache from $path_to_try " )
96
99
else
@@ -152,7 +155,7 @@ function require(mod::Symbol)
152
155
if JLOptions (). incremental != 0
153
156
# spawn off a new incremental compile task from node 1 for recursive `require` calls
154
157
cachefile = compile (mod)
155
- if nothing === _require_from_serialized (1 , cachefile, last)
158
+ if nothing === _require_from_serialized (1 , mod, cachefile, last)
156
159
warn (" require failed to create a precompiled cache file" )
157
160
end
158
161
return
@@ -315,3 +318,30 @@ function cache_dependencies(cachefile::AbstractString)
315
318
end
316
319
return modules, files
317
320
end
321
+
322
+ function stale_cachefile (cachefile:: AbstractString , cachefile_mtime:: Real = mtime (cachefile))
323
+ modules, files = cache_dependencies (cachefile)
324
+ for f in files
325
+ if mtime (f) > cachefile_mtime
326
+ return true
327
+ end
328
+ end
329
+ # files are not stale, so module list is valid and needs checking
330
+ for (M,uuid) in modules
331
+ if ! isdefined (Main, M)
332
+ require (M) # should recursively recompile module M if stale
333
+ end
334
+ if module_uuid (Main .(M)) != uuid
335
+ return true
336
+ end
337
+ end
338
+ return false # fresh cachefile
339
+ end
340
+
341
+ function recompile_stale (mod, cachefile)
342
+ cachestat = stat (cachefile)
343
+ if iswritable (cachestat) && stale_cachefile (cachefile, cachestat. mtime)
344
+ info (" Recompiling stale cache file $cachefile for module $mod ." )
345
+ create_expr_cache (find_in_path (string (mod)), cachefile)
346
+ end
347
+ end
0 commit comments