Skip to content

Commit 6c54523

Browse files
committed
avoid recomputing ml-matches worlds during method-caching [NFCI]
1 parent be77eb8 commit 6c54523

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

src/gf.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ static jl_method_instance_t *cache_method(
953953
jl_methtable_t *mt, jl_typemap_t **cache, jl_value_t *parent JL_PROPAGATES_ROOT,
954954
jl_tupletype_t *tt, // the original tupletype of the signature
955955
jl_method_t *definition,
956-
size_t world,
956+
size_t world, size_t min_valid, size_t max_valid,
957957
jl_svec_t *sparams)
958958
{
959959
// caller must hold the mt->writelock
@@ -996,12 +996,12 @@ static jl_method_instance_t *cache_method(
996996

997997
jl_tupletype_t *cachett = tt;
998998
jl_svec_t* guardsigs = jl_emptysvec;
999-
size_t min_valid = 1;
1000-
size_t max_valid = ~(size_t)0;
1001999
if (!cache_with_orig && mt) {
10021000
// now examine what will happen if we chose to use this sig in the cache
10031001
// TODO: should we first check `compilationsig <: definition`?
1004-
temp = ml_matches(mt, 0, compilationsig, MAX_UNSPECIALIZED_CONFLICTS, 1, world, &min_valid, &max_valid, 0);
1002+
size_t min_valid2 = 1;
1003+
size_t max_valid2 = ~(size_t)0;
1004+
temp = ml_matches(mt, 0, compilationsig, MAX_UNSPECIALIZED_CONFLICTS, 1, world, &min_valid2, &max_valid2, 0);
10051005
int guards = 0;
10061006
if (temp == jl_false) {
10071007
cache_with_orig = 1;
@@ -1052,22 +1052,14 @@ static jl_method_instance_t *cache_method(
10521052
}
10531053
}
10541054
}
1055-
if (cache_with_orig) {
1056-
min_valid = 1;
1057-
max_valid = ~(size_t)0;
1058-
}
1059-
else {
1055+
if (!cache_with_orig) {
10601056
// determined above that there's no ambiguity in also using compilationsig as the cacheablesig
1057+
min_valid = min_valid2;
1058+
max_valid = max_valid2;
10611059
cachett = compilationsig;
10621060
}
10631061
}
10641062

1065-
if (cache_with_orig && mt) {
1066-
// now examine defs to determine the min/max-valid range for this lookup result
1067-
(void)ml_matches(mt, 0, cachett, -1, 0, world, &min_valid, &max_valid, 0);
1068-
}
1069-
assert(mt == NULL || min_valid > 1);
1070-
10711063
// now scan `cachett` and ensure that `Type{T}` in the cache will be matched exactly by `typeof(T)`
10721064
// and also reduce the complexity of rejecting this entry in the cache
10731065
// by replacing non-simple types with jl_any_type to build a new `type`
@@ -1229,7 +1221,7 @@ static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_datatype
12291221
entry = jl_typemap_morespecific_by_type(entry, (jl_value_t*)tt, &search.env, world);
12301222
if (entry != NULL) {
12311223
jl_method_t *m = entry->func.method;
1232-
nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, tt, m, world, search.env);
1224+
nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, tt, m, world, search.min_valid, search.max_valid, search.env);
12331225
}
12341226
}
12351227
JL_GC_POP();
@@ -2088,7 +2080,13 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES
20882080
return NULL;
20892081

20902082
// find if exactly 1 method matches (issue #7302)
2091-
jl_value_t *matches = jl_matching_methods(types, 1, 1, world, min_valid, max_valid);
2083+
size_t min_valid2 = 1;
2084+
size_t max_valid2 = ~(size_t)0;
2085+
jl_value_t *matches = jl_matching_methods(types, 1, 1, world, &min_valid2, &max_valid2);
2086+
if (*min_valid < min_valid2)
2087+
*min_valid = min_valid2;
2088+
if (*max_valid > max_valid2)
2089+
*max_valid = max_valid2;
20922090
if (matches == jl_false || jl_array_len(matches) != 1)
20932091
return NULL;
20942092
jl_tupletype_t *tt = NULL;
@@ -2109,7 +2107,7 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES
21092107
// inject it there now if we think it will be
21102108
// used via dispatch later (e.g. because it was hinted via a call to `precompile`)
21112109
JL_LOCK(&mt->writelock);
2112-
nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, ti, m, world, env);
2110+
nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, ti, m, world, min_valid2, max_valid2, env);
21132111
JL_UNLOCK(&mt->writelock);
21142112
}
21152113
else {
@@ -2538,7 +2536,7 @@ static jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t *gf, j
25382536
if (method->invokes == NULL)
25392537
method->invokes = jl_nothing;
25402538

2541-
mfunc = cache_method(NULL, &method->invokes, (jl_value_t*)method, tt, method, 1, tpenv);
2539+
mfunc = cache_method(NULL, &method->invokes, (jl_value_t*)method, tt, method, 1, 1, ~(size_t)0, tpenv);
25422540
JL_UNLOCK(&method->writelock);
25432541
JL_GC_POP();
25442542
if (jl_options.malloc_log)
@@ -2588,7 +2586,7 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_typemap_entry_t *entry, jl_valu
25882586
method->invokes = jl_nothing;
25892587

25902588
jl_method_instance_t *mfunc = cache_method(NULL, &method->invokes, (jl_value_t*)method,
2591-
(jl_tupletype_t*)tt, method, 1, tpenv);
2589+
(jl_tupletype_t*)tt, method, 1, 1, ~(size_t)0, tpenv);
25922590
JL_GC_POP();
25932591
JL_UNLOCK(&method->writelock);
25942592
return (jl_value_t*)mfunc;
@@ -2930,7 +2928,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs,
29302928
env.matc = (jl_svec_t*)jl_array_ptr_ref(env.t, 0);
29312929
jl_method_t *meth = (jl_method_t*)jl_svecref(env.matc, 2);
29322930
jl_svec_t *tpenv = (jl_svec_t*)jl_svecref(env.matc, 1);
2933-
cache_method(mt, &mt->cache, (jl_value_t*)mt, type, meth, world, tpenv);
2931+
cache_method(mt, &mt->cache, (jl_value_t*)mt, type, meth, world, env.min_valid, env.max_valid, tpenv);
29342932
}
29352933
}
29362934
JL_GC_POP();

0 commit comments

Comments
 (0)