From 020fe5914d894b1e2bd3d85a3913bf1b27d2c118 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 1 Jul 2020 22:35:00 -0400 Subject: [PATCH] improve use of limit in stopping method search We know that dispatch tuple signatures are always disjoint and most-specific over their intersection, so they are always going to be included in the result. We can use that knowledge to abort the search quickly as we discover that there will be many specific matches. --- src/gf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gf.c b/src/gf.c index b672c466644ae..8f394099cd26d 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2507,6 +2507,7 @@ struct ml_matches_env { struct typemap_intersection_env match; int intersections; size_t world; + int lim; // results: jl_value_t *t; // array of svec(argtypes, params, Method, fully-covers) size_t min_valid; @@ -2540,6 +2541,11 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio closure->max_valid = ml->max_world; } jl_method_t *meth = ml->func.method; + if (closure->lim >= 0 && jl_is_dispatch_tupletype(meth->sig)) { + if (closure->lim == 0) + return 0; + closure->lim--; + } closure->matc = jl_svec(4, closure->match.ti, closure->match.env, meth, closure->match.issubty ? jl_true : jl_false); size_t len = jl_array_len(closure->t); if (len == 0) { @@ -2576,7 +2582,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs, else va = NULL; } - struct ml_matches_env env = {{ml_matches_visitor, (jl_value_t*)type, va}, intersections, world}; + struct ml_matches_env env = {{ml_matches_visitor, (jl_value_t*)type, va}, intersections, world, lim}; env.match.ti = NULL; env.match.env = jl_emptysvec; env.t = jl_an_empty_vec_any; @@ -2639,7 +2645,10 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs, return env.t; } } - jl_typemap_intersection_visitor(defs, offs, &env.match); + if (!jl_typemap_intersection_visitor(defs, offs, &env.match)) { + JL_GC_POP(); + return jl_false; + } *min_valid = env.min_valid; *max_valid = env.max_valid; // done with many of these values now