@@ -2229,50 +2229,52 @@ JL_DLLEXPORT jl_value_t *jl_as_global_root(jl_value_t *val JL_MAYBE_UNROOTED)
22292229}
22302230
22312231static  void  jl_prepare_serialization_data (jl_array_t  * mod_array , jl_array_t  * newly_inferred , uint64_t  worklist_key ,
2232-                            /* outputs */   jl_array_t  * * extext_methods ,
2233-                                           jl_array_t  * * new_specializations , jl_array_t  * * method_roots_list ,
2234-                                           jl_array_t  * * ext_targets , jl_array_t  * * edges )
2232+                            /* outputs */   jl_array_t  * * extext_methods , jl_array_t  * * new_specializations ,
2233+                                           jl_array_t  * * method_roots_list , jl_array_t  * * ext_targets , jl_array_t  * * edges )
22352234{
22362235    // extext_methods: [method1, ...], worklist-owned "extending external" methods added to functions owned by modules outside the worklist 
22372236    // ext_targets: [invokesig1, callee1, matches1, ...] non-worklist callees of worklist-owned methods 
22382237    //              ordinary dispatch: invokesig=NULL, callee is MethodInstance 
22392238    //              `invoke` dispatch: invokesig is signature, callee is MethodInstance 
22402239    //              abstract call: callee is signature 
22412240    // edges: [caller1, ext_targets_indexes1, ...] for worklist-owned methods calling external methods 
2242- 
22432241    assert (edges_map  ==  NULL );
2244-     JL_GC_PUSH1 (& edges_map );
22452242
2246-     // Save the inferred code from newly inferred, external methods 
22472243    htable_new (& external_mis , 0 );  // we need external_mis until after `jl_collect_edges` finishes 
2244+     // Save the inferred code from newly inferred, external methods 
22482245    * new_specializations  =  queue_external_cis (newly_inferred );
2249-     // Collect the new method roots 
2250-     htable_t  methods_with_newspecs ;
2251-     htable_new (& methods_with_newspecs , 0 );
2252-     jl_collect_methods (& methods_with_newspecs , * new_specializations );
2253-     * method_roots_list  =  jl_alloc_vec_any (0 );
2254-     jl_collect_new_roots (* method_roots_list , & methods_with_newspecs , worklist_key );
2255-     htable_free (& methods_with_newspecs );
22562246
22572247    // Collect method extensions and edges data 
2258-     edges_map  =  jl_alloc_vec_any (0 );
2248+     JL_GC_PUSH1 (& edges_map );
2249+     if  (edges )
2250+         edges_map  =  jl_alloc_vec_any (0 );
22592251    * extext_methods  =  jl_alloc_vec_any (0 );
2252+     jl_collect_methtable_from_mod (jl_type_type_mt , * extext_methods );
2253+     jl_collect_methtable_from_mod (jl_nonfunction_mt , * extext_methods );
22602254    size_t  i , len  =  jl_array_len (mod_array );
22612255    for  (i  =  0 ; i  <  len ; i ++ ) {
22622256        jl_module_t  * m  =  (jl_module_t * )jl_array_ptr_ref (mod_array , i );
22632257        assert (jl_is_module (m ));
22642258        if  (m -> parent  ==  m ) // some toplevel modules (really just Base) aren't actually 
22652259            jl_collect_extext_methods_from_mod (* extext_methods , m );
22662260    }
2267-     jl_collect_methtable_from_mod (* extext_methods , jl_type_type_mt );
2268-     jl_collect_missing_backedges (jl_type_type_mt );
2269-     jl_collect_methtable_from_mod (* extext_methods , jl_nonfunction_mt );
2270-     jl_collect_missing_backedges (jl_nonfunction_mt );
2271-     // jl_collect_extext_methods_from_mod and jl_collect_missing_backedges also accumulate data in callers_with_edges. 
2272-     // Process this to extract `edges` and `ext_targets`. 
2273-     * ext_targets  =  jl_alloc_vec_any (0 );
2274-     * edges  =  jl_alloc_vec_any (0 );
2275-     jl_collect_edges (* edges , * ext_targets );
2261+ 
2262+     if  (edges ) {
2263+         jl_collect_missing_backedges (jl_type_type_mt );
2264+         jl_collect_missing_backedges (jl_nonfunction_mt );
2265+         // jl_collect_extext_methods_from_mod and jl_collect_missing_backedges also accumulate data in callers_with_edges. 
2266+         // Process this to extract `edges` and `ext_targets`. 
2267+         * ext_targets  =  jl_alloc_vec_any (0 );
2268+         * edges  =  jl_alloc_vec_any (0 );
2269+         * method_roots_list  =  jl_alloc_vec_any (0 );
2270+         // Collect the new method roots 
2271+         htable_t  methods_with_newspecs ;
2272+         htable_new (& methods_with_newspecs , 0 );
2273+         jl_collect_methods (& methods_with_newspecs , * new_specializations );
2274+         jl_collect_new_roots (* method_roots_list , & methods_with_newspecs , worklist_key );
2275+         htable_free (& methods_with_newspecs );
2276+         jl_collect_edges (* edges , * ext_targets );
2277+     }
22762278    htable_free (& external_mis );
22772279    assert (edges_map  ==  NULL ); // jl_collect_edges clears this when done 
22782280
@@ -2562,9 +2564,8 @@ static void jl_save_system_image_to_stream(ios_t *f,
25622564    jl_gc_enable (en );
25632565}
25642566
2565- static  void  jl_write_header_for_incremental (ios_t  * f , jl_array_t  * worklist , jl_array_t  * * mod_array , jl_array_t  * * udeps , int64_t  * srctextpos , int64_t  * checksumpos )
2567+ static  void  jl_write_header_for_incremental (ios_t  * f , jl_array_t  * worklist , jl_array_t  * mod_array , jl_array_t  * * udeps , int64_t  * srctextpos , int64_t  * checksumpos )
25662568{
2567-     * mod_array  =  jl_get_loaded_modules ();  // __toplevel__ modules loaded in this session (from Base.loaded_modules_array) 
25682569    assert (jl_precompile_toplevel_module  ==  NULL );
25692570    jl_precompile_toplevel_module  =  (jl_module_t * )jl_array_ptr_ref (worklist , jl_array_len (worklist )- 1 );
25702571
@@ -2580,7 +2581,7 @@ static void jl_write_header_for_incremental(ios_t *f, jl_array_t *worklist, jl_a
25802581    // write description of requirements for loading (modules that must be pre-loaded if initialization is to succeed) 
25812582    // this can return errors during deserialize, 
25822583    // best to keep it early (before any actual initialization) 
2583-     write_mod_list (f , * mod_array );
2584+     write_mod_list (f , mod_array );
25842585}
25852586
25862587JL_DLLEXPORT  void  jl_create_system_image (void  * * _native_data , jl_array_t  * worklist , bool_t  emit_split ,
@@ -2611,49 +2612,58 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
26112612    int64_t  checksumpos_ff  =  0 ;
26122613    int64_t  datastartpos  =  0 ;
26132614    JL_GC_PUSH6 (& mod_array , & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges );
2614-     if  (worklist ) {
2615-         jl_write_header_for_incremental (f , worklist , & mod_array , udeps , srctextpos , & checksumpos );
2616-         if  (emit_split ) {
2617-             checksumpos_ff  =  write_header (ff , 1 );
2618-             write_uint8 (ff , jl_cache_flags ());
2619-             write_mod_list (ff , mod_array );
2620-         } else  {
2621-             checksumpos_ff  =  checksumpos ;
2622-         }
2623-         {
2624-             // make sure we don't run any Julia code concurrently after this point 
2625-             jl_gc_enable_finalizers (ct , 0 );
2626-             assert (ct -> reentrant_inference  ==  0 );
2627-             ct -> reentrant_inference  =  (uint16_t )-1 ;
2628-         }
2629-         jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ), & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges );
26302615
2616+     if  (worklist ) {
2617+         mod_array  =  jl_get_loaded_modules ();  // __toplevel__ modules loaded in this session (from Base.loaded_modules_array) 
26312618        // Generate _native_data` 
26322619        if  (jl_options .outputo  ||  jl_options .outputbc  ||  jl_options .outputunoptbc  ||  jl_options .outputasm ) {
2620+             jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ),
2621+                                           & extext_methods , & new_specializations , NULL , NULL , NULL );
26332622            jl_precompile_toplevel_module  =  (jl_module_t * )jl_array_ptr_ref (worklist , jl_array_len (worklist )- 1 );
26342623            * _native_data  =  jl_precompile_worklist (worklist , extext_methods , new_specializations );
26352624            jl_precompile_toplevel_module  =  NULL ;
2625+             extext_methods  =  NULL ;
2626+             new_specializations  =  NULL ;
26362627        }
2628+         jl_write_header_for_incremental (f , worklist , mod_array , udeps , srctextpos , & checksumpos );
2629+         if  (emit_split ) {
2630+             checksumpos_ff  =  write_header (ff , 1 );
2631+             write_uint8 (ff , jl_cache_flags ());
2632+             write_mod_list (ff , mod_array );
2633+         }
2634+         else  {
2635+             checksumpos_ff  =  checksumpos ;
2636+         }
2637+     }
2638+     else  {
2639+         * _native_data  =  jl_precompile (jl_options .compile_enabled  ==  JL_OPTIONS_COMPILE_ALL );
2640+     }
26372641
2642+     // Make sure we don't run any Julia code concurrently after this point 
2643+     // since it will invalidate our serialization preparations 
2644+     jl_gc_enable_finalizers (ct , 0 );
2645+     assert (ct -> reentrant_inference  ==  0 );
2646+     ct -> reentrant_inference  =  (uint16_t )-1 ;
2647+     if  (worklist ) {
2648+         jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ),
2649+                                       & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges );
26382650        if  (!emit_split ) {
26392651            write_int32 (f , 0 ); // No clone_targets 
26402652            write_padding (f , LLT_ALIGN (ios_pos (f ), JL_CACHE_BYTE_ALIGNMENT ) -  ios_pos (f ));
2641-         } else  {
2653+         }
2654+         else  {
26422655            write_padding (ff , LLT_ALIGN (ios_pos (ff ), JL_CACHE_BYTE_ALIGNMENT ) -  ios_pos (ff ));
26432656        }
26442657        datastartpos  =  ios_pos (ff );
2645-     } else  {
2646-         * _native_data  =  jl_precompile (jl_options .compile_enabled  ==  JL_OPTIONS_COMPILE_ALL );
26472658    }
26482659    native_functions  =  * _native_data ;
26492660    jl_save_system_image_to_stream (ff , worklist , extext_methods , new_specializations , method_roots_list , ext_targets , edges );
26502661    native_functions  =  NULL ;
2651-     if  (worklist ) {
2652-         // Re-enable running julia code for postoutput hooks, atexit, etc. 
2653-         jl_gc_enable_finalizers (ct , 1 );
2654-         ct -> reentrant_inference  =  0 ;
2655-         jl_precompile_toplevel_module  =  NULL ;
2656-     }
2662+     // make sure we don't run any Julia code concurrently before this point 
2663+     // Re-enable running julia code for postoutput hooks, atexit, etc. 
2664+     jl_gc_enable_finalizers (ct , 1 );
2665+     ct -> reentrant_inference  =  0 ;
2666+     jl_precompile_toplevel_module  =  NULL ;
26572667
26582668    if  (worklist ) {
26592669        // Go back and update the checksum in the header 
0 commit comments