Skip to content

Commit

Permalink
add Base.isprecompiled
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Jun 20, 2023
1 parent a8ef873 commit 0a0a226
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ New library functions
* `fourthroot(x)` is now defined in `Base.Math` and can be used to compute the fourth root of `x`.
It can also be accessed using the unicode character ``, which can be typed by `\fourthroot<tab>` ([#48899]).
* `Libc.memmove`, `Libc.memset`, and `Libc.memcpy` are now defined, whose functionality matches that of their respective C calls.
* `Base.isprecompiled(pkg::PkgId)` to identify whether a package has already been precompiled ([#50218]).

New library features
--------------------
Expand Down
53 changes: 53 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,59 @@ end

# End extensions

# should sync with the types of arguments of `stale_cachefile`
const StaleCacheKey = Tuple{Base.PkgId, UInt128, String, String}

"""
Base.isprecompiled(pkg::PkgId)
Returns whether a given PkgId within the active project is precompiled.
!!! compat "Julia 1.10"
This function requires at least Julia 1.10.
"""
function isprecompiled(pkg::PkgId;
stale_cache::Dict{StaleCacheKey,Bool}=Dict{StaleCacheKey, Bool}(),
cachepaths::Vector{String}=Base.find_all_in_cache_path(pkg),
sourcepath::String=Base.locate_package(pkg)
)
isnothing(sourcepath) && error("Cannot locate source for $(repr(PkgId))")
for path_to_try in cachepaths
staledeps = stale_cachefile(sourcepath, path_to_try, ignore_loaded = true)
if staledeps === true
continue
end
staledeps, _ = staledeps::Tuple{Vector{Any}, Union{Nothing, String}}
# finish checking staledeps module graph
for i in 1:length(staledeps)
dep = staledeps[i]
dep isa Module && continue
modpath, modkey, modbuild_id = dep::Tuple{String, PkgId, UInt128}
modpaths = find_all_in_cache_path(modkey)
for modpath_to_try in modpaths::Vector{String}
stale_cache_key = (modkey, modbuild_id, modpath, modpath_to_try)::StaleCacheKey
if get!(() -> stale_cachefile(stale_cache_key..., ignore_loaded=true) === true,
stale_cache, stale_cache_key)
continue
end
@goto check_next_dep
end
@goto check_next_path
@label check_next_dep
end
try
# update timestamp of precompilation file so that it is the first to be tried by code loading
touch(path_to_try)
catch ex
# file might be read-only and then we fail to update timestamp, which is fine
ex isa IOError || rethrow()
end
return true
@label check_next_path
end
return false
end

# loads a precompile cache file, after checking stale_cachefile tests
function _tryrequire_from_serialized(modkey::PkgId, build_id::UInt128)
assert_havelock(require_lock)
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ Base.identify_package
Base.locate_package
Base.require
Base.compilecache
Base.isprecompiled
```

## Internals
Expand Down
5 changes: 4 additions & 1 deletion test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,10 @@ precompile_test_harness("code caching") do dir
precompile(getelsize, (Vector{Int32},))
end
""")
Base.compilecache(Base.PkgId(string(Cache_module)))
pkgid = Base.PkgId(string(Cache_module))
@test !Base.isprecompiled(pkgid)
Base.compilecache(pkgid)
@test Base.isprecompiled(pkgid)
@eval using $Cache_module
M = getfield(@__MODULE__, Cache_module)
# Test that this cache file "owns" all the roots
Expand Down

0 comments on commit 0a0a226

Please sign in to comment.