diff --git a/src/gc.c b/src/gc.c index 1937138a8eae0a2184b84929aaa86addc0a26786..b3e117f01a93dd7ee1c6279961d64167ea9bf20d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -6072,18 +6072,28 @@ void identify_loop_visit_ref(void *dst, int ref_type, int type = type_from_visit_fn(visit_dst); struct mc_marker *ref_to = find_mc_marker(dst); if (ref_to) { - /* Already visited. */ + /* Already visited or queued for visiting. */ return; } + ref_to = my_make_mc_marker(dst, visit_dst, extra); + if (type != PIKE_T_UNKNOWN) { struct svalue s; SET_SVAL(s, type, 0, refs, dst); low_mapping_insert(identify_loop_reverse, &s, Pike_sp-1, 0); - } - ref_to = my_make_mc_marker(dst, visit_dst, extra); - mc_wq_enqueue(ref_to); + mc_wq_enqueue(ref_to); + } else { + /* Not a valid svalue type. + * + * Probably T_MAPPING_DATA or T_MULTISET_DATA or similar. + * + * Recurse directly while we have the containing thing on the stack. + */ + ref_to->flags |= MC_FLAG_INT_VISITED; + visit_dst(dst, VISIT_COMPLEX_ONLY, extra); + } } void identify_loop_visit_leave(void *thing, int type, void *extra)