11static htable_t new_code_instance_validate ;
2- static htable_t external_mis ;
2+
33
44// inverse of backedges graph (caller=>callees hash)
55jl_array_t * edges_map JL_GLOBALLY_ROOTED = NULL ; // rooted for the duration of our uses of this
@@ -108,11 +108,6 @@ JL_DLLEXPORT void jl_push_newly_inferred(jl_value_t* ci)
108108}
109109
110110
111- static int method_instance_in_queue (jl_method_instance_t * mi )
112- {
113- return ptrhash_get (& external_mis , mi ) != HT_NOTFOUND ;
114- }
115-
116111// compute whether a type references something internal to worklist
117112// and thus could not have existed before deserialize
118113// and thus does not need delayed unique-ing
@@ -216,10 +211,10 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited,
216211 return found ;
217212}
218213
219- // given the list of CodeInstances that were inferred during the
220- // build, select those that are (1) external, and (2 ) are inferred to be called
221- // from the worklist or explicitly added by a `precompile` statement.
222- // Also prepares for method_instance_in_queue queries .
214+ // Given the list of CodeInstances that were inferred during the build, select
215+ // those that are (1) external, (2) still valid, and (3 ) are inferred to be
216+ // called from the worklist or explicitly added by a `precompile` statement.
217+ // These will be preserved in the image .
223218static jl_array_t * queue_external_cis (jl_array_t * list )
224219{
225220 if (list == NULL )
@@ -238,17 +233,12 @@ static jl_array_t *queue_external_cis(jl_array_t *list)
238233 assert (jl_is_code_instance (ci ));
239234 jl_method_instance_t * mi = ci -> def ;
240235 jl_method_t * m = mi -> def .method ;
241- if (jl_is_method (m )) {
242- if (jl_object_in_image ((jl_value_t * )m -> module )) {
243- if (ptrhash_get (& external_mis , mi ) == HT_NOTFOUND ) {
244- int found = has_backedge_to_worklist (mi , & visited , & stack );
245- assert (found == 0 || found == 1 );
246- assert (stack .len == 0 );
247- if (found == 1 ) {
248- ptrhash_put (& external_mis , mi , mi );
249- jl_array_ptr_1d_push (new_specializations , (jl_value_t * )ci );
250- }
251- }
236+ if (jl_is_method (m ) && jl_object_in_image ((jl_value_t * )m -> module )) {
237+ int found = has_backedge_to_worklist (mi , & visited , & stack );
238+ assert (found == 0 || found == 1 );
239+ assert (stack .len == 0 );
240+ if (found == 1 && ci -> max_world == ~(size_t )0 ) {
241+ jl_array_ptr_1d_push (new_specializations , (jl_value_t * )ci );
252242 }
253243 }
254244 }
@@ -259,31 +249,25 @@ static jl_array_t *queue_external_cis(jl_array_t *list)
259249}
260250
261251// New roots for external methods
262- static void jl_collect_methods ( htable_t * mset , jl_array_t * new_specializations )
252+ static void jl_collect_new_roots ( jl_array_t * roots , jl_array_t * new_specializations , uint64_t key )
263253{
264- size_t i , l = new_specializations ? jl_array_len ( new_specializations ) : 0 ;
265- jl_value_t * v ;
266- jl_method_t * m ;
267- for (i = 0 ; i < l ; i ++ ) {
268- v = jl_array_ptr_ref (new_specializations , i );
269- assert (jl_is_code_instance (v ));
270- m = (( jl_code_instance_t * ) v ) -> def -> def .method ;
254+ htable_t mset ;
255+ htable_new ( & mset , 0 ) ;
256+ size_t l = new_specializations ? jl_array_len ( new_specializations ) : 0 ;
257+ for (size_t i = 0 ; i < l ; i ++ ) {
258+ jl_code_instance_t * ci = ( jl_code_instance_t * ) jl_array_ptr_ref (new_specializations , i );
259+ assert (jl_is_code_instance (ci ));
260+ jl_method_t * m = ci -> def -> def .method ;
271261 assert (jl_is_method (m ));
272- ptrhash_put (mset , (void * )m , (void * )m );
262+ ptrhash_put (& mset , (void * )m , (void * )m );
273263 }
274- }
275-
276- static void jl_collect_new_roots (jl_array_t * roots , const htable_t * mset , uint64_t key )
277- {
278- size_t i , sz = mset -> size ;
279264 int nwithkey ;
280- jl_method_t * m ;
281- void * const * table = mset -> table ;
265+ void * const * table = mset .table ;
282266 jl_array_t * newroots = NULL ;
283267 JL_GC_PUSH1 (& newroots );
284- for (i = 0 ; i < sz ; i += 2 ) {
268+ for (size_t i = 0 ; i < mset . size ; i += 2 ) {
285269 if (table [i + 1 ] != HT_NOTFOUND ) {
286- m = (jl_method_t * )table [i ];
270+ jl_method_t * m = (jl_method_t * )table [i ];
287271 assert (jl_is_method (m ));
288272 nwithkey = nroots_with_key (m , key );
289273 if (nwithkey ) {
@@ -305,6 +289,7 @@ static void jl_collect_new_roots(jl_array_t *roots, const htable_t *mset, uint64
305289 }
306290 }
307291 JL_GC_POP ();
292+ htable_free (& mset );
308293}
309294
310295// Create the forward-edge map (caller => callees)
@@ -422,9 +407,18 @@ static void jl_record_edges(jl_method_instance_t *caller, arraylist_t *wq, jl_ar
422407// Extract `edges` and `ext_targets` from `edges_map`
423408// `edges` = [caller1, targets_indexes1, ...], the list of methods and their edges
424409// `ext_targets` is [invokesig1, callee1, matches1, ...], the edges for each target
425- static void jl_collect_edges (jl_array_t * edges , jl_array_t * ext_targets )
410+ static void jl_collect_edges (jl_array_t * edges , jl_array_t * ext_targets , jl_array_t * external_cis )
426411{
427412 size_t world = jl_atomic_load_acquire (& jl_world_counter );
413+ htable_t external_mis ;
414+ htable_new (& external_mis , 0 );
415+ if (external_cis ) {
416+ for (size_t i = 0 ; i < jl_array_len (external_cis ); i ++ ) {
417+ jl_code_instance_t * ci = (jl_code_instance_t * )jl_array_ptr_ref (external_cis , i );
418+ jl_method_instance_t * mi = ci -> def ;
419+ ptrhash_put (& external_mis , (void * )mi , (void * )mi );
420+ }
421+ }
428422 arraylist_t wq ;
429423 arraylist_new (& wq , 0 );
430424 void * * table = (void * * )jl_array_data (edges_map ); // edges_map is caller => callees
@@ -438,10 +432,11 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets)
438432 continue ;
439433 assert (jl_is_method_instance (caller ) && jl_is_method (caller -> def .method ));
440434 if (!jl_object_in_image ((jl_value_t * )caller -> def .method -> module ) ||
441- method_instance_in_queue ( caller )) {
435+ ptrhash_get ( & external_mis , caller ) != HT_NOTFOUND ) {
442436 jl_record_edges (caller , & wq , edges );
443437 }
444438 }
439+ htable_free (& external_mis );
445440 while (wq .len ) {
446441 jl_method_instance_t * caller = (jl_method_instance_t * )arraylist_pop (& wq );
447442 jl_record_edges (caller , & wq , edges );
@@ -1060,6 +1055,7 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a
10601055 htable_reset (& visited , l );
10611056 for (i = 0 ; i < l ; i ++ ) {
10621057 jl_code_instance_t * ci = (jl_code_instance_t * )jl_array_ptr_ref (ci_list , i );
1058+ assert (ci -> max_world == 1 || ci -> max_world == ~(size_t )0 );
10631059 assert (ptrhash_get (& visited , (void * )ci -> def ) == HT_NOTFOUND ); // check that we don't have multiple cis for same mi
10641060 ptrhash_put (& visited , (void * )ci -> def , (void * )ci );
10651061 }
@@ -1120,7 +1116,7 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a
11201116 assert (jl_is_code_instance (ci ));
11211117 jl_code_instance_t * codeinst = (jl_code_instance_t * )ci ;
11221118 remove_code_instance_from_validation (codeinst ); // mark it as handled
1123- assert (codeinst -> min_world > = world && codeinst -> inferred );
1119+ assert (codeinst -> min_world = = world && codeinst -> inferred );
11241120 codeinst -> max_world = ~(size_t )0 ;
11251121 if (jl_rettype_inferred (caller , world , ~(size_t )0 ) == jl_nothing ) {
11261122 jl_mi_cache_insert (caller , codeinst );
@@ -1160,8 +1156,8 @@ static void validate_new_code_instances(void)
11601156 //assert(0 && "unexpected unprocessed CodeInstance found");
11611157 jl_code_instance_t * ci = (jl_code_instance_t * )new_code_instance_validate .table [i ];
11621158 JL_GC_PROMISE_ROOTED (ci ); // TODO: this needs a root (or restructuring to avoid it)
1163- assert (ci -> min_world > = world && ci -> inferred );
1164- ci -> max_world = ~(size_t )0 ;
1159+ assert (ci -> min_world = = world && ci -> inferred );
1160+ assert ( ci -> max_world == ~(size_t )0 ) ;
11651161 jl_method_instance_t * caller = ci -> def ;
11661162 if (jl_rettype_inferred (caller , world , ~(size_t )0 ) == jl_nothing ) {
11671163 jl_mi_cache_insert (caller , ci );
0 commit comments