@@ -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
25762660uint_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