Skip to content

Commit 3509ef3

Browse files
committed
staticdata: Don't discard inlineable code that may be needed to compile inference
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.
1 parent d48a675 commit 3509ef3

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
@@ -755,6 +755,15 @@ static void jl_queue_module_for_serialization(jl_serializer_state *s, jl_module_
755755
}
756756
}
757757

758+
static int codeinst_may_be_runnable(jl_code_instance_t *ci, int incremental) {
759+
size_t max_world = jl_atomic_load_relaxed(&ci->max_world);
760+
if (max_world == ~(size_t)0)
761+
return 1;
762+
if (incremental)
763+
return 0;
764+
return jl_atomic_load_relaxed(&ci->min_world) <= jl_typeinf_world && jl_typeinf_world <= max_world;
765+
}
766+
758767
// Anything that requires uniquing or fixing during deserialization needs to be "toplevel"
759768
// in serialization (i.e., have its own entry in `serialization_order`). Consequently,
760769
// objects that act as containers for other potentially-"problematic" objects must add such "children"
@@ -923,8 +932,8 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
923932
else if (def->source == NULL) {
924933
// don't delete code from optimized opaque closures that can't be reconstructed (and builtins)
925934
}
926-
else if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run
927-
jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant
935+
else if (!codeinst_may_be_runnable(ci, s->incremental) || // delete all code that cannot run
936+
jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant
928937
discard = 1;
929938
}
930939
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
@@ -2499,4 +2499,10 @@ let m = only(methods(Base.var"@big_str"))
24992499
@test m.specializations === Core.svec() || !isdefined(m.specializations, :cache)
25002500
end
25012501

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

0 commit comments

Comments
 (0)