Skip to content

Commit 3ea60d2

Browse files
authored
staticdata: prune backedges table during serialization (#58156)
After the bindings change, there is quite a lot of garbage in here now at runtime (it does not de-duplicate entries added for bindings), so attempt to do a bit of that during serialization. Re-landing part of #58078
1 parent 828e3a1 commit 3ea60d2

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/staticdata.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,12 +882,38 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
882882
// prevent this from happening, so we do not need to detect that user
883883
// error now.
884884
}
885+
// don't recurse into all backedges memory (yet)
886+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mi->backedges, 1);
887+
if (backedges) {
888+
assert(!jl_options.trim && !jl_options.strip_ir);
889+
jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1);
890+
size_t i = 0, n = jl_array_nrows(backedges);
891+
while (i < n) {
892+
jl_value_t *invokeTypes;
893+
jl_code_instance_t *caller;
894+
i = get_next_edge((jl_array_t*)backedges, i, &invokeTypes, &caller);
895+
if (invokeTypes)
896+
jl_queue_for_serialization(s, invokeTypes);
897+
}
898+
}
885899
}
886900
if (jl_is_mtable(v)) {
887901
jl_methtable_t *mt = (jl_methtable_t*)v;
888902
if (jl_options.trim || jl_options.strip_ir) {
889903
record_field_change((jl_value_t**)&mt->backedges, NULL);
890904
}
905+
else {
906+
// don't recurse into all backedges memory (yet)
907+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1);
908+
if (backedges) {
909+
jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1);
910+
for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i += 2) {
911+
jl_value_t *t = jl_array_ptr_ref(backedges, i);
912+
assert(!jl_is_code_instance(t));
913+
jl_queue_for_serialization(s, t);
914+
}
915+
}
916+
}
891917
}
892918
if (jl_is_binding(v)) {
893919
jl_binding_t *b = (jl_binding_t*)v;
@@ -899,6 +925,18 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
899925
if (jl_options.trim || jl_options.strip_ir) {
900926
record_field_change((jl_value_t**)&b->backedges, NULL);
901927
}
928+
else {
929+
// don't recurse into all backedges memory (yet)
930+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&b->backedges, 1);
931+
if (backedges) {
932+
jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1);
933+
for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i++) {
934+
jl_value_t *b = jl_array_ptr_ref(backedges, i);
935+
if (!jl_is_code_instance(b) && !jl_is_method_instance(b) && !jl_is_method(b)) // otherwise usually a Binding?
936+
jl_queue_for_serialization(s, b);
937+
}
938+
}
939+
}
902940
}
903941
if (s->incremental && jl_is_globalref(v)) {
904942
jl_globalref_t *gr = (jl_globalref_t*)v;
@@ -2572,6 +2610,52 @@ static void jl_prune_type_cache_linear(jl_svec_t *cache)
25722610
jl_svecset(cache, ins++, jl_nothing);
25732611
}
25742612

2613+
static void jl_prune_mi_backedges(jl_array_t *backedges)
2614+
{
2615+
if (backedges == NULL)
2616+
return;
2617+
size_t i = 0, ins = 0, n = jl_array_nrows(backedges);
2618+
while (i < n) {
2619+
jl_value_t *invokeTypes;
2620+
jl_code_instance_t *caller;
2621+
i = get_next_edge(backedges, i, &invokeTypes, &caller);
2622+
if (ptrhash_get(&serialization_order, caller) != HT_NOTFOUND)
2623+
ins = set_next_edge(backedges, ins, invokeTypes, caller);
2624+
}
2625+
jl_array_del_end(backedges, n - ins);
2626+
}
2627+
2628+
static void jl_prune_mt_backedges(jl_array_t *backedges)
2629+
{
2630+
if (backedges == NULL)
2631+
return;
2632+
size_t i = 0, ins = 0, n = jl_array_nrows(backedges);
2633+
for (i = 1; i < n; i += 2) {
2634+
jl_value_t *ci = jl_array_ptr_ref(backedges, i);
2635+
if (ptrhash_get(&serialization_order, ci) != HT_NOTFOUND) {
2636+
jl_array_ptr_set(backedges, ins++, jl_array_ptr_ref(backedges, i - 1));
2637+
jl_array_ptr_set(backedges, ins++, ci);
2638+
}
2639+
}
2640+
jl_array_del_end(backedges, n - ins);
2641+
}
2642+
2643+
2644+
static void jl_prune_binding_backedges(jl_array_t *backedges)
2645+
{
2646+
if (backedges == NULL)
2647+
return;
2648+
size_t i = 0, ins = 0, n = jl_array_nrows(backedges);
2649+
for (i = 0; i < n; i++) {
2650+
jl_value_t *b = jl_array_ptr_ref(backedges, i);
2651+
if (ptrhash_get(&serialization_order, b) != HT_NOTFOUND) {
2652+
jl_array_ptr_set(backedges, ins, b);
2653+
ins++;
2654+
}
2655+
}
2656+
jl_array_del_end(backedges, n - ins);
2657+
}
2658+
25752659

25762660
uint_t bindingkey_hash(size_t idx, jl_value_t *data);
25772661

@@ -3229,6 +3313,21 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
32293313
jl_gc_wb(tn, jl_atomic_load_relaxed(&tn->cache));
32303314
jl_prune_type_cache_linear(jl_atomic_load_relaxed(&tn->linearcache));
32313315
}
3316+
else if (jl_is_method_instance(v)) {
3317+
jl_method_instance_t *mi = (jl_method_instance_t*)v;
3318+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mi->backedges, 1);
3319+
jl_prune_mi_backedges((jl_array_t*)backedges);
3320+
}
3321+
else if (jl_is_mtable(v)) {
3322+
jl_methtable_t *mt = (jl_methtable_t*)v;
3323+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1);
3324+
jl_prune_mt_backedges((jl_array_t*)backedges);
3325+
}
3326+
else if (jl_is_binding(v)) {
3327+
jl_binding_t *b = (jl_binding_t*)v;
3328+
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&b->backedges, 1);
3329+
jl_prune_binding_backedges((jl_array_t*)backedges);
3330+
}
32323331
}
32333332
}
32343333

0 commit comments

Comments
 (0)