@@ -1394,6 +1394,10 @@ static void jl_write_module(jl_serializer_state *s, uintptr_t item, jl_module_t
1394
1394
}
1395
1395
}
1396
1396
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 );
1397
1401
}
1398
1402
1399
1403
static 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);
3537
3541
int IMAGE_NATIVE_CODE_TAINTED = 0 ;
3538
3542
3539
3543
// 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 )
3541
3545
{
3542
-
3543
3546
if (jl_atomic_load_relaxed (& bpart -> max_world ) != ~(size_t )0 )
3544
- return ;
3547
+ return 1 ;
3545
3548
size_t raw_kind = bpart -> kind ;
3546
3549
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 )) {
3554
3551
jl_check_new_binding_implicit (bpart , b , NULL , jl_atomic_load_relaxed (& jl_world_counter ));
3555
3552
bpart -> kind |= (raw_kind & 0xf0 );
3556
3553
if (bpart -> min_world > jl_require_world )
3557
3554
goto invalidated ;
3558
3555
}
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 ;
3559
3562
if (latest_imported_bpart -> min_world <= bpart -> min_world ) {
3560
3563
// Imported binding is still valid
3561
3564
if ((kind == BINDING_KIND_EXPLICIT || kind == BINDING_KIND_IMPORTED ) &&
3562
3565
external_blob_index ((jl_value_t * )imported_binding ) != mod_idx ) {
3563
3566
jl_add_binding_backedge (imported_binding , (jl_value_t * )b );
3564
3567
}
3565
- return ;
3568
+ return 1 ;
3566
3569
}
3567
3570
else {
3568
3571
// Binding partition was invalidated
@@ -3580,13 +3583,14 @@ static void jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_
3580
3583
jl_binding_t * bedge = (jl_binding_t * )edge ;
3581
3584
if (!jl_atomic_load_relaxed (& bedge -> partitions ))
3582
3585
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 );
3584
3587
}
3585
3588
}
3586
3589
if (bpart -> kind & BINDING_FLAG_EXPORTED ) {
3587
3590
jl_module_t * mod = b -> globalref -> mod ;
3588
3591
jl_sym_t * name = b -> globalref -> name ;
3589
3592
JL_LOCK (& mod -> lock );
3593
+ jl_atomic_store_release (& mod -> export_set_changed_since_require_world , 1 );
3590
3594
if (mod -> usings_backedges ) {
3591
3595
for (size_t i = 0 ; i < jl_array_len (mod -> usings_backedges ); i ++ ) {
3592
3596
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_
3596
3600
if (!jl_atomic_load_relaxed (& importee -> partitions ))
3597
3601
continue ;
3598
3602
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 );
3600
3604
JL_LOCK (& mod -> lock );
3601
3605
}
3602
3606
}
3603
3607
JL_UNLOCK (& mod -> lock );
3608
+ return 0 ;
3604
3609
}
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 ;
3605
3621
}
3606
3622
3607
3623
static 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
4063
4079
jl_module_t * mod = (jl_module_t * )obj ;
4064
4080
size_t mod_idx = external_blob_index ((jl_value_t * )mod );
4065
4081
jl_svec_t * table = jl_atomic_load_relaxed (& mod -> bindings );
4082
+ int unchanged_implicit = all_usings_unchanged_implicit (mod );
4066
4083
for (size_t i = 0 ; i < jl_svec_len (table ); i ++ ) {
4067
4084
jl_binding_t * b = (jl_binding_t * )jl_svecref (table , i );
4068
4085
if ((jl_value_t * )b == jl_nothing )
4069
4086
continue ;
4070
4087
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
+ }
4072
4091
}
4073
4092
}
4074
4093
}
0 commit comments