diff --git a/src/array.c b/src/array.c
index 2bd6c2f4db324c51402d54f56a9237f0d0f9f48c..e75094065934000c5790fbd880d97c8f6deef877 100644
--- a/src/array.c
+++ b/src/array.c
@@ -2816,7 +2816,7 @@ PMOD_EXPORT void visit_array (struct array *a, int action, void *extra)
     size_t e, s = a->size;
     int ref_type = a->flags & ARRAY_WEAK_FLAG ? REF_TYPE_WEAK : REF_TYPE_NORMAL;
     for (e = 0; e < s; e++)
-      visit_svalue (ITEM (a) + e, ref_type);
+      visit_svalue (ITEM (a) + e, ref_type, extra);
   }
 }
 
diff --git a/src/array.h b/src/array.h
index b296628af70bb1e4974ae77a423af8826f84b622..abb99c6e53b2e34fb15a42cb1323c53c345c7b5f 100644
--- a/src/array.h
+++ b/src/array.h
@@ -219,9 +219,9 @@ PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b);
 
 #define array_get_flags(a) ((a)->flags)
 
-#define visit_array_ref(A, REF_TYPE)					\
+#define visit_array_ref(A, REF_TYPE, EXTRA)				\
   visit_ref (pass_array (A), (REF_TYPE),				\
-	     (visit_thing_fn *) &visit_array, NULL)
+	     (visit_thing_fn *) &visit_array, (EXTRA))
 #define gc_cycle_check_array(X, WEAK) \
   gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_array, (X), (WEAK))
 
diff --git a/src/constants.c b/src/constants.c
index 4a333fd103ccfd9a8c0731b2776c92def8587e08..6071d0c9996af8314814f499bfa69605029c1ca8 100644
--- a/src/constants.c
+++ b/src/constants.c
@@ -194,7 +194,7 @@ PMOD_EXPORT void quick_add_efun(const char *name, ptrdiff_t name_length,
   free_string(n);
 }
 
-PMOD_EXPORT void visit_callable (struct callable *c, int action)
+PMOD_EXPORT void visit_callable (struct callable *c, int action, void *extra)
 {
   switch (action) {
 #ifdef PIKE_DEBUG
@@ -210,8 +210,8 @@ PMOD_EXPORT void visit_callable (struct callable *c, int action)
   }
 
   if (!(action & VISIT_COMPLEX_ONLY)) {
-    visit_type_ref (c->type, REF_TYPE_NORMAL);
-    visit_string_ref (c->name, REF_TYPE_NORMAL);
+    visit_type_ref (c->type, REF_TYPE_NORMAL, extra);
+    visit_string_ref (c->name, REF_TYPE_NORMAL, extra);
   }
 
   /* Looks like the c->prog isn't refcounted..? */
diff --git a/src/constants.h b/src/constants.h
index 4934f3d9889f05a07963e68ed8757cf14ee0e69d..4357e2035e3504be98b50ec9bd0bc3cacff5c581 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -75,14 +75,14 @@ PMOD_EXPORT void quick_add_efun(const char *name, ptrdiff_t name_length,
                                 int flags,
                                 optimize_fun optimize,
                                 docode_fun docode);
-PMOD_EXPORT void visit_callable (struct callable *c, int action);
+PMOD_EXPORT void visit_callable (struct callable *c, int action, void *extra);
 void init_builtin_constants(void);
 void exit_builtin_constants(void);
 /* Prototypes end here */
 
-#define visit_callable_ref(C, REF_TYPE)				\
+#define visit_callable_ref(C, REF_TYPE, EXTRA)			\
   visit_ref (pass_callable (C), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_callable, NULL)
+	     (visit_thing_fn *) &visit_callable, (EXTRA))
 
 #include "pike_macros.h"
 
diff --git a/src/gc.c b/src/gc.c
index 79531037032f1bb2d36b626e0f67823964cac620..6918c27de4aeb68de521332ce89a3da6e54cd4af 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -4436,10 +4436,10 @@ PMOD_EXPORT TYPE_T type_from_visit_fn (visit_thing_fn *fn)
 }
 
 PMOD_EXPORT TYPE_FIELD real_visit_svalues (struct svalue *s, size_t num,
-					   int ref_type)
+					   int ref_type, void *extra)
 {
   for (; num; num--, s++)
-    visit_svalue (s, ref_type);
+    visit_svalue (s, ref_type, extra);
   return 0;
 }
 
diff --git a/src/gc.h b/src/gc.h
index 41fcc991df8c66e255d98b75a68b16162a364b0e..1697503f0461f09fb441c4d210cae4ed618ba7aa 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -507,32 +507,33 @@ static INLINE int __attribute__((unused)) debug_gc_check_weak (void *a, const ch
    gc_cycle_check_svalues((S), (N)) :					\
    Pike_in_gc == GC_PASS_MARK || Pike_in_gc == GC_PASS_ZAP_WEAK ?	\
    gc_mark_svalues((S), (N)) :						\
-   (visit_svalues ((S), (N), REF_TYPE_NORMAL), 0))
+   (visit_svalues ((S), (N), REF_TYPE_NORMAL, NULL), 0))
 #define gc_recurse_short_svalue(U,T)					\
   (Pike_in_gc == GC_PASS_CYCLE ?					\
    gc_cycle_check_short_svalue((U), (T)) :				\
    Pike_in_gc == GC_PASS_MARK || Pike_in_gc == GC_PASS_ZAP_WEAK ?	\
    gc_mark_short_svalue((U), (T)) :					\
-   visit_short_svalue ((U), (T), REF_TYPE_NORMAL))
+   visit_short_svalue ((U), (T), REF_TYPE_NORMAL, NULL))
 #define gc_recurse_weak_svalues(S,N)					\
   (Pike_in_gc == GC_PASS_CYCLE ?					\
    gc_cycle_check_weak_svalues((S), (N)) :				\
    Pike_in_gc == GC_PASS_MARK || Pike_in_gc == GC_PASS_ZAP_WEAK ?	\
    gc_mark_weak_svalues((S), (N)) :					\
-   (visit_svalues ((S), (N), REF_TYPE_WEAK), 0))
+   (visit_svalues ((S), (N), REF_TYPE_WEAK, NULL), 0))
 #define gc_recurse_weak_short_svalue(U,T)				\
   (Pike_in_gc == GC_PASS_CYCLE ?					\
    gc_cycle_check_weak_short_svalue((U), (T)) :				\
    Pike_in_gc == GC_PASS_MARK || Pike_in_gc == GC_PASS_ZAP_WEAK ?	\
    gc_mark_weak_short_svalue((U), (T)) :				\
-   visit_short_svalue ((U), (T), REF_TYPE_WEAK))
+   visit_short_svalue ((U), (T), REF_TYPE_WEAK, NULL))
 
 #define GC_RECURSE_THING(V, T)						\
   (DMALLOC_TOUCH_MARKER(V, Pike_in_gc == GC_PASS_CYCLE) ?		\
    PIKE_CONCAT(gc_cycle_check_, T)(V, 0) :				\
    Pike_in_gc == GC_PASS_MARK || Pike_in_gc == GC_PASS_ZAP_WEAK ?	\
    PIKE_CONCAT3(gc_mark_, T, _as_referenced)(V) :			\
-   PIKE_CONCAT3 (visit_,T,_ref) (debug_malloc_pass (V), REF_TYPE_NORMAL))
+   PIKE_CONCAT3 (visit_,T,_ref) (debug_malloc_pass (V),			\
+				 REF_TYPE_NORMAL, NULL))
 #define gc_recurse_array(V) GC_RECURSE_THING((V), array)
 #define gc_recurse_mapping(V) GC_RECURSE_THING((V), mapping)
 #define gc_recurse_multiset(V) GC_RECURSE_THING((V), multiset)
@@ -677,49 +678,50 @@ PMOD_EXPORT extern visit_thing_fn *const visit_fn_from_type[MAX_TYPE + 1];
 PMOD_EXPORT TYPE_T type_from_visit_fn (visit_thing_fn *fn);
 
 PMOD_EXPORT TYPE_FIELD real_visit_svalues (struct svalue *s, size_t num,
-					   int ref_type);
+					   int ref_type, void *extra);
 
 static INLINE int __attribute__((unused)) real_visit_short_svalue (union anything *u, TYPE_T t,
-					   int ref_type)
+								   int ref_type, void *extra)
 {
   check_short_svalue (u, t);
   if (REFCOUNTED_TYPE(t))
-    visit_ref (u->ptr, ref_type, visit_fn_from_type[t], NULL);
+    visit_ref (u->ptr, ref_type, visit_fn_from_type[t], extra);
   return 0;
 }
-#define visit_short_svalue(U, T, REF_TYPE) \
-  (real_visit_short_svalue (debug_malloc_pass ((U)->ptr), (T), (REF_TYPE)))
+#define visit_short_svalue(U, T, REF_TYPE, EXTRA)				\
+  (real_visit_short_svalue (debug_malloc_pass ((U)->ptr), (T), (REF_TYPE), (EXTRA)))
 
 #ifdef DEBUG_MALLOC
 static INLINE TYPE_FIELD __attribute__((unused)) dmalloc_visit_svalues (struct svalue *s, size_t num,
-						int ref_type, char *l)
+									int ref_type, char *l, void *extra)
 {
-  return real_visit_svalues (dmalloc_check_svalues (s, num, l), num, ref_type);
+  return real_visit_svalues (dmalloc_check_svalues (s, num, l),
+			     num, ref_type, extra);
 }
-#define visit_svalues(S, NUM, REF_TYPE)					\
-  dmalloc_visit_svalues ((S), (NUM), (REF_TYPE), DMALLOC_LOCATION())
+#define visit_svalues(S, NUM, REF_TYPE, EXTRA)				\
+  dmalloc_visit_svalues ((S), (NUM), (REF_TYPE), (EXTRA), DMALLOC_LOCATION())
 static INLINE void __attribute__((unused)) dmalloc_visit_svalue (struct svalue *s,
-					 int ref_type, char *l)
+								 int ref_type, void *extra, char *l)
 {
   int t = TYPEOF(*s);
   check_svalue (s);
   dmalloc_check_svalue (s, l);
   if (REFCOUNTED_TYPE(t)) {
-    if (t == PIKE_T_FUNCTION) visit_function (s, ref_type);
-    else visit_ref (s->u.ptr, ref_type, visit_fn_from_type[t], NULL);
+    if (t == PIKE_T_FUNCTION) visit_function (s, ref_type, extra);
+    else visit_ref (s->u.ptr, ref_type, visit_fn_from_type[t], extra);
   }
 }
-#define visit_svalue(S, REF_TYPE) \
-  dmalloc_visit_svalue ((S), (REF_TYPE), DMALLOC_LOCATION())
+#define visit_svalue(S, REF_TYPE, EXTRA)				\
+  dmalloc_visit_svalue ((S), (REF_TYPE), (EXTRA), DMALLOC_LOCATION())
 #else
 #define visit_svalues real_visit_svalues
-static INLINE void __attribute__((unused)) visit_svalue (struct svalue *s, int ref_type)
+static INLINE void __attribute__((unused)) visit_svalue (struct svalue *s, int ref_type, void *extra)
 {
   int t = TYPEOF(*s);
   check_svalue (s);
   if (REFCOUNTED_TYPE(t)) {
-    if (t == PIKE_T_FUNCTION) visit_function (s, ref_type);
-    else visit_ref (s->u.ptr, ref_type, visit_fn_from_type[t], NULL);
+    if (t == PIKE_T_FUNCTION) visit_function (s, ref_type, extra);
+    else visit_ref (s->u.ptr, ref_type, visit_fn_from_type[t], extra);
   }
 }
 #endif
diff --git a/src/mapping.c b/src/mapping.c
index 1a5c7a790d64e66cdec34777b7a79ce20a5738bb..d8a4ec48e161e6b855ac69ae665d05959d01ddeb 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -2494,8 +2494,8 @@ static void visit_mapping_data (struct mapping_data *md, int action,
     INT32 e;
     struct keypair *k;
     NEW_MAPPING_LOOP (md) {
-      visit_svalue (&k->ind, ind_ref_type);
-      visit_svalue (&k->val, val_ref_type);
+      visit_svalue (&k->ind, ind_ref_type, extra);
+      visit_svalue (&k->val, val_ref_type, extra);
     }
   }
 }
diff --git a/src/mapping.h b/src/mapping.h
index b1574de7254e3839f26307dba29485ae0a7768d4..abec6e3f95c3d7b3314a4848670becf30757da14 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -394,9 +394,9 @@ void free_all_mapping_blocks();
 
 #define allocate_mapping(X) dmalloc_touch(struct mapping *,debug_allocate_mapping(X))
 
-#define visit_mapping_ref(M, REF_TYPE)				\
+#define visit_mapping_ref(M, REF_TYPE, EXTRA)			\
   visit_ref (pass_mapping (M), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_mapping, NULL)
+	     (visit_thing_fn *) &visit_mapping, (EXTRA))
 #define gc_cycle_check_mapping(X, WEAK) \
   gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_mapping, (X), (WEAK))
 
diff --git a/src/multiset.c b/src/multiset.c
index 8520d8df8cc720450e9601288eec41387da5a45a..abfdd86b3013edc1830cc66408231b97bd09c5ca 100644
--- a/src/multiset.c
+++ b/src/multiset.c
@@ -3512,14 +3512,14 @@ static void visit_multiset_data (struct multiset_data *msd, int action,
 	msd->flags & MULTISET_WEAK_VALUES ? REF_TYPE_WEAK : REF_TYPE_NORMAL;
       do {
 	low_use_multiset_index (node, ind);
-	visit_svalue (&ind, ind_ref_type);
-	visit_svalue (&node->iv.val, val_ref_type);
+	visit_svalue (&ind, ind_ref_type, extra);
+	visit_svalue (&node->iv.val, val_ref_type, extra);
       } while ((node = low_multiset_next (node)));
     }
     else
       do {
 	low_use_multiset_index (node, ind);
-	visit_svalue (&ind, ind_ref_type);
+	visit_svalue (&ind, ind_ref_type, extra);
       } while ((node = low_multiset_next (node)));
   }
 }
diff --git a/src/multiset.h b/src/multiset.h
index 8bc79635704b380a89872bc67ee24651c6c8e221..c6d37788aa98549ed2649bb5d0f45f428c10c6df 100644
--- a/src/multiset.h
+++ b/src/multiset.h
@@ -412,9 +412,9 @@ void real_gc_cycle_check_multiset (struct multiset *l, int weak);
 void gc_cycle_check_all_multisets (void);
 size_t gc_free_all_unreferenced_multisets (void);
 
-#define visit_multiset_ref(L, REF_TYPE)				\
+#define visit_multiset_ref(L, REF_TYPE, EXTRA)			\
   visit_ref (pass_multiset (L), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_multiset, NULL)
+	     (visit_thing_fn *) &visit_multiset, (EXTRA))
 #define gc_cycle_check_multiset(X, WEAK) \
   gc_cycle_enqueue ((gc_cycle_check_cb *) real_gc_cycle_check_multiset, (X), (WEAK))
 
diff --git a/src/object.c b/src/object.c
index 5f6b6f5477ff4a98eae39223792e7f008eb142b6..7ed36edabf3dcd4f8086f68a47b5b4dd9b115e09 100644
--- a/src/object.c
+++ b/src/object.c
@@ -2113,7 +2113,7 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
     debug_malloc_touch (o);
     debug_malloc_touch (storage);
 
-    visit_program_ref (p, REF_TYPE_NORMAL);
+    visit_program_ref (p, REF_TYPE_NORMAL, extra);
 
     for (e = p->num_inherits - 1; e >= 0; e--) {
       struct program *inh_prog = inh[e].prog;
@@ -2148,40 +2148,40 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
 	    if ((TYPEOF(*s) != T_OBJECT && TYPEOF(*s) != T_FUNCTION) ||
 		s->u.object != o ||
 		!(id_flags & IDENTIFIER_NO_THIS_REF))
-	      visit_svalue (s, REF_TYPE_NORMAL);
+	      visit_svalue (s, REF_TYPE_NORMAL, extra);
 	    break;
 	  }
 
 	  case T_ARRAY:
 	    if (u->array)
-	      visit_array_ref (u->array, REF_TYPE_NORMAL);
+	      visit_array_ref (u->array, REF_TYPE_NORMAL, extra);
 	    break;
 	  case T_MAPPING:
 	    if (u->mapping)
-	      visit_mapping_ref (u->mapping, REF_TYPE_NORMAL);
+	      visit_mapping_ref (u->mapping, REF_TYPE_NORMAL, extra);
 	    break;
 	  case T_MULTISET:
 	    if (u->multiset)
-	      visit_multiset_ref (u->multiset, REF_TYPE_NORMAL);
+	      visit_multiset_ref (u->multiset, REF_TYPE_NORMAL, extra);
 	    break;
 	  case T_PROGRAM:
 	    if (u->program)
-	      visit_program_ref (u->program, REF_TYPE_NORMAL);
+	      visit_program_ref (u->program, REF_TYPE_NORMAL, extra);
 	    break;
 
 	  case T_OBJECT:
 	    if (u->object && (u->object != o ||
 			      !(id_flags & IDENTIFIER_NO_THIS_REF)))
-	      visit_object_ref (u->object, REF_TYPE_NORMAL);
+	      visit_object_ref (u->object, REF_TYPE_NORMAL, extra);
 	    break;
 
 	  case T_STRING:
 	    if (u->string && !(action & VISIT_COMPLEX_ONLY))
-	      visit_string_ref (u->string, REF_TYPE_NORMAL);
+	      visit_string_ref (u->string, REF_TYPE_NORMAL, extra);
 	    break;
 	  case T_TYPE:
 	    if (u->type && !(action & VISIT_COMPLEX_ONLY))
-	      visit_type_ref (u->type, REF_TYPE_NORMAL);
+	      visit_type_ref (u->type, REF_TYPE_NORMAL, extra);
 	    break;
 
 #ifdef PIKE_DEBUG
@@ -2208,11 +2208,12 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
     /* Strong ref follows. It must be last. */
     if (p->flags & PROGRAM_USES_PARENT)
       if (PARENT_INFO (o)->parent)
-	visit_object_ref (PARENT_INFO (o)->parent, REF_TYPE_STRONG);
+	visit_object_ref (PARENT_INFO (o)->parent, REF_TYPE_STRONG, extra);
   }
 }
 
-PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type)
+PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type,
+				 void *extra)
 {
 #ifdef PIKE_DEBUG
   if (TYPEOF(*s) != T_FUNCTION)
@@ -2223,9 +2224,9 @@ PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type)
     /* Could avoid this if we had access to the action from the caller
      * and check if it's VISIT_COMPLEX_ONLY. However, visit_callable
      * will only return first thing. */
-    visit_callable_ref (s->u.efun, ref_type);
+    visit_callable_ref (s->u.efun, ref_type, extra);
   else
-    visit_object_ref (s->u.object, ref_type);
+    visit_object_ref (s->u.object, ref_type, extra);
 }
 
 static void gc_check_object(struct object *o);
diff --git a/src/object.h b/src/object.h
index 0498e02b881b0e56d993c93650945ba294f1b7e9..d1b100cb24f8eabb3f43a060bdaaa33e181060c4 100644
--- a/src/object.h
+++ b/src/object.h
@@ -134,7 +134,8 @@ PMOD_EXPORT struct array *object_indices(struct object *o, int inherit_level);
 PMOD_EXPORT struct array *object_values(struct object *o, int inherit_level);
 PMOD_EXPORT struct array *object_types(struct object *o, int inherit_level);
 PMOD_EXPORT void visit_object (struct object *o, int action, void *extra);
-PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type);
+PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type,
+				 void *extra);
 PMOD_EXPORT void gc_mark_object_as_referenced(struct object *o);
 PMOD_EXPORT void real_gc_cycle_check_object(struct object *o, int weak);
 unsigned gc_touch_all_objects(void);
@@ -168,9 +169,9 @@ void check_all_objects(void);
 #define master() debug_master()
 #endif
 
-#define visit_object_ref(O, REF_TYPE)				\
+#define visit_object_ref(O, REF_TYPE, EXTRA)			\
   visit_ref (pass_object (O), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_object, NULL)
+	     (visit_thing_fn *) &visit_object, (EXTRA))
 #define gc_cycle_check_object(X, WEAK) \
   gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_object, (X), (WEAK))
 
diff --git a/src/pike_types.c b/src/pike_types.c
index d881417608e6ee666e724f58e3aa982393e40d42..b1d9f90ab02be34a3d0713f95aac94bde7aa7856 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -8935,11 +8935,11 @@ PMOD_EXPORT void visit_type (struct pike_type *t, int action, void *extra)
     case T_OR:
     case T_AND:
     case PIKE_T_RING:
-      visit_type_ref (t->car, REF_TYPE_INTERNAL);
+      visit_type_ref (t->car, REF_TYPE_INTERNAL, extra);
       /* FALL_THROUGH */
     case T_SCOPE:
     case T_ASSIGN:
-      visit_type_ref (t->cdr, REF_TYPE_INTERNAL);
+      visit_type_ref (t->cdr, REF_TYPE_INTERNAL, extra);
       break;
     case T_ARRAY:
     case T_MULTISET:
@@ -8947,12 +8947,13 @@ PMOD_EXPORT void visit_type (struct pike_type *t, int action, void *extra)
     case T_TYPE:
     case T_PROGRAM:
     case T_STRING:
-      visit_type_ref (t->car, REF_TYPE_INTERNAL);
+      visit_type_ref (t->car, REF_TYPE_INTERNAL, extra);
       break;
     case PIKE_T_ATTRIBUTE:
     case PIKE_T_NAME:
-      visit_string_ref ((struct pike_string *) t->car, REF_TYPE_INTERNAL);
-      visit_type_ref (t->cdr, REF_TYPE_INTERNAL);
+      visit_string_ref ((struct pike_string *) t->car, REF_TYPE_INTERNAL,
+			extra);
+      visit_type_ref (t->cdr, REF_TYPE_INTERNAL, extra);
       break;
 #ifdef PIKE_DEBUG
     case '0':
diff --git a/src/pike_types.h b/src/pike_types.h
index 43af1c9c23567ba84258bb55a3305fb24e4d0d22..71edea4ac93820593a3e7f32117dd491b5f80731 100644
--- a/src/pike_types.h
+++ b/src/pike_types.h
@@ -316,9 +316,9 @@ void register_attribute_handler(struct pike_string *attr,
 				struct svalue *handler);
 /* Prototypes end here */
 
-#define visit_type_ref(T, REF_TYPE)				\
+#define visit_type_ref(T, REF_TYPE, EXTRA)			\
   visit_ref (pass_type (T), (REF_TYPE),				\
-	     (visit_thing_fn *) &visit_type, NULL)
+	     (visit_thing_fn *) &visit_type, (EXTRA))
 
 #ifdef DEBUG_MALLOC
 #define pop_type() ((struct pike_type *)debug_malloc_pass(debug_pop_type()))
diff --git a/src/program.c b/src/program.c
index 3c2c25b948b1241d9658e38bb5f931a0bd9d456f..d932b94dacf89dcdc209a2ab6ce51698851716f7 100644
--- a/src/program.c
+++ b/src/program.c
@@ -11048,14 +11048,14 @@ PMOD_EXPORT void visit_program (struct program *p, int action, void *extra)
     struct inherit *inh = p->inherits;
 
     for (e = p->num_constants - 1; e >= 0; e--)
-      visit_svalue (&consts[e].sval, REF_TYPE_NORMAL);
+      visit_svalue (&consts[e].sval, REF_TYPE_NORMAL, extra);
 
     for (e = p->num_inherits - 1; e >= 0; e--) {
       if (inh[e].parent)
-	visit_object_ref (inh[e].parent, REF_TYPE_NORMAL);
+	visit_object_ref (inh[e].parent, REF_TYPE_NORMAL, extra);
 
       if (e && inh[e].prog)
-	visit_program_ref (inh[e].prog, REF_TYPE_NORMAL);
+	visit_program_ref (inh[e].prog, REF_TYPE_NORMAL, extra);
     }
 
     if (!(action & VISIT_COMPLEX_ONLY)) {
@@ -11064,22 +11064,22 @@ PMOD_EXPORT void visit_program (struct program *p, int action, void *extra)
 
       for (e = p->num_inherits - 1; e >= 0; e--) {
 	if (inh[e].name)
-	  visit_string_ref (inh[e].name, REF_TYPE_NORMAL);
+	  visit_string_ref (inh[e].name, REF_TYPE_NORMAL, extra);
       }
 
       for (e = p->num_identifiers - 1; e >= 0; e--) {
 	struct identifier *id = ids + e;
-	visit_string_ref (id->name, REF_TYPE_NORMAL);
-	visit_type_ref (id->type, REF_TYPE_NORMAL);
+	visit_string_ref (id->name, REF_TYPE_NORMAL, extra);
+	visit_type_ref (id->type, REF_TYPE_NORMAL, extra);
       }
 
       for (e = p->num_strings - 1; e >= 0; e--)
-	visit_string_ref (strs[e], REF_TYPE_NORMAL);
+	visit_string_ref (strs[e], REF_TYPE_NORMAL, extra);
     }
 
     /* Strong ref follows. It must be last. */
     if (p->parent)
-      visit_program_ref (p->parent, REF_TYPE_STRONG);
+      visit_program_ref (p->parent, REF_TYPE_STRONG, extra);
   }
 }
 
diff --git a/src/program.h b/src/program.h
index d8bd48bab7196e7319a6685e29eee5f6bb4a3d57..e81c4ca8ae00f0a8204fcc51b9d1e945c6528e07 100644
--- a/src/program.h
+++ b/src/program.h
@@ -1156,9 +1156,9 @@ static INLINE int __attribute__((unused)) FIND_LFUN(struct program * p, int lfun
 
 #define start_new_program() debug_start_new_program(__LINE__,__FILE__)
 
-#define visit_program_ref(P, REF_TYPE)				\
+#define visit_program_ref(P, REF_TYPE, EXTRA)			\
   visit_ref (pass_program (P), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_program, NULL)
+	     (visit_thing_fn *) &visit_program, (EXTRA))
 #define gc_cycle_check_program(X, WEAK) \
   gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_program, (X), (WEAK))
 
diff --git a/src/stralloc.h b/src/stralloc.h
index 0c728b6b0b73c63239d585d1814a67ff1c9ff92f..b3b1843aed12eac0d5d2c0a96d126e767c4f8568 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -490,9 +490,9 @@ static INLINE int __attribute__((unused)) string_has_null( struct pike_string *x
 
 #define ISCONSTSTR(X,Y) c_compare_string((X),Y,sizeof(Y)-sizeof(""))
 
-#define visit_string_ref(S, REF_TYPE)				\
+#define visit_string_ref(S, REF_TYPE, EXTRA)			\
   visit_ref (pass_string (S), (REF_TYPE),			\
-	     (visit_thing_fn *) &visit_string, NULL)
+	     (visit_thing_fn *) &visit_string, (EXTRA))
 
 #ifdef DEBUG_MALLOC
 #define make_shared_string(X) \