-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement support for object caching through pkgimages (#47184)
This implements caching native code in "package images" (pkgimages). We now write two serialization files, one ending in `*.ji` and the other with the platform dynamic library extension (e.g., `*.so`). The `*.ji` contains "extended" header information (include the source-code dump for Revise), whereas the dynamic library includes the Julia objects, including LLVM-generated native code. Native code is compiled once during precompilation and then a second time to build a "clean" module. When we find an edge to an external function (already cached in anloaded pkgimage), we emit a global variable which we will patch during loading with the address of the function to call. This allows us to leverage the standard multiversioning capabilities. Co-authored-by: Tim Holy <tim.holy@gmail.com> Co-authored-by: Kristoffer Carlsson <kristoffer.carlsson@chalmers.se> Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com> Co-authored-by: Ian Butterworth <i.r.butterworth@gmail.com> Co-authored-by: Max Horn <max@quendi.de> Co-authored-by: Michael Schlottke-Lakemper <michael@sloede.com> Co-authored-by: Alex Ames <alexander.m.ames@gmail.com>
- Loading branch information
1 parent
03bdf15
commit a2db90f
Showing
48 changed files
with
1,750 additions
and
764 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# This file is a part of Julia. License is MIT: https://julialang.org/license | ||
module Linking | ||
|
||
import Base.Libc: Libdl | ||
|
||
# inlined LLD_jll | ||
# These get calculated in __init__() | ||
const PATH = Ref("") | ||
const LIBPATH = Ref("") | ||
const PATH_list = String[] | ||
const LIBPATH_list = String[] | ||
const lld_path = Ref{String}() | ||
const lld_exe = Sys.iswindows() ? "lld.exe" : "lld" | ||
|
||
if Sys.iswindows() | ||
const LIBPATH_env = "PATH" | ||
const LIBPATH_default = "" | ||
const pathsep = ';' | ||
elseif Sys.isapple() | ||
const LIBPATH_env = "DYLD_FALLBACK_LIBRARY_PATH" | ||
const LIBPATH_default = "~/lib:/usr/local/lib:/lib:/usr/lib" | ||
const pathsep = ':' | ||
else | ||
const LIBPATH_env = "LD_LIBRARY_PATH" | ||
const LIBPATH_default = "" | ||
const pathsep = ':' | ||
end | ||
|
||
function adjust_ENV!(env::Dict, PATH::String, LIBPATH::String, adjust_PATH::Bool, adjust_LIBPATH::Bool) | ||
if adjust_LIBPATH | ||
LIBPATH_base = get(env, LIBPATH_env, expanduser(LIBPATH_default)) | ||
if !isempty(LIBPATH_base) | ||
env[LIBPATH_env] = string(LIBPATH, pathsep, LIBPATH_base) | ||
else | ||
env[LIBPATH_env] = LIBPATH | ||
end | ||
end | ||
if adjust_PATH && (LIBPATH_env != "PATH" || !adjust_LIBPATH) | ||
if !isempty(get(env, "PATH", "")) | ||
env["PATH"] = string(PATH, pathsep, env["PATH"]) | ||
else | ||
env["PATH"] = PATH | ||
end | ||
end | ||
return env | ||
end | ||
|
||
function __init_lld_path() | ||
# Prefer our own bundled lld, but if we don't have one, pick it up off of the PATH | ||
# If this is an in-tree build, `lld` will live in `tools`. Otherwise, it'll be in `libexec` | ||
for bundled_lld_path in (joinpath(Sys.BINDIR, Base.LIBEXECDIR, lld_exe), | ||
joinpath(Sys.BINDIR, "..", "tools", lld_exe), | ||
joinpath(Sys.BINDIR, lld_exe)) | ||
if isfile(bundled_lld_path) | ||
lld_path[] = abspath(bundled_lld_path) | ||
return | ||
end | ||
end | ||
lld_path[] = something(Sys.which(lld_exe), lld_exe) | ||
return | ||
end | ||
|
||
const VERBOSE = Ref{Bool}(false) | ||
|
||
function __init__() | ||
VERBOSE[] = parse(Bool, get(ENV, "JULIA_VERBOSE_LINKING", "false")) | ||
|
||
__init_lld_path() | ||
PATH[] = dirname(lld_path[]) | ||
if Sys.iswindows() | ||
# On windows, the dynamic libraries (.dll) are in Sys.BINDIR ("usr\\bin") | ||
append!(LIBPATH_list, [abspath(Sys.BINDIR, Base.LIBDIR, "julia"), Sys.BINDIR]) | ||
else | ||
append!(LIBPATH_list, [abspath(Sys.BINDIR, Base.LIBDIR, "julia"), abspath(Sys.BINDIR, Base.LIBDIR)]) | ||
end | ||
LIBPATH[] = join(LIBPATH_list, pathsep) | ||
return | ||
end | ||
|
||
function lld(; adjust_PATH::Bool = true, adjust_LIBPATH::Bool = true) | ||
env = adjust_ENV!(copy(ENV), PATH[], LIBPATH[], adjust_PATH, adjust_LIBPATH) | ||
return Cmd(Cmd([lld_path[]]); env) | ||
end | ||
|
||
function ld() | ||
default_args = `` | ||
@static if Sys.iswindows() | ||
# LLD supports mingw style linking | ||
flavor = "gnu" | ||
m = Sys.ARCH == :x86_64 ? "i386pep" : "i386pe" | ||
default_args = `-m $m -Bdynamic --enable-auto-image-base --allow-multiple-definition` | ||
elseif Sys.isapple() | ||
flavor = "darwin" | ||
arch = Sys.ARCH == :aarch64 ? :arm64 : Sys.ARCH | ||
default_args = `-arch $arch -undefined dynamic_lookup -platform_version macos $(Base.MACOS_PRODUCT_VERSION) $(Base.MACOS_PLATFORM_VERSION)` | ||
else | ||
flavor = "gnu" | ||
end | ||
|
||
`$(lld()) -flavor $flavor $default_args` | ||
end | ||
|
||
const WHOLE_ARCHIVE = if Sys.isapple() | ||
"-all_load" | ||
else | ||
"--whole-archive" | ||
end | ||
|
||
const NO_WHOLE_ARCHIVE = if Sys.isapple() | ||
"" | ||
else | ||
"--no-whole-archive" | ||
end | ||
|
||
const SHARED = if Sys.isapple() | ||
"-dylib" | ||
else | ||
"-shared" | ||
end | ||
|
||
is_debug() = ccall(:jl_is_debugbuild, Cint, ()) == 1 | ||
libdir() = abspath(Sys.BINDIR, Base.LIBDIR) | ||
private_libdir() = abspath(Sys.BINDIR, Base.PRIVATE_LIBDIR) | ||
if Sys.iswindows() | ||
shlibdir() = Sys.BINDIR | ||
else | ||
shlibdir() = libdir() | ||
end | ||
|
||
function link_image_cmd(path, out) | ||
LIBDIR = "-L$(libdir())" | ||
PRIVATE_LIBDIR = "-L$(private_libdir())" | ||
SHLIBDIR = "-L$(shlibdir())" | ||
LIBS = is_debug() ? ("-ljulia-debug", "-ljulia-internal-debug") : ("-ljulia", "-ljulia-internal") | ||
@static if Sys.iswindows() | ||
LIBS = (LIBS..., "-lopenlibm", "-lssp", "-lgcc_s", "-lgcc", "-lmsvcrt") | ||
end | ||
|
||
V = VERBOSE[] ? "--verbose" : "" | ||
`$(ld()) $V $SHARED -o $out $WHOLE_ARCHIVE $path $NO_WHOLE_ARCHIVE $LIBDIR $PRIVATE_LIBDIR $SHLIBDIR $LIBS` | ||
end | ||
|
||
function link_image(path, out, internal_stderr::IO = stderr, internal_stdout::IO = stdout) | ||
run(link_image_cmd(path, out), Base.DevNull(), stderr, stdout) | ||
end | ||
|
||
end # module Linking |
Oops, something went wrong.
a2db90f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Executing the daily package evaluation, I will reply here when finished:
@nanosoldier
runtests(isdaily = true)
a2db90f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your package evaluation job has completed - possible new issues were detected. A full report can be found here.