Skip to content

Commit 3705629

Browse files
authored
staticdata: Don't discard inlineable code that inference may need (#58842)
See #58841 (comment). We were accidentally discarding inferred code during staticdata preparation that we would need immediately afterwards to satisfy inlining requests during code generation for the system image. This was resulting in spurious extra compilation at the first inference after sysimage reload. Additionally it was likely causing various unnecessary dispatch slow paths in the generated inference code. Fixes #58841.
1 parent 6a9da96 commit 3705629

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/staticdata.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,15 @@ static void jl_queue_module_for_serialization(jl_serializer_state *s, jl_module_
756756
}
757757
}
758758

759+
static int codeinst_may_be_runnable(jl_code_instance_t *ci, int incremental) {
760+
size_t max_world = jl_atomic_load_relaxed(&ci->max_world);
761+
if (max_world == ~(size_t)0)
762+
return 1;
763+
if (incremental)
764+
return 0;
765+
return jl_atomic_load_relaxed(&ci->min_world) <= jl_typeinf_world && jl_typeinf_world <= max_world;
766+
}
767+
759768
// Anything that requires uniquing or fixing during deserialization needs to be "toplevel"
760769
// in serialization (i.e., have its own entry in `serialization_order`). Consequently,
761770
// objects that act as containers for other potentially-"problematic" objects must add such "children"
@@ -924,8 +933,8 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
924933
else if (def->source == NULL) {
925934
// don't delete code from optimized opaque closures that can't be reconstructed (and builtins)
926935
}
927-
else if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run
928-
jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant
936+
else if (!codeinst_may_be_runnable(ci, s->incremental) || // delete all code that cannot run
937+
jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant
929938
discard = 1;
930939
}
931940
else if (native_functions && // don't delete any code if making a ji file

test/precompile.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,4 +2498,10 @@ let m = only(methods(Base.var"@big_str"))
24982498
@test m.specializations === Core.svec() || !isdefined(m.specializations, :cache)
24992499
end
25002500

2501+
# Issue #58841 - make sure we don't accidentally throw away code for inference
2502+
let io = IOBuffer()
2503+
run(pipeline(`$(Base.julia_cmd()) --trace-compile=stderr -e 'f() = sin(1.) == 0. ? 1 : 0; exit(f())'`, stderr=io))
2504+
@test isempty(String(take!(io)))
2505+
end
2506+
25012507
finish_precompile_test!()

0 commit comments

Comments
 (0)