diff --git a/src/array.c b/src/array.c
index ac765f289be3d465e5559cb0fbf072ffd365de20..a0c89e02e52907b93ab50088916a368c0b117bcb 100644
--- a/src/array.c
+++ b/src/array.c
@@ -2743,7 +2743,7 @@ void check_all_arrays(void)
 PMOD_EXPORT void visit_array (struct array *a, int action, void *extra)
 {
   visit_enter(a, T_ARRAY, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
@@ -2757,7 +2757,8 @@ PMOD_EXPORT void visit_array (struct array *a, int action, void *extra)
       break;
   }
 
-  if (a->type_field &
+  if (!(action & VISIT_NO_REFS) &&
+      a->type_field &
       (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES)) {
     size_t e, s = a->size;
     int ref_type = a->flags & ARRAY_WEAK_FLAG ? REF_TYPE_WEAK : REF_TYPE_NORMAL;
diff --git a/src/constants.c b/src/constants.c
index d09ed922df74acb1701b4b9a081c00e8f1c6375f..70da82324457beddd5130b22e4c822dd3be8e42f 100644
--- a/src/constants.c
+++ b/src/constants.c
@@ -197,7 +197,7 @@ PMOD_EXPORT void quick_add_efun(const char *name, ptrdiff_t name_length,
 PMOD_EXPORT void visit_callable (struct callable *c, int action, void *extra)
 {
   visit_enter(c, T_STRUCT_CALLABLE, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
diff --git a/src/gc.c b/src/gc.c
index c1db83d65d4368b4a7fd309cf758bfbf52747396..40103f81027835c9a99e67f3563f327532c6f10a 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -5750,6 +5750,10 @@ void f_count_memory (INT32 args)
       if (mc_ref_from->flags & MC_FLAG_INTERNAL) {
 	action = VISIT_COUNT_BYTES; /* Memory count this. */
 	MC_DEBUG_MSG (NULL, "enter with byte counting");
+	if (mc_lookahead < 0) {
+	  MC_DEBUG_MSG (NULL, "VISIT_NO_REFS mode");
+	  action |= VISIT_NO_REFS;
+	}
 
 	mc_ref_from->visit_fn (mc_ref_from->thing, action, mc_ref_from->extra);
 	count_visits++;
diff --git a/src/gc.h b/src/gc.h
index 70baabfd74e09007a3d8a2e68cd423f501a22684..2e3ef562b1c23b7831e27473433dbcd5129d2944 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -683,6 +683,16 @@ PMOD_EXPORT extern visit_leave_cb *visit_leave;
  * mc_counted_bytes, then visit the refs. Never combined with
  * VISIT_COMPLEX_ONLY. */
 
+#define VISIT_MODE_MASK 0x0F
+/* Bitmask for visit mode selection. The rest is flags. */
+
+#define VISIT_NO_REFS 0x10
+/* Don't visit any refs. Typically set when lookahead is negative as
+   an optimization. */
+
+#define VISIT_FLAGS_MASK 0xF0
+/* Bitmask for visit flags. */
+
 /* Map between type and visit function for the standard ref types. */
 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);
diff --git a/src/mapping.c b/src/mapping.c
index 5126ba9c39bfb1e1d877074161dcff24874761e9..f8b1dcb40bc7dd66435104fa19869fc563a8b4e8 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -2528,7 +2528,7 @@ static void visit_mapping_data (struct mapping_data *md, int action,
 				void *extra)
 {
   visit_enter(md, T_MAPPING_DATA, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
@@ -2541,7 +2541,8 @@ static void visit_mapping_data (struct mapping_data *md, int action,
       break;
   }
 
-  if ((md->ind_types | md->val_types) &
+  if (!(action & VISIT_NO_REFS) &&
+      (md->ind_types | md->val_types) &
       (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES)) {
     int ind_ref_type =
       md->flags & MAPPING_WEAK_INDICES ? REF_TYPE_WEAK : REF_TYPE_NORMAL;
@@ -2560,7 +2561,7 @@ static void visit_mapping_data (struct mapping_data *md, int action,
 PMOD_EXPORT void visit_mapping (struct mapping *m, int action, void *extra)
 {
   visit_enter(m, T_MAPPING, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
diff --git a/src/multiset.c b/src/multiset.c
index 5ac958851f920f630b44c101daf32f1a9c34c6e7..02a5c8a345b5f1de1b1a0e5c6f6c149bddd4ad55 100644
--- a/src/multiset.c
+++ b/src/multiset.c
@@ -3472,7 +3472,7 @@ static void visit_multiset_data (struct multiset_data *msd, int action,
 				 void *extra)
 {
   visit_enter(msd, T_MULTISET_DATA, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
@@ -3487,7 +3487,8 @@ static void visit_multiset_data (struct multiset_data *msd, int action,
       break;
   }
 
-  if (msd->root &&
+  if (!(action & VISIT_NO_REFS) &&
+      msd->root &&
       ((msd->ind_types | msd->val_types) &
        (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES))) {
     int ind_ref_type =
@@ -3515,7 +3516,7 @@ static void visit_multiset_data (struct multiset_data *msd, int action,
 PMOD_EXPORT void visit_multiset (struct multiset *l, int action, void *extra)
 {
   visit_enter(l, T_MULTISET, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
diff --git a/src/object.c b/src/object.c
index 0c486cfb7580e607f15ad20b174a9c86223c50cc..98e9f6ce33c08855f083bf5f0e2460f30a6efa92 100644
--- a/src/object.c
+++ b/src/object.c
@@ -2105,7 +2105,7 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
   if (o->next == o) return; /* Fake object used by compiler */
 
   visit_enter(o, T_OBJECT, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
@@ -2133,31 +2133,32 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
 
     for (e = p->num_inherits - 1; e >= 0; e--) {
       struct program *inh_prog = inh[e].prog;
-      unsigned INT16 *inh_prog_var_idxs = inh_prog->variable_index;
-      struct identifier *inh_prog_ids = inh_prog->identifiers;
-      char *inh_storage = storage + inh[e].storage_offset;
-
-      int q, num_vars = (int) inh_prog->num_variable_index;
-
-      for (q = 0; q < num_vars; q++) {
-	int d = inh_prog_var_idxs[q];
-	struct identifier *id = inh_prog_ids + d;
-	int id_flags = id->identifier_flags;
-	int rtt = id->run_time_type;
-	void *var;
-	union anything *u;
+      if (!(action & VISIT_NO_REFS)) {
+	unsigned INT16 *inh_prog_var_idxs = inh_prog->variable_index;
+	struct identifier *inh_prog_ids = inh_prog->identifiers;
+	char *inh_storage = storage + inh[e].storage_offset;
+
+	int q, num_vars = (int) inh_prog->num_variable_index;
 
-	if (IDENTIFIER_IS_ALIAS (id_flags))
-	  continue;
+	for (q = 0; q < num_vars; q++) {
+	  int d = inh_prog_var_idxs[q];
+	  struct identifier *id = inh_prog_ids + d;
+	  int id_flags = id->identifier_flags;
+	  int rtt = id->run_time_type;
+	  void *var;
+	  union anything *u;
 
-	var = inh_storage + id->func.offset;
-	u = (union anything *) var;
+	  if (IDENTIFIER_IS_ALIAS (id_flags))
+	    continue;
+
+	  var = inh_storage + id->func.offset;
+	  u = (union anything *) var;
 #ifdef DEBUG_MALLOC
-	if (REFCOUNTED_TYPE(rtt))
-	  debug_malloc_touch (u->ptr);
+	  if (REFCOUNTED_TYPE(rtt))
+	    debug_malloc_touch (u->ptr);
 #endif
 
-	switch (rtt) {
+	  switch (rtt) {
 	  case T_MIXED: {
 	    struct svalue *s = (struct svalue *) var;
 	    dmalloc_touch_svalue (s);
@@ -2209,6 +2210,7 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra)
 	  default:
 	    Pike_fatal ("Invalid runtime type %d.\n", rtt);
 #endif
+	  }
 	}
       }
 
diff --git a/src/pike_types.c b/src/pike_types.c
index ed6fad4e1952475f4a8713641466e77258f74ce9..6185092f7e04d7378c5f06190f96e0762864bee4 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -8956,7 +8956,7 @@ PMOD_EXPORT void *find_type(struct pike_type *t,
 PMOD_EXPORT void visit_type (struct pike_type *t, int action, void *extra)
 {
   visit_enter(t, PIKE_T_TYPE, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
diff --git a/src/program.c b/src/program.c
index 5a829319498e96310d39e2e22aa4a7ef4d97021f..6c57a87661509adb8bc9846b8d5ba325b7e3f06f 100644
--- a/src/program.c
+++ b/src/program.c
@@ -11042,7 +11042,7 @@ void cleanup_program(void)
 PMOD_EXPORT void visit_program (struct program *p, int action, void *extra)
 {
   visit_enter(p, T_PROGRAM, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);
diff --git a/src/stralloc.c b/src/stralloc.c
index db28194f1ca293ca9d845c6fc733d504a60dc077..f22bd94e9b011683e448815a0d4112a5d852eb7c 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -2242,7 +2242,7 @@ void count_memory_in_strings(size_t *num, size_t *size)
 PMOD_EXPORT void visit_string (struct pike_string *s, int action, void *extra)
 {
   visit_enter(s, T_STRING, extra);
-  switch (action) {
+  switch (action & VISIT_MODE_MASK) {
 #ifdef PIKE_DEBUG
     default:
       Pike_fatal ("Unknown visit action %d.\n", action);