@@ -478,6 +478,7 @@ void *native_functions; // opaque jl_native_code_desc_t blob used for fetching
478478
479479// table of struct field addresses to rewrite during saving
480480static htable_t field_replace ;
481+ static htable_t relocatable_ext_cis ;
481482
482483// array of definitions for the predefined function pointers
483484// (reverse of fptr_to_id)
@@ -710,7 +711,8 @@ static int needs_uniquing(jl_value_t *v) JL_NOTSAFEPOINT
710711
711712static void record_field_change (jl_value_t * * addr , jl_value_t * newval ) JL_NOTSAFEPOINT
712713{
713- ptrhash_put (& field_replace , (void * )addr , newval );
714+ if (* addr != newval )
715+ ptrhash_put (& field_replace , (void * )addr , newval );
714716}
715717
716718static jl_value_t * get_replaceable_field (jl_value_t * * addr , int mutabl ) JL_GC_DISABLED
@@ -852,6 +854,8 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
852854 // TODO: if (ci in ci->defs->cache)
853855 record_field_change ((jl_value_t * * )& ci -> next , NULL );
854856 }
857+ if (jl_atomic_load_relaxed (& ci -> inferred ) && !is_relocatable_ci (& relocatable_ext_cis , ci ))
858+ record_field_change ((jl_value_t * * )& ci -> inferred , jl_nothing );
855859 }
856860
857861 if (immediate ) // must be things that can be recursively handled, and valid as type parameters
@@ -1647,6 +1651,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED
16471651 jl_atomic_store_release (& newci -> min_world , 1 );
16481652 jl_atomic_store_release (& newci -> max_world , 0 );
16491653 }
1654+ newci -> relocatability = 0 ;
16501655 }
16511656 jl_atomic_store_relaxed (& newci -> invoke , NULL );
16521657 jl_atomic_store_relaxed (& newci -> specsigflags , 0 );
@@ -2603,7 +2608,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new
26032608 * edges = jl_alloc_vec_any (0 );
26042609 * method_roots_list = jl_alloc_vec_any (0 );
26052610 // Collect the new method roots for external specializations
2606- jl_collect_new_roots (* method_roots_list , * new_ext_cis , worklist_key );
2611+ jl_collect_new_roots (& relocatable_ext_cis , * method_roots_list , * new_ext_cis , worklist_key );
26072612 jl_collect_edges (* edges , * ext_targets , * new_ext_cis , world );
26082613 }
26092614 assert (edges_map == NULL ); // jl_collect_edges clears this when done
@@ -3004,6 +3009,7 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
30043009 assert ((ct -> reentrant_timing & 0b1110 ) == 0 );
30053010 ct -> reentrant_timing |= 0b1000 ;
30063011 if (worklist ) {
3012+ htable_new (& relocatable_ext_cis , 0 );
30073013 jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ),
30083014 & extext_methods , & new_ext_cis , & method_roots_list , & ext_targets , & edges );
30093015 if (!emit_split ) {
@@ -3020,6 +3026,8 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
30203026 jl_save_system_image_to_stream (ff , mod_array , worklist , extext_methods , new_ext_cis , method_roots_list , ext_targets , edges );
30213027 if (_native_data != NULL )
30223028 native_functions = NULL ;
3029+ if (worklist )
3030+ htable_free (& relocatable_ext_cis );
30233031 // make sure we don't run any Julia code concurrently before this point
30243032 // Re-enable running julia code for postoutput hooks, atexit, etc.
30253033 jl_gc_enable_finalizers (ct , 1 );
0 commit comments