@@ -513,7 +513,7 @@ static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_tupletype_t *sig)
513513
514514static jl_value_t * ml_matches (union jl_typemap_t ml , int offs ,
515515 jl_tupletype_t * type , int lim , int include_ambiguous ,
516- size_t world );
516+ size_t world , size_t * min_valid , size_t * max_valid );
517517
518518static void jl_cacheable_sig (
519519 jl_tupletype_t * const type , // the specialized type signature for type lambda
@@ -841,6 +841,8 @@ static jl_method_instance_t *cache_method(jl_methtable_t *mt, union jl_typemap_t
841841 need_guard_entries = 1 ;
842842 }
843843
844+ size_t min_valid = definition -> min_world ;
845+ size_t max_valid = definition -> max_world ;
844846 int cache_with_orig = 0 ;
845847 jl_svec_t * guardsigs = jl_emptysvec ;
846848 jl_tupletype_t * origtype = type ; // backup the prior value of `type`
@@ -849,7 +851,7 @@ static jl_method_instance_t *cache_method(jl_methtable_t *mt, union jl_typemap_t
849851 temp2 = (jl_value_t * )type ;
850852 }
851853 if (need_guard_entries ) {
852- temp = ml_matches (mt -> defs , 0 , type , -1 , 0 , 0 ); // TODO: use MAX_UNSPECIALIZED_CONFLICTS?
854+ temp = ml_matches (mt -> defs , 0 , type , -1 , 0 , world , & min_valid , & max_valid ); // TODO: use MAX_UNSPECIALIZED_CONFLICTS?
853855 int guards = 0 ;
854856 if (temp == jl_false ) {
855857 cache_with_orig = 1 ;
@@ -890,18 +892,23 @@ static jl_method_instance_t *cache_method(jl_methtable_t *mt, union jl_typemap_t
890892 guards = 0 ;
891893 for (i = 0 , l = jl_array_len (temp ); i < l ; i ++ ) {
892894 jl_value_t * m = jl_array_ptr_ref (temp , i );
893- if (((jl_method_t * )jl_svecref (m ,2 )) != definition ) {
895+ jl_method_t * other = (jl_method_t * )jl_svecref (m , 2 );
896+ if (other != definition ) {
894897 jl_svecset (guardsigs , guards , (jl_tupletype_t * )jl_svecref (m , 0 ));
895898 guards ++ ;
896899 //jl_typemap_insert(cache, parent, (jl_tupletype_t*)jl_svecref(m, 0),
897- // jl_emptysvec, NULL, jl_emptysvec, /*guard*/NULL, jl_cachearg_offset(mt), &lambda_cache, 1, ~(size_t)0 , NULL);
900+ // jl_emptysvec, NULL, jl_emptysvec, /*guard*/NULL, jl_cachearg_offset(mt), &lambda_cache, other->min_world, other->max_world , NULL);
898901 }
899902 }
900903 }
901904 }
902905
903906 // here we infer types and specialize the method
904907 newmeth = jl_specializations_get_linfo (definition , type , sparams , world );
908+ if (newmeth -> min_world < min_valid )
909+ min_valid = newmeth -> min_world ;
910+ if (newmeth -> max_world < max_valid )
911+ max_valid = newmeth -> max_world ;
905912
906913 if (cache_with_orig ) {
907914 // if there is a need to cache with one of the original signatures,
@@ -940,7 +947,7 @@ static jl_method_instance_t *cache_method(jl_methtable_t *mt, union jl_typemap_t
940947 }
941948
942949 jl_typemap_insert (cache , parent , origtype , jl_emptysvec , type , guardsigs , (jl_value_t * )newmeth , jl_cachearg_offset (mt ), & lambda_cache ,
943- newmeth -> min_world , newmeth -> max_world , NULL );
950+ min_valid , max_valid , NULL );
944951
945952 if (definition -> traced && jl_method_tracer && allow_exec )
946953 jl_call_tracer (jl_method_tracer , (jl_value_t * )newmeth );
@@ -1439,18 +1446,24 @@ jl_method_instance_t *jl_method_lookup(jl_methtable_t *mt, jl_value_t **args, si
14391446//
14401447// lim is the max # of methods to return. if there are more, returns jl_false.
14411448// -1 for no limit.
1442- JL_DLLEXPORT jl_value_t * jl_matching_methods (jl_tupletype_t * types , int lim , int include_ambiguous , size_t world )
1449+ JL_DLLEXPORT jl_value_t * jl_matching_methods (jl_tupletype_t * types , int lim , int include_ambiguous , size_t world , size_t * min_valid , size_t * max_valid )
14431450{
14441451 assert (jl_nparams (types ) > 0 );
1445- if (jl_tparam0 (types ) == jl_bottom_type )
1446- return (jl_value_t * )jl_alloc_vec_any (0 );
1447- if (!jl_is_datatype (jl_tparam0 (types ))) {
1452+ jl_value_t * matches = NULL ;
1453+ if (jl_tparam0 (types ) == jl_bottom_type ) {
1454+ matches = (jl_value_t * )jl_alloc_vec_any (0 );
1455+ }
1456+ else if (!jl_is_datatype (jl_tparam0 (types ))) {
14481457 return jl_false ; // indeterminate - ml_matches can't deal with this case
14491458 }
1450- jl_methtable_t * mt = ((jl_datatype_t * )jl_tparam0 (types ))-> name -> mt ;
1451- if (mt == NULL )
1452- return (jl_value_t * )jl_alloc_vec_any (0 );
1453- return ml_matches (mt -> defs , 0 , types , lim , include_ambiguous , world );
1459+ else {
1460+ jl_methtable_t * mt = ((jl_datatype_t * )jl_tparam0 (types ))-> name -> mt ;
1461+ if (mt == NULL )
1462+ matches = (jl_value_t * )jl_alloc_vec_any (0 );
1463+ else
1464+ matches = ml_matches (mt -> defs , 0 , types , lim , include_ambiguous , world , min_valid , max_valid );
1465+ }
1466+ return matches ;
14541467}
14551468
14561469jl_llvm_functions_t jl_compile_for_dispatch (jl_method_instance_t * * pli , size_t world )
@@ -1520,8 +1533,10 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world
15201533 // if one argument type is DataType, multiple Type{} definitions
15211534 // might match. also be conservative with tuples rather than trying
15221535 // to analyze them in detail.
1536+ size_t min_valid = 0 ;
1537+ size_t max_valid = ~(size_t )0 ;
15231538 if (ti == (jl_value_t * )jl_datatype_type || jl_is_tuple_type (ti )) {
1524- jl_value_t * matches = jl_matching_methods (types , 1 , 0 , world );
1539+ jl_value_t * matches = jl_matching_methods (types , 1 , 0 , world , & min_valid , & max_valid );
15251540 if (matches == jl_false )
15261541 return NULL ;
15271542 break ;
@@ -2259,19 +2274,30 @@ static int tvar_exists_at_top_level(jl_value_t *tv, jl_tupletype_t *sig, int att
22592274
22602275struct ml_matches_env {
22612276 struct typemap_intersection_env match ;
2262- jl_value_t * t ; // results: array of svec(argtypes, params, Method)
2277+ // results:
2278+ jl_value_t * t ; // array of svec(argtypes, params, Method)
2279+ size_t min_valid ;
2280+ size_t max_valid ;
2281+ // temporary:
22632282 jl_svec_t * matc ; // current working svec
2283+ // inputs:
2284+ size_t world ;
22642285 int lim ;
22652286 int include_ambiguous ; // whether ambiguous matches should be included
2266- size_t world ;
22672287};
22682288static int ml_matches_visitor (jl_typemap_entry_t * ml , struct typemap_intersection_env * closure0 )
22692289{
22702290 struct ml_matches_env * closure = container_of (closure0 , struct ml_matches_env , match );
22712291 int i ;
2272- if (closure -> world != 0 ) // use zero as a flag value for returning all matches
2273- if (closure -> world < ml -> min_world || closure -> world > ml -> max_world )
2292+ if (closure -> world != 0 ) { // use zero as a flag value for returning all matches
2293+ if (ml -> min_world < closure -> min_valid )
2294+ closure -> min_valid = ml -> min_world ;
2295+ if (ml -> max_world > closure -> max_valid )
2296+ closure -> max_valid = ml -> max_world ;
2297+ if (closure -> world < ml -> min_world || closure -> world > ml -> max_world ) {
22742298 return 1 ; // ignore method table entries that are not part of this world
2299+ }
2300+ }
22752301 // a method is shadowed if type <: S <: m->sig where S is the
22762302 // signature of another applicable method
22772303 /*
@@ -2412,7 +2438,7 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio
24122438// See below for the meaning of lim.
24132439static jl_value_t * ml_matches (union jl_typemap_t defs , int offs ,
24142440 jl_tupletype_t * type , int lim , int include_ambiguous ,
2415- size_t world )
2441+ size_t world , size_t * min_valid , size_t * max_valid )
24162442{
24172443 size_t l = jl_svec_len (type -> parameters );
24182444 jl_value_t * va = NULL ;
@@ -2434,9 +2460,13 @@ static jl_value_t *ml_matches(union jl_typemap_t defs, int offs,
24342460 env .lim = lim ;
24352461 env .include_ambiguous = include_ambiguous ;
24362462 env .world = world ;
2463+ env .min_valid = * min_valid ;
2464+ env .max_valid = * max_valid ;
24372465 JL_GC_PUSH4 (& env .t , & env .matc , & env .match .env , & env .match .ti );
24382466 jl_typemap_intersection_visitor (defs , offs , & env .match );
24392467 JL_GC_POP ();
2468+ * min_valid = env .min_valid ;
2469+ * max_valid = env .max_valid ;
24402470 return env .t ;
24412471}
24422472
0 commit comments