@@ -1394,6 +1394,10 @@ static void jl_write_module(jl_serializer_state *s, uintptr_t item, jl_module_t
13941394 }
13951395 }
13961396 assert (ios_pos (s -> s ) - reloc_offset == tot );
1397+
1398+ // After reload, everything that has happened in this process happened semantically at
1399+ // (for .incremental) or before jl_require_world, so reset this flag.
1400+ jl_atomic_store_relaxed (& newm -> export_set_changed_since_require_world , 0 );
13971401}
13981402
13991403static void record_memoryref (jl_serializer_state * s , size_t reloc_offset , jl_genericmemoryref_t ref ) {
@@ -3537,32 +3541,31 @@ extern void export_jl_small_typeof(void);
35373541int IMAGE_NATIVE_CODE_TAINTED = 0 ;
35383542
35393543// TODO: This should possibly be in Julia
3540- static void jl_validate_binding_partition (jl_binding_t * b , jl_binding_partition_t * bpart , size_t mod_idx )
3544+ static int jl_validate_binding_partition (jl_binding_t * b , jl_binding_partition_t * bpart , size_t mod_idx , int unchanged_implicit )
35413545{
3542-
35433546 if (jl_atomic_load_relaxed (& bpart -> max_world ) != ~(size_t )0 )
3544- return ;
3547+ return 1 ;
35453548 size_t raw_kind = bpart -> kind ;
35463549 enum jl_partition_kind kind = (enum jl_partition_kind )(raw_kind & 0x0f );
3547- if (!jl_bkind_is_some_import (kind ))
3548- return ;
3549- jl_binding_t * imported_binding = (jl_binding_t * )bpart -> restriction ;
3550- jl_binding_partition_t * latest_imported_bpart = jl_atomic_load_relaxed (& imported_binding -> partitions );
3551- if (!latest_imported_bpart )
3552- return ;
3553- if (kind == BINDING_KIND_IMPLICIT || kind == BINDING_KIND_FAILED ) {
3550+ if (!unchanged_implicit && jl_bkind_is_some_implicit (kind )) {
35543551 jl_check_new_binding_implicit (bpart , b , NULL , jl_atomic_load_relaxed (& jl_world_counter ));
35553552 bpart -> kind |= (raw_kind & 0xf0 );
35563553 if (bpart -> min_world > jl_require_world )
35573554 goto invalidated ;
35583555 }
3556+ if (!jl_bkind_is_some_import (kind ))
3557+ return 1 ;
3558+ jl_binding_t * imported_binding = (jl_binding_t * )bpart -> restriction ;
3559+ jl_binding_partition_t * latest_imported_bpart = jl_atomic_load_relaxed (& imported_binding -> partitions );
3560+ if (!latest_imported_bpart )
3561+ return 1 ;
35593562 if (latest_imported_bpart -> min_world <= bpart -> min_world ) {
35603563 // Imported binding is still valid
35613564 if ((kind == BINDING_KIND_EXPLICIT || kind == BINDING_KIND_IMPORTED ) &&
35623565 external_blob_index ((jl_value_t * )imported_binding ) != mod_idx ) {
35633566 jl_add_binding_backedge (imported_binding , (jl_value_t * )b );
35643567 }
3565- return ;
3568+ return 1 ;
35663569 }
35673570 else {
35683571 // Binding partition was invalidated
@@ -3580,13 +3583,14 @@ static void jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_
35803583 jl_binding_t * bedge = (jl_binding_t * )edge ;
35813584 if (!jl_atomic_load_relaxed (& bedge -> partitions ))
35823585 continue ;
3583- jl_validate_binding_partition (bedge , jl_atomic_load_relaxed (& bedge -> partitions ), mod_idx );
3586+ jl_validate_binding_partition (bedge , jl_atomic_load_relaxed (& bedge -> partitions ), mod_idx , 0 );
35843587 }
35853588 }
35863589 if (bpart -> kind & BINDING_FLAG_EXPORTED ) {
35873590 jl_module_t * mod = b -> globalref -> mod ;
35883591 jl_sym_t * name = b -> globalref -> name ;
35893592 JL_LOCK (& mod -> lock );
3593+ jl_atomic_store_release (& mod -> export_set_changed_since_require_world , 1 );
35903594 if (mod -> usings_backedges ) {
35913595 for (size_t i = 0 ; i < jl_array_len (mod -> usings_backedges ); i ++ ) {
35923596 jl_module_t * edge = (jl_module_t * )jl_array_ptr_ref (mod -> usings_backedges , i );
@@ -3596,12 +3600,24 @@ static void jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_
35963600 if (!jl_atomic_load_relaxed (& importee -> partitions ))
35973601 continue ;
35983602 JL_UNLOCK (& mod -> lock );
3599- jl_validate_binding_partition (importee , jl_atomic_load_relaxed (& importee -> partitions ), mod_idx );
3603+ jl_validate_binding_partition (importee , jl_atomic_load_relaxed (& importee -> partitions ), mod_idx , 0 );
36003604 JL_LOCK (& mod -> lock );
36013605 }
36023606 }
36033607 JL_UNLOCK (& mod -> lock );
3608+ return 0 ;
36043609 }
3610+ return 1 ;
3611+ }
3612+
3613+ static int all_usings_unchanged_implicit (jl_module_t * mod )
3614+ {
3615+ int unchanged_implicit = 1 ;
3616+ for (size_t i = 0 ; unchanged_implicit && i < module_usings_length (mod ); i ++ ) {
3617+ jl_module_t * usee = module_usings_getmod (mod , i );
3618+ unchanged_implicit &= !jl_atomic_load_acquire (& usee -> export_set_changed_since_require_world );
3619+ }
3620+ return unchanged_implicit ;
36053621}
36063622
36073623static void jl_restore_system_image_from_stream_ (ios_t * f , jl_image_t * image , jl_array_t * depmods , uint64_t checksum ,
@@ -4063,12 +4079,15 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
40634079 jl_module_t * mod = (jl_module_t * )obj ;
40644080 size_t mod_idx = external_blob_index ((jl_value_t * )mod );
40654081 jl_svec_t * table = jl_atomic_load_relaxed (& mod -> bindings );
4082+ int unchanged_implicit = all_usings_unchanged_implicit (mod );
40664083 for (size_t i = 0 ; i < jl_svec_len (table ); i ++ ) {
40674084 jl_binding_t * b = (jl_binding_t * )jl_svecref (table , i );
40684085 if ((jl_value_t * )b == jl_nothing )
40694086 continue ;
40704087 jl_binding_partition_t * bpart = jl_atomic_load_relaxed (& b -> partitions );
4071- jl_validate_binding_partition (b , bpart , mod_idx );
4088+ if (!jl_validate_binding_partition (b , bpart , mod_idx , unchanged_implicit )) {
4089+ unchanged_implicit = all_usings_unchanged_implicit (mod );
4090+ }
40724091 }
40734092 }
40744093 }
0 commit comments