From b22d195394ab8c621d092924ca9ca97574589fc1 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 21 Aug 2015 00:46:24 -0400 Subject: [PATCH] fix #12722: compilecache should use same path as require, and .ji files should be considered stale if the module is no longer found at the same path --- base/loading.jl | 14 ++++++++------ src/dump.c | 44 ++++++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index b9b6257146078..f61440dc373c0 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -328,7 +328,7 @@ end compilecache(mod::Symbol) = compilecache(string(mod)) function compilecache(name::ByteString) myid() == 1 || error("can only precompile from node 1") - path = find_in_path(name) + path = find_in_path(name, nothing) path === nothing && throw(ArgumentError("$name not found in path")) cachepath = LOAD_CACHE_PATH[1] if !isdir(cachepath) @@ -374,13 +374,16 @@ function cache_dependencies(cachefile::AbstractString) end end -function stale_cachefile(cachefile::AbstractString) +function stale_cachefile(modpath, cachefile) io = open(cachefile, "r") try if !isvalid_cache_header(io) return true # invalid cache file end modules, files = cache_dependencies(io) + if files[1][1] != modpath + return true # cache file was compiled from a different path + end for (f,ftime) in files if mtime(f) != ftime return true @@ -402,11 +405,10 @@ function stale_cachefile(cachefile::AbstractString) end function recompile_stale(mod, cachefile) - cachestat = stat(cachefile) - if iswritable(cachestat) && stale_cachefile(cachefile) + path = find_in_path(string(mod), nothing) + if stale_cachefile(path, cachefile) info("Recompiling stale cache file $cachefile for module $mod.") - path = find_in_path(string(mod)) - path === nothing && error("module $mod not found") + path === nothing && error("module $mod not found in current path") create_expr_cache(path, cachefile) end end diff --git a/src/dump.c b/src/dump.c index ab150bd97e974..9f9de232df654 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1015,43 +1015,39 @@ void jl_serialize_dependency_list(ios_t *s) static jl_array_t *deps = NULL; if (!deps) deps = (jl_array_t*)jl_get_global(jl_base_module, jl_symbol("_require_dependencies")); - if (deps) { - // sort!(deps) so that we can easily eliminate duplicates - static jl_value_t *sort_func = NULL; - if (!sort_func) - sort_func = jl_get_global(jl_base_module, jl_symbol("sort!")); - jl_apply((jl_function_t*)sort_func, (jl_value_t**)&deps, 1); - - size_t l = jl_array_len(deps); - jl_value_t *prev = NULL; + + // unique(deps) to eliminate duplicates while preserving order: + // we preserve order so that the topmost included .jl file comes first + static jl_value_t *unique_func = NULL; + if (!unique_func) + unique_func = jl_get_global(jl_base_module, jl_symbol("unique")); + jl_array_t *udeps = deps && unique_func ? (jl_array_t *) jl_apply((jl_function_t*)unique_func, (jl_value_t**)&deps, 1) : NULL; + + if (udeps) { + JL_GC_PUSH(udeps); + size_t l = jl_array_len(udeps); for (size_t i=0; i < l; i++) { - jl_value_t *dep = jl_fieldref(jl_cellref(deps, i), 0); + jl_value_t *dep = jl_fieldref(jl_cellref(udeps, i), 0); size_t slen = jl_string_len(dep); - if (!prev || memcmp(jl_string_data(dep), jl_string_data(prev), slen)) { - total_size += 4 + slen + 8; - } - prev = dep; + total_size += 4 + slen + 8; } total_size += 4; } // write the total size so that we can quickly seek past all of the // dependencies if we don't need them write_uint64(s, total_size); - if (deps) { - size_t l = jl_array_len(deps); - jl_value_t *prev = NULL; + if (udeps) { + size_t l = jl_array_len(udeps); for (size_t i=0; i < l; i++) { - jl_value_t *deptuple = jl_cellref(deps, i); + jl_value_t *deptuple = jl_cellref(udeps, i); jl_value_t *dep = jl_fieldref(deptuple, 0); size_t slen = jl_string_len(dep); - if (!prev || memcmp(jl_string_data(dep), jl_string_data(prev), slen)) { - write_int32(s, slen); - ios_write(s, jl_string_data(dep), slen); - write_float64(s, jl_unbox_float64(jl_fieldref(deptuple, 1))); - } - prev = dep; + write_int32(s, slen); + ios_write(s, jl_string_data(dep), slen); + write_float64(s, jl_unbox_float64(jl_fieldref(deptuple, 1))); } write_int32(s, 0); // terminator, for ease of reading + JL_GC_POP(udeps); } }