@@ -882,12 +882,38 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
882
882
// prevent this from happening, so we do not need to detect that user
883
883
// error now.
884
884
}
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
+ }
885
899
}
886
900
if (jl_is_mtable (v )) {
887
901
jl_methtable_t * mt = (jl_methtable_t * )v ;
888
902
if (jl_options .trim || jl_options .strip_ir ) {
889
903
record_field_change ((jl_value_t * * )& mt -> backedges , NULL );
890
904
}
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
+ }
891
917
}
892
918
if (jl_is_binding (v )) {
893
919
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_
899
925
if (jl_options .trim || jl_options .strip_ir ) {
900
926
record_field_change ((jl_value_t * * )& b -> backedges , NULL );
901
927
}
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
+ }
902
940
}
903
941
if (s -> incremental && jl_is_globalref (v )) {
904
942
jl_globalref_t * gr = (jl_globalref_t * )v ;
@@ -2572,6 +2610,52 @@ static void jl_prune_type_cache_linear(jl_svec_t *cache)
2572
2610
jl_svecset (cache , ins ++ , jl_nothing );
2573
2611
}
2574
2612
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
+
2575
2659
2576
2660
uint_t bindingkey_hash (size_t idx , jl_value_t * data );
2577
2661
@@ -3229,6 +3313,21 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
3229
3313
jl_gc_wb (tn , jl_atomic_load_relaxed (& tn -> cache ));
3230
3314
jl_prune_type_cache_linear (jl_atomic_load_relaxed (& tn -> linearcache ));
3231
3315
}
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
+ }
3232
3331
}
3233
3332
}
3234
3333
0 commit comments