@@ -1366,6 +1366,7 @@ static void jl_collect_backedges(jl_array_t *edges, jl_array_t *ext_targets)
13661366 jl_value_t * invokeTypes ;
13671367 jl_method_instance_t * c ;
13681368 size_t i ;
1369+ size_t world = jl_get_world_counter ();
13691370 void * * table = edges_map .table ; // edges is caller => callees
13701371 size_t table_size = edges_map .size ;
13711372 for (i = 0 ; i < table_size ; i += 2 ) {
@@ -1408,15 +1409,28 @@ static void jl_collect_backedges(jl_array_t *edges, jl_array_t *ext_targets)
14081409 size_t min_valid = 0 ;
14091410 size_t max_valid = ~(size_t )0 ;
14101411 int ambig = 0 ;
1411- jl_value_t * matches = jl_matching_methods ((jl_tupletype_t * )sig , jl_nothing , -1 , 0 , jl_atomic_load_acquire (& jl_world_counter ), & min_valid , & max_valid , & ambig );
1412- if (matches == jl_false ) {
1413- valid = 0 ;
1414- break ;
1415- }
1416- size_t k ;
1417- for (k = 0 ; k < jl_array_len (matches ); k ++ ) {
1418- jl_method_match_t * match = (jl_method_match_t * )jl_array_ptr_ref (matches , k );
1419- jl_array_ptr_set (matches , k , match -> method );
1412+ jl_value_t * matches ;
1413+ if (mode == 2 && callee && jl_is_method_instance (callee ) && jl_is_type (sig )) {
1414+ // invoke, use subtyping
1415+ jl_methtable_t * mt = jl_method_get_table (((jl_method_instance_t * )callee )-> def .method );
1416+ size_t min_world , max_world ;
1417+ matches = jl_gf_invoke_lookup_worlds (sig , (jl_value_t * )mt , world , & min_world , & max_world );
1418+ if (matches == jl_nothing ) {
1419+ valid = 0 ;
1420+ break ;
1421+ }
1422+ matches = (jl_value_t * )((jl_method_match_t * )matches )-> method ;
1423+ } else {
1424+ matches = jl_matching_methods ((jl_tupletype_t * )sig , jl_nothing , -1 , 0 , jl_atomic_load_acquire (& jl_world_counter ), & min_valid , & max_valid , & ambig );
1425+ if (matches == jl_false ) {
1426+ valid = 0 ;
1427+ break ;
1428+ }
1429+ size_t k ;
1430+ for (k = 0 ; k < jl_array_len (matches ); k ++ ) {
1431+ jl_method_match_t * match = (jl_method_match_t * )jl_array_ptr_ref (matches , k );
1432+ jl_array_ptr_set (matches , k , match -> method );
1433+ }
14201434 }
14211435 jl_array_ptr_1d_push (ext_targets , mode == 1 ? NULL : sig );
14221436 jl_array_ptr_1d_push (ext_targets , callee );
@@ -2542,8 +2556,10 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids)
25422556 jl_array_t * valids = jl_alloc_array_1d (jl_array_uint8_type , l );
25432557 memset (jl_array_data (valids ), 1 , l );
25442558 jl_value_t * loctag = NULL , * matches = NULL ;
2545- JL_GC_PUSH2 (& loctag , & matches );
2559+ jl_methtable_t * mt = NULL ;
2560+ JL_GC_PUSH3 (& loctag , & matches , & mt );
25462561 * pvalids = valids ;
2562+ size_t world = jl_get_world_counter ();
25472563 for (i = 0 ; i < l ; i ++ ) {
25482564 jl_value_t * invokesig = jl_array_ptr_ref (targets , i * 3 );
25492565 jl_value_t * callee = jl_array_ptr_ref (targets , i * 3 + 1 );
@@ -2555,33 +2571,43 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids)
25552571 else {
25562572 sig = callee == NULL ? invokesig : callee ;
25572573 }
2558- jl_array_t * expected = (jl_array_t * )jl_array_ptr_ref (targets , i * 3 + 2 );
2559- assert (jl_is_array (expected ));
2574+ jl_value_t * expected = jl_array_ptr_ref (targets , i * 3 + 2 );
25602575 int valid = 1 ;
25612576 size_t min_valid = 0 ;
25622577 size_t max_valid = ~(size_t )0 ;
25632578 int ambig = 0 ;
2564- // TODO: possibly need to included ambiguities too (for the optimizer correctness)?
2565- matches = jl_matching_methods ((jl_tupletype_t * )sig , jl_nothing , -1 , 0 , jl_atomic_load_acquire (& jl_world_counter ), & min_valid , & max_valid , & ambig );
2566- if (matches == jl_false || jl_array_len (matches ) != jl_array_len (expected )) {
2567- valid = 0 ;
2568- }
2569- else {
2570- size_t j , k , l = jl_array_len (expected );
2571- for (k = 0 ; k < jl_array_len (matches ); k ++ ) {
2572- jl_method_match_t * match = (jl_method_match_t * )jl_array_ptr_ref (matches , k );
2573- jl_method_t * m = match -> method ;
2574- for (j = 0 ; j < l ; j ++ ) {
2575- if (m == (jl_method_t * )jl_array_ptr_ref (expected , j ))
2579+ int use_invoke = invokesig == NULL || callee == NULL ? 0 : 1 ;
2580+ if (!use_invoke ) {
2581+ // TODO: possibly need to included ambiguities too (for the optimizer correctness)?
2582+ matches = jl_matching_methods ((jl_tupletype_t * )sig , jl_nothing , -1 , 0 , jl_atomic_load_acquire (& jl_world_counter ), & min_valid , & max_valid , & ambig );
2583+ if (matches == jl_false || jl_array_len (matches ) != jl_array_len (expected )) {
2584+ valid = 0 ;
2585+ }
2586+ else {
2587+ assert (jl_is_array (expected ));
2588+ size_t j , k , l = jl_array_len (expected );
2589+ for (k = 0 ; k < jl_array_len (matches ); k ++ ) {
2590+ jl_method_match_t * match = (jl_method_match_t * )jl_array_ptr_ref (matches , k );
2591+ jl_method_t * m = match -> method ;
2592+ for (j = 0 ; j < l ; j ++ ) {
2593+ if (m == (jl_method_t * )jl_array_ptr_ref (expected , j ))
2594+ break ;
2595+ }
2596+ if (j == l ) {
2597+ // intersection has a new method or a method was
2598+ // deleted--this is now probably no good, just invalidate
2599+ // everything about it now
2600+ valid = 0 ;
25762601 break ;
2602+ }
25772603 }
2578- if ( j == l ) {
2579- // intersection has a new method or a method was
2580- // deleted--this is now probably no good, just invalidate
2581- // everything about it now
2582- valid = 0 ;
2583- break ;
2584- }
2604+ }
2605+ } else {
2606+ mt = jl_method_get_table ((( jl_method_instance_t * ) callee ) -> def . method );
2607+ size_t min_world , max_world ;
2608+ matches = jl_gf_invoke_lookup_worlds ( invokesig , ( jl_value_t * ) mt , world , & min_world , & max_world ) ;
2609+ if ( matches == jl_nothing || expected != ( jl_value_t * )(( jl_method_match_t * ) matches ) -> method ) {
2610+ valid = 0 ;
25852611 }
25862612 }
25872613 jl_array_uint8_set (valids , i , valid );
@@ -2593,7 +2619,7 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids)
25932619 jl_array_ptr_1d_push (_jl_debug_method_invalidation , loctag );
25942620 loctag = jl_box_uint64 (jl_worklist_key (serializer_worklist ));
25952621 jl_array_ptr_1d_push (_jl_debug_method_invalidation , loctag );
2596- if (matches != jl_false ) {
2622+ if (! use_invoke && matches != jl_false ) {
25972623 // setdiff!(matches, expected)
25982624 size_t j , k , ins = 0 ;
25992625 for (j = 0 ; j < jl_array_len (matches ); j ++ ) {
0 commit comments