Skip to content

Commit 980071c

Browse files
authored
Ensure compilation happens after logging starts (#53)
If compilation of the workload happens before the logging system is initialized, many CodeInstances may be missed. This exploits `Core.@latestworld` to prevent inference from proceeding into the workload. It removes the `@force_compile`, which introduces some risk that even the workload will be interpreted. Also wraps the `@setup_workload` block with a `let`. Fixes #17 Fixes #26 Fixes #37 Closes #40 Closes JuliaLang/julia#57957
1 parent 10d0a0f commit 980071c

File tree

12 files changed

+228
-5
lines changed

12 files changed

+228
-5
lines changed

.github/workflows/CI.yml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jobs:
3333
- uses: julia-actions/cache@v2
3434
- uses: julia-actions/julia-buildpkg@v1
3535
- uses: julia-actions/julia-runtest@v1
36+
- run: julia --code-coverage=none --startup=no --project test/without_coverage.jl
3637
- uses: julia-actions/julia-processcoverage@v1
3738
- uses: codecov/codecov-action@v5
3839
with:

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
*.jl.mem
44
/Manifest.toml
55
/docs/build/
6+
.vscode/

Project.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
name = "PrecompileTools"
22
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
3-
authors = ["Tim Holy <[email protected]>", "t-bltg <[email protected]>", "and contributors"]
43
version = "1.3.0"
4+
authors = ["Tim Holy <[email protected]>", "t-bltg <[email protected]>", "and contributors"]
55

66
[deps]
77
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
88

99
[compat]
10+
InteractiveUtils = "1.11.0"
1011
Preferences = "1"
1112
julia = "1.12"
1213

1314
[extras]
15+
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1416
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
1517
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1618
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
1719

1820
[targets]
19-
test = ["Pkg", "Test", "UUIDs"]
21+
test = ["InteractiveUtils", "Pkg", "Test", "UUIDs"]

src/workloads.jl

+7-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ function workload_enabled(mod::Module)
1212
end
1313
end
1414

15+
@noinline is_generating_output() = ccall(:jl_generating_output, Cint, ()) == 1
16+
1517
function tag_newly_inferred_enable()
1618
ccall(:jl_tag_newly_inferred_enable, Cvoid, ())
1719
if !Base.generating_output() # for verbose[]
@@ -60,10 +62,10 @@ end
6062
- indirect runtime-dispatched calls to such methods.
6163
"""
6264
macro compile_workload(ex::Expr)
63-
local iscompiling = :((ccall(:jl_generating_output, Cint, ()) == 1 && $PrecompileTools.workload_enabled(@__MODULE__)))
65+
local iscompiling = :($PrecompileTools.is_generating_output() && $PrecompileTools.workload_enabled(@__MODULE__))
6466
ex = quote
6567
begin
66-
Base.Experimental.@force_compile
68+
Core.@latestworld # block inference from proceeding beyond this point (xref https://github.com/JuliaLang/julia/issues/57957)
6769
$(esc(ex))
6870
end
6971
end
@@ -110,7 +112,9 @@ macro setup_workload(ex::Expr)
110112
# trigger inference & codegen in undesirable ways (see #16).
111113
return quote
112114
if $iscompiling || $PrecompileTools.verbose[]
113-
$(esc(ex))
115+
let
116+
$(esc(ex))
117+
end
114118
end
115119
end
116120
end

test/AliasTables/Manifest.toml

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.12.0-DEV"
4+
manifest_format = "2.0"
5+
project_hash = "08b5cd69f1c3c631130172e148f3d7bf0afe42df"
6+
7+
[[deps.AliasTables]]
8+
deps = ["PrecompileTools"]
9+
path = "."
10+
uuid = "beccad7b-8a6a-4466-a02c-5791472d17ea"
11+
version = "0.1.0"
12+
13+
[[deps.Dates]]
14+
deps = ["Printf"]
15+
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
16+
version = "1.11.0"
17+
18+
[[deps.PrecompileTools]]
19+
deps = ["Preferences"]
20+
path = "../.."
21+
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
22+
version = "1.3.0"
23+
24+
[[deps.Preferences]]
25+
deps = ["TOML"]
26+
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
27+
uuid = "21216c6a-2e73-6563-6e65-726566657250"
28+
version = "1.4.3"
29+
30+
[[deps.Printf]]
31+
deps = ["Unicode"]
32+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
33+
version = "1.11.0"
34+
35+
[[deps.Random]]
36+
deps = ["SHA"]
37+
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
38+
version = "1.11.0"
39+
40+
[[deps.SHA]]
41+
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
42+
version = "0.7.0"
43+
44+
[[deps.TOML]]
45+
deps = ["Dates"]
46+
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
47+
version = "1.0.3"
48+
49+
[[deps.Unicode]]
50+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
51+
version = "1.11.0"

test/AliasTables/Project.toml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name = "AliasTables"
2+
uuid = "beccad7b-8a6a-4466-a02c-5791472d17ea"
3+
version = "0.1.0"
4+
authors = ["Tim Holy <[email protected]>"]
5+
6+
[deps]
7+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
8+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
9+
10+
[compat]
11+
Random = "1.11.0"

test/AliasTables/src/AliasTables.jl

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module AliasTables
2+
3+
using Random
4+
using PrecompileTools
5+
6+
export AliasTable
7+
8+
struct AliasTable{T}
9+
x::T
10+
end
11+
Base.rand(x::AliasTable) = rand(x.x)
12+
13+
PrecompileTools.@compile_workload begin
14+
at = AliasTable([1.0, 2.0])
15+
rand(at)
16+
end
17+
18+
end

test/MSort/Manifest.toml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.12.0-DEV"
4+
manifest_format = "2.0"
5+
project_hash = "54196cb61d86afd465157edc4da76dcf0e248920"
6+
7+
[[deps.Dates]]
8+
deps = ["Printf"]
9+
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
10+
version = "1.11.0"
11+
12+
[[deps.MSort]]
13+
deps = ["PrecompileTools"]
14+
path = "."
15+
uuid = "75c9a4e7-9bfb-42c4-89fa-37abaaaaefd3"
16+
version = "0.1.0"
17+
18+
[[deps.PrecompileTools]]
19+
deps = ["Preferences"]
20+
path = "../.."
21+
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
22+
version = "1.3.0"
23+
24+
[[deps.Preferences]]
25+
deps = ["TOML"]
26+
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
27+
uuid = "21216c6a-2e73-6563-6e65-726566657250"
28+
version = "1.4.3"
29+
30+
[[deps.Printf]]
31+
deps = ["Unicode"]
32+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
33+
version = "1.11.0"
34+
35+
[[deps.TOML]]
36+
deps = ["Dates"]
37+
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
38+
version = "1.0.3"
39+
40+
[[deps.Unicode]]
41+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
42+
version = "1.11.0"

test/MSort/Project.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name = "MSort"
2+
uuid = "75c9a4e7-9bfb-42c4-89fa-37abaaaaefd3"
3+
version = "0.1.0"
4+
authors = ["Tim Holy <[email protected]>"]
5+
6+
[deps]
7+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"

test/MSort/src/MSort.jl

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
module MSort
2+
3+
# issue #26
4+
5+
using PrecompileTools
6+
7+
function quicksort(
8+
v::Vector{T};
9+
lo::Int = 1,
10+
hi::Int = length(v),
11+
) where {T <: Union{Int64, Float64}}
12+
x = copy(v)
13+
quick!(x, lo, hi)
14+
x
15+
end
16+
17+
function partition(
18+
xp::Vector{T},
19+
pivot::T,
20+
left::Int,
21+
right::Int,
22+
) where {T <: Union{Int64, Float64}}
23+
while left <= right
24+
while xp[left] < pivot
25+
left += 1
26+
end
27+
while pivot < xp[right]
28+
right -= 1
29+
end
30+
if left <= right
31+
xp[left], xp[right] = xp[right], xp[left]
32+
left += 1
33+
right -= 1
34+
end
35+
end
36+
left, right
37+
end
38+
39+
function quick!(
40+
xp::Vector{T},
41+
i::Int,
42+
j::Int,
43+
) where {T <: Union{Int64, Float64}}
44+
if j > i
45+
left, right = partition(xp, xp[(j+i)>>>1], i, j)
46+
quick!(xp, i, right)
47+
quick!(xp, left, j)
48+
end
49+
end
50+
51+
@setup_workload begin
52+
@compile_workload begin
53+
quicksort(rand(64))
54+
end
55+
end
56+
57+
end

test/runtests.jl

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ using Base: specializations
8787
end
8888
PrecompileTools.verbose[] = oldval
8989

90+
## @recompile_invalidations
91+
9092
# Mimic the format written to `_jl_debug_method_invalidation`
9193
# As a source of MethodInstances, `getproperty` has lots
9294
m = which(getproperty, (Any, Symbol))

test/without_coverage.jl

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using PrecompileTools
2+
using Test
3+
using InteractiveUtils
4+
5+
@testset "No-coverage tests" begin
6+
@assert Base.JLOptions().code_coverage == 0 "These tests should be run with coverage disabled"
7+
8+
push!(LOAD_PATH, @__DIR__)
9+
10+
using MSort
11+
using AliasTables
12+
x = rand(64)
13+
pipe = Pipe()
14+
oldstderr = stderr
15+
redirect_stderr(pipe)
16+
@trace_compile begin
17+
MSort.quicksort(x)
18+
at = AliasTable([1.0, 2.0])
19+
rand(at)
20+
end
21+
close(pipe.in)
22+
redirect_stderr(oldstderr)
23+
str = read(pipe.out, String)
24+
@test isempty(str)
25+
26+
pop!(LOAD_PATH)
27+
end

0 commit comments

Comments
 (0)