Skip to content

Commit 7a69201

Browse files
committed
fix #265
1 parent 855b846 commit 7a69201

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/gf.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,42 @@ static void update_max_args(jl_methtable_t *mt, jl_tupletype_t *type)
10041004
}
10051005

10061006
// invalidate cached methods that overlap this definition
1007+
struct invalidate_spec_env {
1008+
jl_lambda_info_t *replaced;
1009+
size_t max_world;
1010+
int invalidated;
1011+
};
1012+
static int invalidate_spec(jl_typemap_entry_t *oldentry, void *closure)
1013+
{
1014+
struct invalidate_spec_env *env = (struct invalidate_spec_env*)closure;
1015+
if (oldentry->func.linfo == env->replaced) {
1016+
if (oldentry->max_world > env->max_world) {
1017+
oldentry->max_world = env->max_world;
1018+
env->invalidated = 1;
1019+
}
1020+
}
1021+
return 1;
1022+
}
1023+
static void invalidate_conflicting_recursive(jl_lambda_info_t *oldentry, size_t max_world)
1024+
{
1025+
if (oldentry->backedges) {
1026+
size_t i, l = jl_array_len(oldentry->backedges);
1027+
for (i = 0; i < l; i++) {
1028+
struct invalidate_spec_env env;
1029+
env.max_world = max_world;
1030+
env.invalidated = 0;
1031+
env.replaced = (jl_lambda_info_t*)jl_array_ptr_ref(oldentry->backedges, i);
1032+
jl_method_t *m = env.replaced->def;
1033+
jl_typemap_visitor(m->specializations, invalidate_spec, &env);
1034+
jl_datatype_t *gf = jl_first_argument_datatype((jl_value_t*)m->sig);
1035+
assert(jl_is_datatype(gf) && gf->name->mt);
1036+
jl_typemap_visitor(gf->name->mt->cache, invalidate_spec, &env);
1037+
1038+
if (env.invalidated)
1039+
invalidate_conflicting_recursive(env.replaced, max_world);
1040+
}
1041+
}
1042+
}
10071043
struct invalidate_conflicting_env {
10081044
struct typemap_intersection_env match;
10091045
jl_array_t *shadowed;
@@ -1013,10 +1049,11 @@ static int invalidate_conflicting(jl_typemap_entry_t *oldentry, struct typemap_i
10131049
{
10141050
struct invalidate_conflicting_env *closure = container_of(closure0, struct invalidate_conflicting_env, match);
10151051
size_t i, n = jl_array_len(closure->shadowed);
1016-
jl_value_t **d = jl_array_ptr_data(closure->shadowed);
1052+
jl_method_t **d = (jl_method_t**)jl_array_ptr_data(closure->shadowed);
10171053
for (i = 0; i < n; i++) {
1018-
if (d[i] == (jl_value_t*)oldentry->func.linfo->def) {
1054+
if (d[i] == oldentry->func.linfo->def) {
10191055
oldentry->max_world = closure->max_world;
1056+
invalidate_conflicting_recursive(oldentry->func.linfo, closure->max_world);
10201057
return 1;
10211058
}
10221059
}
@@ -1064,6 +1101,12 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
10641101
env.match.type = (jl_value_t*)type;
10651102
env.max_world = method->min_world - 1;
10661103
jl_typemap_intersection_visitor(mt->cache, jl_cachearg_offset(mt), &env.match);
1104+
1105+
size_t i, n = jl_array_len(env.shadowed);
1106+
jl_method_t **d = (jl_method_t**)jl_array_ptr_data(env.shadowed);
1107+
for (i = 0; i < n; i++) {
1108+
jl_typemap_intersection_visitor(d[i]->specializations, 0, &env.match);
1109+
}
10671110
}
10681111
update_max_args(mt, type);
10691112
JL_UNLOCK(&mt->writelock);

0 commit comments

Comments
 (0)