From 10350b31f100991eb8834dc182ce075deabbcfe2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Tue, 24 Jun 2014 11:41:12 +0200
Subject: [PATCH] Pike.identify_cycle: Fixed support for mappings and
 multisets.

References from mapping_data and multiset_data were not registered
on their corresponding mapping or multiset, but on the initial
argument to Pike.identify_cycle().
---
 src/gc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/gc.c b/src/gc.c
index 1937138a8e..b3e117f01a 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)
-- 
GitLab