Skip to content

Commit 6e0b2da

Browse files
author
KristofferC
committed
pass the environment stack to precompile workers via serialization
1 parent 2eebacf commit 6e0b2da

File tree

9 files changed

+72
-14
lines changed

9 files changed

+72
-14
lines changed

base/codeloading2.jl

+13-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,19 @@ struct EnvironmentStack
305305
envs::Vector{Union{ImplicitEnv, ExplicitEnv}}
306306
end
307307

308-
function EnvironmentStack(environments = load_path())
308+
309+
# Caching
310+
311+
const CACHED_ENV_STACK = Ref{Union{EnvironmentStack, Nothing}}(nothing)
312+
313+
function EnvironmentStack(environments = nothing)
314+
if CACHED_ENV_STACK[] !== nothing
315+
return CACHED_ENV_STACK[]
316+
end
317+
# Avoid looking up `load_path` until it is really needed.
318+
if environments === nothing
319+
environments = load_path()
320+
end
309321
envs = Union{ImplicitEnv, ExplicitEnv}[]
310322
for env in environments
311323
if isfile(env)

base/loading.jl

+23-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ end
159159
const ns_dummy_uuid = UUID("fe0723d6-3a44-4c41-8065-ee0f42c8ceab")
160160

161161
function dummy_uuid(project_file::String)
162-
@lock require_lock begin
163162
project_path = try
164163
realpath(project_file)
165164
catch ex
@@ -168,7 +167,6 @@ function dummy_uuid(project_file::String)
168167
end
169168
uuid = uuid5(ns_dummy_uuid, project_path)
170169
return uuid
171-
end
172170
end
173171

174172
## package path slugs: turning UUID + SHA1 into a pair of 4-byte "slugs" ##
@@ -789,6 +787,9 @@ For more details regarding code loading, see the manual sections on [modules](@r
789787
"""
790788
function require(into::Module, mod::Symbol)
791789
@lock require_lock begin
790+
no_initial_cache = CACHED_ENV_STACK[] === nothing
791+
try
792+
no_initial_cache && (CACHED_ENV_STACK[] = EnvironmentStack())
792793
uuidkey = identify_package(into, String(mod))
793794
# Core.println("require($(PkgId(into)), $mod) -> $uuidkey from env \"$env\"")
794795
if uuidkey === nothing
@@ -824,6 +825,9 @@ function require(into::Module, mod::Symbol)
824825
push!(_require_dependencies, (into, binpack(uuidkey), 0.0))
825826
end
826827
return _require_prelocked(uuidkey)
828+
finally
829+
no_initial_cache && (CACHED_ENV_STACK[] = nothing)
830+
end # try
827831
end # @lock
828832
end
829833

@@ -1209,6 +1213,7 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
12091213
end
12101214

12111215
const PRECOMPILE_TRACE_COMPILE = Ref{String}()
1216+
const ENV_SERIALIZATION_FILE = Ref{Union{Nothing,String}}(nothing)
12121217
function create_expr_cache(pkg::PkgId, input::String, output::String, concrete_deps::typeof(_concrete_dependencies), internal_stderr::IO = stderr, internal_stdout::IO = stdout)
12131218
@nospecialize internal_stderr internal_stdout
12141219
rm(output, force=true) # Remove file if it exists
@@ -1241,6 +1246,22 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, concrete_d
12411246
-`, stderr = internal_stderr, stdout = internal_stdout),
12421247
"w", stdout)
12431248
# write data over stdin to avoid the (unlikely) case of exceeding max command line size
1249+
serialization_pkgid = PkgId(UUID("9e88b42a-f829-5b0c-bbe9-9e923198166b"), "Serialization")
1250+
if haskey(loaded_modules, serialization_pkgid)
1251+
local ftmp
1252+
if ENV_SERIALIZATION_FILE[] === nothing || !isfile(ENV_SERIALIZATION_FILE[])
1253+
Serialization = loaded_modules[serialization_pkgid]
1254+
ftmp, iotmp = mktemp()
1255+
Serialization.serialize(iotmp, EnvironmentStack())
1256+
close(iotmp)
1257+
else
1258+
ftmp = ENV_SERIALIZATION_FILE[]
1259+
end
1260+
write(io.in, """
1261+
Base.ENV_SERIALIZATION_FILE[] = $(repr(ftmp))
1262+
Base.CACHED_ENV_STACK[] = (Base.loaded_modules[Base.PkgId(Base.UUID("9e88b42a-f829-5b0c-bbe9-9e923198166b"), "Serialization")].deserialize(IOBuffer(read($(repr(ftmp))))))
1263+
""")
1264+
end
12441265
write(io.in, """
12451266
Base.include_package_for_output($(pkg_str(pkg)), $(repr(abspath(input))), $(repr(depot_path)), $(repr(dl_load_path)),
12461267
$(repr(load_path)), $deps, $(repr(source_path(nothing))))

contrib/generate_precompile.jl

+25
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,31 @@ if Libdl !== nothing
186186
"""
187187
end
188188

189+
Serialization = get(Base.loaded_modules,
190+
Base.PkgId(Base.UUID("9e88b42a-f829-5b0c-bbe9-9e923198166b"), "Serialization"),
191+
nothing)
192+
if Serialization !== nothing
193+
# Deserializing environment
194+
hardcoded_precompile_statements *= """
195+
precompile(Tuple{typeof(Serialization.deserialize), String})
196+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.EnvironmentStack}})
197+
precompile(Tuple{typeof(Serialization.deserialize_fillarray!), Array{String, 1}, Serialization.Serializer{Base.IOStream}})
198+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Union}})
199+
precompile(Tuple{typeof(Serialization.deserialize_fillarray!), Array{Union{Base.ExplicitEnv, Base.ImplicitEnv}, 1}, Serialization.Serializer{Base.IOStream}})
200+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.ExplicitEnv}})
201+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.Dict{String, Base.UUID}}})
202+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.UUID}})
203+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.Dict{Base.UUID, Base.Dict{String, Base.UUID}}}})
204+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.Dict{Base.UUID, Union{Base.Missing, Nothing, Base.SHA1, String}}}})
205+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.SHA1}})
206+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.ImplicitEnv}})
207+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.Dict{String, Base.ImplicitEnvPkg}}})
208+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.ImplicitEnvPkg}})
209+
precompile(Tuple{typeof(Serialization.deserialize_fillarray!), Array{Base.PkgId, 1}, Serialization.Serializer{Base.IOStream}})
210+
precompile(Tuple{typeof(Serialization.deserialize), Serialization.Serializer{Base.IOStream}, Type{Base.PkgId}})
211+
"""
212+
end
213+
189214
Test = get(Base.loaded_modules,
190215
Base.PkgId(Base.UUID("8dfed614-e22c-5e08-85e1-65c5234f0b40"), "Test"),
191216
nothing)

deps/checksums/Pkg-3cbbd860afd4c2a50a80a04fa229fe5cd5bddc76.tar.gz/md5

-1
This file was deleted.

deps/checksums/Pkg-3cbbd860afd4c2a50a80a04fa229fe5cd5bddc76.tar.gz/sha512

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
da299f922804dae87cefd024e9c96866
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fa9edd15a7e4e754ece0ae7f7a5b3dda744340211e0857e4f59d5050c86fe73ff938cb6afe6588caaa0945dedcd0f0373a92e38fc47c2673dbec02df4ce40251

stdlib/Pkg.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
PKG_BRANCH = master
2-
PKG_SHA1 = 3cbbd860afd4c2a50a80a04fa229fe5cd5bddc76
2+
PKG_SHA1 = 45003c2e00a50d0594b927782f8342739860e3da
33
PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git
44
PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1

stdlib/Serialization/src/Serialization.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -1465,13 +1465,13 @@ function deserialize_string(s::AbstractSerializer, len::Int)
14651465
end
14661466

14671467
# default DataType deserializer
1468-
function deserialize(s::AbstractSerializer, t::DataType)
1469-
nf = length(t.types)
1470-
if nf == 0 && t.size > 0
1468+
function deserialize(s::AbstractSerializer, ::Type{T}) where {T}
1469+
nf = length(T.types)
1470+
if nf == 0 && T.size > 0
14711471
# bits type
1472-
return read(s.io, t)
1473-
elseif ismutabletype(t)
1474-
x = ccall(:jl_new_struct_uninit, Any, (Any,), t)
1472+
return read(s.io, T)
1473+
elseif ismutabletype(T)
1474+
x = ccall(:jl_new_struct_uninit, Any, (Any,), T)
14751475
deserialize_cycle(s, x)
14761476
for i in 1:nf
14771477
tag = Int32(read(s.io, UInt8)::UInt8)
@@ -1481,7 +1481,7 @@ function deserialize(s::AbstractSerializer, t::DataType)
14811481
end
14821482
return x
14831483
elseif nf == 0
1484-
return ccall(:jl_new_struct_uninit, Any, (Any,), t)
1484+
return ccall(:jl_new_struct_uninit, Any, (Any,), T)
14851485
else
14861486
na = nf
14871487
vflds = Vector{Any}(undef, nf)
@@ -1494,7 +1494,7 @@ function deserialize(s::AbstractSerializer, t::DataType)
14941494
na >= i && (na = i - 1) # rest of tail must be undefined values
14951495
end
14961496
end
1497-
return ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt32), t, vflds, na)
1497+
return ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt32), T, vflds, na)
14981498
end
14991499
end
15001500

0 commit comments

Comments
 (0)