@@ -88,6 +88,8 @@ External links:
88
88
#include "valgrind.h"
89
89
#include "julia_assert.h"
90
90
91
+ static const size_t WORLD_AGE_REVALIDATION_SENTINEL = 0x1 ;
92
+
91
93
#include "staticdata_utils.c"
92
94
#include "precompile_utils.c"
93
95
@@ -501,6 +503,8 @@ typedef struct {
501
503
jl_array_t * link_ids_gvars ;
502
504
jl_array_t * link_ids_external_fnvars ;
503
505
jl_ptls_t ptls ;
506
+ // Set (implemented has a hasmap of MethodInstances to themselves) of which MethodInstances have (forward) edges
507
+ // to other MethodInstances.
504
508
htable_t callers_with_edges ;
505
509
jl_image_t * image ;
506
510
int8_t incremental ;
@@ -1596,45 +1600,45 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED
1596
1600
}
1597
1601
else if (jl_is_code_instance (v )) {
1598
1602
assert (f == s -> s );
1603
+
1599
1604
// Handle the native-code pointers
1600
- assert (f == s -> s );
1601
- jl_code_instance_t * m = (jl_code_instance_t * )v ;
1602
- jl_code_instance_t * newm = (jl_code_instance_t * )& f -> buf [reloc_offset ];
1605
+ jl_code_instance_t * ci = (jl_code_instance_t * )v ;
1606
+ jl_code_instance_t * newci = (jl_code_instance_t * )& f -> buf [reloc_offset ];
1603
1607
1604
1608
if (s -> incremental ) {
1605
1609
arraylist_push (& s -> fixup_objs , (void * )reloc_offset );
1606
- if (m -> min_world > 1 )
1607
- newm -> min_world = ~(size_t )0 ; // checks that we reprocess this upon deserialization
1608
- if (m -> max_world != ~(size_t )0 )
1609
- newm -> max_world = 0 ;
1610
+ if (ci -> min_world > 1 )
1611
+ newci -> min_world = ~(size_t )0 ; // checks that we reprocess this upon deserialization
1612
+ if (ci -> max_world != ~(size_t )0 )
1613
+ newci -> max_world = 0 ;
1610
1614
else {
1611
- if (jl_atomic_load_relaxed (& m -> inferred ) && ptrhash_has (& s -> callers_with_edges , m -> def ))
1612
- newm -> max_world = 1 ; // sentinel value indicating this will need validation
1613
- if (m -> min_world > 0 && jl_atomic_load_relaxed (& m -> inferred ) ) {
1615
+ if (jl_atomic_load_relaxed (& ci -> inferred ) && ptrhash_has (& s -> callers_with_edges , ci -> def ))
1616
+ newci -> max_world = WORLD_AGE_REVALIDATION_SENTINEL ;
1617
+ if (ci -> min_world > 0 && jl_atomic_load_relaxed (& ci -> inferred ) ) {
1614
1618
// TODO: also check if this object is part of the codeinst cache
1615
1619
// will check on deserialize if this cache entry is still valid
1616
1620
}
1617
1621
}
1618
1622
}
1619
- jl_atomic_store_relaxed (& newm -> invoke , NULL );
1620
- jl_atomic_store_relaxed (& newm -> specsigflags , 0 );
1621
- jl_atomic_store_relaxed (& newm -> specptr .fptr , NULL );
1623
+ jl_atomic_store_relaxed (& newci -> invoke , NULL );
1624
+ jl_atomic_store_relaxed (& newci -> specsigflags , 0 );
1625
+ jl_atomic_store_relaxed (& newci -> specptr .fptr , NULL );
1622
1626
int8_t fptr_id = JL_API_NULL ;
1623
1627
int8_t builtin_id = 0 ;
1624
- if (jl_atomic_load_relaxed (& m -> invoke ) == jl_fptr_const_return ) {
1628
+ if (jl_atomic_load_relaxed (& ci -> invoke ) == jl_fptr_const_return ) {
1625
1629
fptr_id = JL_API_CONST ;
1626
1630
}
1627
1631
else {
1628
- if (jl_is_method (m -> def -> def .method )) {
1629
- builtin_id = jl_fptr_id (jl_atomic_load_relaxed (& m -> specptr .fptr ));
1632
+ if (jl_is_method (ci -> def -> def .method )) {
1633
+ builtin_id = jl_fptr_id (jl_atomic_load_relaxed (& ci -> specptr .fptr ));
1630
1634
if (builtin_id ) { // found in the table of builtins
1631
1635
assert (builtin_id >= 2 );
1632
1636
fptr_id = JL_API_BUILTIN ;
1633
1637
}
1634
1638
else {
1635
1639
int32_t invokeptr_id = 0 ;
1636
1640
int32_t specfptr_id = 0 ;
1637
- jl_get_function_id (native_functions , m , & invokeptr_id , & specfptr_id ); // see if we generated code for it
1641
+ jl_get_function_id (native_functions , ci , & invokeptr_id , & specfptr_id ); // see if we generated code for it
1638
1642
if (invokeptr_id ) {
1639
1643
if (invokeptr_id == -1 ) {
1640
1644
fptr_id = JL_API_BOXED ;
@@ -1666,7 +1670,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED
1666
1670
}
1667
1671
}
1668
1672
}
1669
- jl_atomic_store_relaxed (& newm -> invoke , NULL ); // relocation offset
1673
+ jl_atomic_store_relaxed (& newci -> invoke , NULL ); // relocation offset
1670
1674
if (fptr_id != JL_API_NULL ) {
1671
1675
assert (fptr_id < BuiltinFunctionTag && "too many functions to serialize" );
1672
1676
arraylist_push (& s -> relocs_list , (void * )(reloc_offset + offsetof(jl_code_instance_t , invoke ))); // relocation location
@@ -2514,7 +2518,7 @@ JL_DLLEXPORT jl_value_t *jl_as_global_root(jl_value_t *val, int insert)
2514
2518
}
2515
2519
2516
2520
static void jl_prepare_serialization_data (jl_array_t * mod_array , jl_array_t * newly_inferred , uint64_t worklist_key ,
2517
- /* outputs */ jl_array_t * * extext_methods , jl_array_t * * new_specializations ,
2521
+ /* outputs */ jl_array_t * * extext_methods , jl_array_t * * new_ext_cis ,
2518
2522
jl_array_t * * method_roots_list , jl_array_t * * ext_targets , jl_array_t * * edges )
2519
2523
{
2520
2524
// extext_methods: [method1, ...], worklist-owned "extending external" methods added to functions owned by modules outside the worklist
@@ -2526,7 +2530,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new
2526
2530
assert (edges_map == NULL );
2527
2531
2528
2532
// Save the inferred code from newly inferred, external methods
2529
- * new_specializations = queue_external_cis (newly_inferred );
2533
+ * new_ext_cis = queue_external_cis (newly_inferred );
2530
2534
2531
2535
// Collect method extensions and edges data
2532
2536
JL_GC_PUSH1 (& edges_map );
@@ -2552,9 +2556,9 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new
2552
2556
* ext_targets = jl_alloc_vec_any (0 );
2553
2557
* edges = jl_alloc_vec_any (0 );
2554
2558
* method_roots_list = jl_alloc_vec_any (0 );
2555
- // Collect the new method roots
2556
- jl_collect_new_roots (* method_roots_list , * new_specializations , worklist_key );
2557
- jl_collect_edges (* edges , * ext_targets , * new_specializations , world );
2559
+ // Collect the new method roots for external specializations
2560
+ jl_collect_new_roots (* method_roots_list , * new_ext_cis , worklist_key );
2561
+ jl_collect_edges (* edges , * ext_targets , * new_ext_cis , world );
2558
2562
}
2559
2563
assert (edges_map == NULL ); // jl_collect_edges clears this when done
2560
2564
@@ -2564,7 +2568,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new
2564
2568
// In addition to the system image (where `worklist = NULL`), this can also save incremental images with external linkage
2565
2569
static void jl_save_system_image_to_stream (ios_t * f , jl_array_t * mod_array ,
2566
2570
jl_array_t * worklist , jl_array_t * extext_methods ,
2567
- jl_array_t * new_specializations , jl_array_t * method_roots_list ,
2571
+ jl_array_t * new_ext_cis , jl_array_t * method_roots_list ,
2568
2572
jl_array_t * ext_targets , jl_array_t * edges ) JL_GC_DISABLED
2569
2573
{
2570
2574
htable_new (& field_replace , 0 );
@@ -2680,7 +2684,7 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
2680
2684
// Queue method extensions
2681
2685
jl_queue_for_serialization (& s , extext_methods );
2682
2686
// Queue the new specializations
2683
- jl_queue_for_serialization (& s , new_specializations );
2687
+ jl_queue_for_serialization (& s , new_ext_cis );
2684
2688
// Queue the new roots
2685
2689
jl_queue_for_serialization (& s , method_roots_list );
2686
2690
// Queue the edges
@@ -2836,7 +2840,7 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
2836
2840
}
2837
2841
jl_write_value (& s , jl_module_init_order );
2838
2842
jl_write_value (& s , extext_methods );
2839
- jl_write_value (& s , new_specializations );
2843
+ jl_write_value (& s , new_ext_cis );
2840
2844
jl_write_value (& s , method_roots_list );
2841
2845
jl_write_value (& s , ext_targets );
2842
2846
jl_write_value (& s , edges );
@@ -2924,24 +2928,24 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
2924
2928
ff = f ;
2925
2929
}
2926
2930
2927
- jl_array_t * mod_array = NULL , * extext_methods = NULL , * new_specializations = NULL ;
2931
+ jl_array_t * mod_array = NULL , * extext_methods = NULL , * new_ext_cis = NULL ;
2928
2932
jl_array_t * method_roots_list = NULL , * ext_targets = NULL , * edges = NULL ;
2929
2933
int64_t checksumpos = 0 ;
2930
2934
int64_t checksumpos_ff = 0 ;
2931
2935
int64_t datastartpos = 0 ;
2932
- JL_GC_PUSH6 (& mod_array , & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges );
2936
+ JL_GC_PUSH6 (& mod_array , & extext_methods , & new_ext_cis , & method_roots_list , & ext_targets , & edges );
2933
2937
2934
2938
if (worklist ) {
2935
2939
mod_array = jl_get_loaded_modules (); // __toplevel__ modules loaded in this session (from Base.loaded_modules_array)
2936
2940
// Generate _native_data`
2937
2941
if (_native_data != NULL ) {
2938
2942
jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ),
2939
- & extext_methods , & new_specializations , NULL , NULL , NULL );
2943
+ & extext_methods , & new_ext_cis , NULL , NULL , NULL );
2940
2944
jl_precompile_toplevel_module = (jl_module_t * )jl_array_ptr_ref (worklist , jl_array_len (worklist )- 1 );
2941
- * _native_data = jl_precompile_worklist (worklist , extext_methods , new_specializations );
2945
+ * _native_data = jl_precompile_worklist (worklist , extext_methods , new_ext_cis );
2942
2946
jl_precompile_toplevel_module = NULL ;
2943
2947
extext_methods = NULL ;
2944
- new_specializations = NULL ;
2948
+ new_ext_cis = NULL ;
2945
2949
}
2946
2950
jl_write_header_for_incremental (f , worklist , mod_array , udeps , srctextpos , & checksumpos );
2947
2951
if (emit_split ) {
@@ -2964,7 +2968,7 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
2964
2968
ct -> reentrant_timing |= 0b1000 ;
2965
2969
if (worklist ) {
2966
2970
jl_prepare_serialization_data (mod_array , newly_inferred , jl_worklist_key (worklist ),
2967
- & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges );
2971
+ & extext_methods , & new_ext_cis , & method_roots_list , & ext_targets , & edges );
2968
2972
if (!emit_split ) {
2969
2973
write_int32 (f , 0 ); // No clone_targets
2970
2974
write_padding (f , LLT_ALIGN (ios_pos (f ), JL_CACHE_BYTE_ALIGNMENT ) - ios_pos (f ));
@@ -2976,7 +2980,7 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli
2976
2980
}
2977
2981
if (_native_data != NULL )
2978
2982
native_functions = * _native_data ;
2979
- jl_save_system_image_to_stream (ff , mod_array , worklist , extext_methods , new_specializations , method_roots_list , ext_targets , edges );
2983
+ jl_save_system_image_to_stream (ff , mod_array , worklist , extext_methods , new_ext_cis , method_roots_list , ext_targets , edges );
2980
2984
if (_native_data != NULL )
2981
2985
native_functions = NULL ;
2982
2986
// make sure we don't run any Julia code concurrently before this point
@@ -3058,7 +3062,7 @@ extern void export_jl_small_typeof(void);
3058
3062
static void jl_restore_system_image_from_stream_ (ios_t * f , jl_image_t * image , jl_array_t * depmods , uint64_t checksum ,
3059
3063
/* outputs */ jl_array_t * * restored , jl_array_t * * init_order ,
3060
3064
jl_array_t * * extext_methods ,
3061
- jl_array_t * * new_specializations , jl_array_t * * method_roots_list ,
3065
+ jl_array_t * * new_ext_cis , jl_array_t * * method_roots_list ,
3062
3066
jl_array_t * * ext_targets , jl_array_t * * edges ,
3063
3067
char * * base , arraylist_t * ccallable_list , pkgcachesizes * cachesizes ) JL_GC_DISABLED
3064
3068
{
@@ -3120,7 +3124,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
3120
3124
ios_seek (f , LLT_ALIGN (ios_pos (f ), 8 ));
3121
3125
assert (!ios_eof (f ));
3122
3126
s .s = f ;
3123
- uintptr_t offset_restored = 0 , offset_init_order = 0 , offset_extext_methods = 0 , offset_new_specializations = 0 , offset_method_roots_list = 0 ;
3127
+ uintptr_t offset_restored = 0 , offset_init_order = 0 , offset_extext_methods = 0 , offset_new_ext_cis = 0 , offset_method_roots_list = 0 ;
3124
3128
uintptr_t offset_ext_targets = 0 , offset_edges = 0 ;
3125
3129
if (!s .incremental ) {
3126
3130
size_t i ;
@@ -3152,7 +3156,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
3152
3156
offset_restored = jl_read_offset (& s );
3153
3157
offset_init_order = jl_read_offset (& s );
3154
3158
offset_extext_methods = jl_read_offset (& s );
3155
- offset_new_specializations = jl_read_offset (& s );
3159
+ offset_new_ext_cis = jl_read_offset (& s );
3156
3160
offset_method_roots_list = jl_read_offset (& s );
3157
3161
offset_ext_targets = jl_read_offset (& s );
3158
3162
offset_edges = jl_read_offset (& s );
@@ -3181,16 +3185,14 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
3181
3185
uint32_t external_fns_begin = read_uint32 (f );
3182
3186
jl_read_arraylist (s .s , ccallable_list ? ccallable_list : & s .ccallable_list );
3183
3187
if (s .incremental ) {
3184
- assert (restored && init_order && extext_methods && new_specializations && method_roots_list && ext_targets && edges );
3188
+ assert (restored && init_order && extext_methods && new_ext_cis && method_roots_list && ext_targets && edges );
3185
3189
* restored = (jl_array_t * )jl_delayed_reloc (& s , offset_restored );
3186
3190
* init_order = (jl_array_t * )jl_delayed_reloc (& s , offset_init_order );
3187
3191
* extext_methods = (jl_array_t * )jl_delayed_reloc (& s , offset_extext_methods );
3188
- * new_specializations = (jl_array_t * )jl_delayed_reloc (& s , offset_new_specializations );
3192
+ * new_ext_cis = (jl_array_t * )jl_delayed_reloc (& s , offset_new_ext_cis );
3189
3193
* method_roots_list = (jl_array_t * )jl_delayed_reloc (& s , offset_method_roots_list );
3190
3194
* ext_targets = (jl_array_t * )jl_delayed_reloc (& s , offset_ext_targets );
3191
3195
* edges = (jl_array_t * )jl_delayed_reloc (& s , offset_edges );
3192
- if (!* new_specializations )
3193
- * new_specializations = jl_alloc_vec_any (0 );
3194
3196
}
3195
3197
s .s = NULL ;
3196
3198
@@ -3454,8 +3456,6 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
3454
3456
jl_code_instance_t * ci = (jl_code_instance_t * )obj ;
3455
3457
assert (s .incremental );
3456
3458
ci -> min_world = world ;
3457
- if (ci -> max_world != 0 )
3458
- jl_array_ptr_1d_push (* new_specializations , (jl_value_t * )ci );
3459
3459
}
3460
3460
else if (jl_is_globalref (obj )) {
3461
3461
continue ; // wait until all the module binding tables have been initialized
@@ -3601,11 +3601,11 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i
3601
3601
assert (datastartpos > 0 && datastartpos < dataendpos );
3602
3602
needs_permalloc = jl_options .permalloc_pkgimg || needs_permalloc ;
3603
3603
jl_value_t * restored = NULL ;
3604
- jl_array_t * init_order = NULL , * extext_methods = NULL , * new_specializations = NULL , * method_roots_list = NULL , * ext_targets = NULL , * edges = NULL ;
3604
+ jl_array_t * init_order = NULL , * extext_methods = NULL , * new_ext_cis = NULL , * method_roots_list = NULL , * ext_targets = NULL , * edges = NULL ;
3605
3605
jl_svec_t * cachesizes_sv = NULL ;
3606
3606
char * base ;
3607
3607
arraylist_t ccallable_list ;
3608
- JL_GC_PUSH8 (& restored , & init_order , & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges , & cachesizes_sv );
3608
+ JL_GC_PUSH8 (& restored , & init_order , & extext_methods , & new_ext_cis , & method_roots_list , & ext_targets , & edges , & cachesizes_sv );
3609
3609
3610
3610
{ // make a permanent in-memory copy of f (excluding the header)
3611
3611
ios_bufmode (f , bm_none );
@@ -3629,17 +3629,18 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i
3629
3629
ios_close (f );
3630
3630
ios_static_buffer (f , sysimg , len );
3631
3631
pkgcachesizes cachesizes ;
3632
- jl_restore_system_image_from_stream_ (f , image , depmods , checksum , (jl_array_t * * )& restored , & init_order , & extext_methods , & new_specializations , & method_roots_list , & ext_targets , & edges , & base , & ccallable_list , & cachesizes );
3632
+ jl_restore_system_image_from_stream_ (f , image , depmods , checksum , (jl_array_t * * )& restored , & init_order , & extext_methods , & new_ext_cis , & method_roots_list ,
3633
+ & ext_targets , & edges , & base , & ccallable_list , & cachesizes );
3633
3634
JL_SIGATOMIC_END ();
3634
3635
3635
3636
// Insert method extensions
3636
3637
jl_insert_methods (extext_methods );
3637
- // No special processing of `new_specializations ` is required because recaching handled it
3638
+ // No special processing of `new_ext_cis ` is required because recaching handled it
3638
3639
// Add roots to methods
3639
3640
jl_copy_roots (method_roots_list , jl_worklist_key ((jl_array_t * )restored ));
3640
3641
// Handle edges
3641
3642
size_t world = jl_atomic_load_acquire (& jl_world_counter );
3642
- jl_insert_backedges ((jl_array_t * )edges , (jl_array_t * )ext_targets , (jl_array_t * )new_specializations , world ); // restore external backedges (needs to be last)
3643
+ jl_insert_backedges ((jl_array_t * )edges , (jl_array_t * )ext_targets , (jl_array_t * )new_ext_cis , world ); // restore external backedges (needs to be last)
3643
3644
// reinit ccallables
3644
3645
jl_reinit_ccallable (& ccallable_list , base , pkgimage_handle );
3645
3646
arraylist_free (& ccallable_list );
@@ -3653,7 +3654,8 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i
3653
3654
jl_svecset (cachesizes_sv , 4 , jl_box_long (cachesizes .reloclist ));
3654
3655
jl_svecset (cachesizes_sv , 5 , jl_box_long (cachesizes .gvarlist ));
3655
3656
jl_svecset (cachesizes_sv , 6 , jl_box_long (cachesizes .fptrlist ));
3656
- restored = (jl_value_t * )jl_svec (8 , restored , init_order , extext_methods , new_specializations , method_roots_list ,
3657
+ restored = (jl_value_t * )jl_svec (8 , restored , init_order , extext_methods ,
3658
+ new_ext_cis ? (jl_value_t * )new_ext_cis : jl_nothing , method_roots_list ,
3657
3659
ext_targets , edges , cachesizes_sv );
3658
3660
}
3659
3661
else {
0 commit comments