Skip to content

Commit 6f10b8f

Browse files
committed
fixup! avoid invalidations when it doesn't resolve an MethodError
Be less conservative
1 parent f62b8f3 commit 6f10b8f

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

src/gf.c

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,9 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
16611661
jl_svec_t *specializations = jl_atomic_load_acquire(&m->specializations);
16621662
jl_method_instance_t **data = (jl_method_instance_t**)jl_svec_data(specializations);
16631663
size_t i, l = jl_svec_len(specializations);
1664+
int invalid = 0;
16641665
int shadowing = 0;
1666+
int ambig = 0;
16651667
for (i = 0; i < l; i++) {
16661668
jl_method_instance_t *mi = jl_atomic_load_relaxed(&data[i]);
16671669
if (mi == NULL)
@@ -1672,35 +1674,40 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
16721674
if (jl_type_morespecific(m->sig, type))
16731675
// not actually shadowing--the existing method is still better
16741676
break;
1675-
if (!jl_type_morespecific(type, mi->def.method->sig)) {
1676-
// adding an ambiguity--see if there already was one
1677-
size_t k;
1678-
for (k = 0; k < n; k++) {
1679-
jl_method_t *m2 = d[k];
1680-
if (m == m2 || !jl_subtype(isect, m2->sig))
1681-
continue;
1682-
if (k > i) {
1683-
if (jl_type_morespecific(m2->sig, type)) {
1684-
// not actually shadowing this--m2 will still be better
1685-
morespec[k] = 1;
1686-
continue;
1687-
}
1688-
}
1689-
if (!jl_type_morespecific(m->sig, m2->sig) &&
1690-
!jl_type_morespecific(m2->sig, m->sig)) {
1677+
shadowing = 1;
1678+
ambig = !jl_type_morespecific(type, m->sig);
1679+
}
1680+
// replacing a method--see if this really was the selected method previously
1681+
// over the intersection
1682+
if (ambig) {
1683+
size_t k;
1684+
for (k = 0; k < n; k++) {
1685+
jl_method_t *m2 = d[k];
1686+
if (m == m2 || !jl_subtype(isect, m2->sig))
1687+
continue;
1688+
if (morespec[k])
1689+
break;
1690+
if (k > j) { // possibly haven't actually computed morespec yet
1691+
if (jl_type_morespecific(m2->sig, type)) {
1692+
// not actually shadowing this--m2 will still be better
1693+
morespec[k] = 1;
16911694
break;
16921695
}
16931696
}
1694-
if (k != n)
1695-
continue;
1697+
// since m2 was also a previous match over isect,
1698+
// see if m was also previously dominant over m2
1699+
if (!jl_type_morespecific(m->sig, m2->sig))
1700+
break;
16961701
}
1697-
shadowing = 1;
1702+
if (k != n)
1703+
continue;
16981704
}
1705+
invalid = 1;
16991706
if (mi->backedges)
17001707
invalidate_backedges(mi, max_world, "jl_method_table_insert");
17011708
}
17021709
}
1703-
if (shadowing == 0)
1710+
if (invalid == 0)
17041711
morespec[j] = 1; // the method won't need to be dropped from any cache
17051712
}
17061713
for (j = 0; j < n; j++) {

0 commit comments

Comments
 (0)