diff --git a/src/array.c b/src/array.c
index 1b16bd19da7095569a30fe3e0d54115af33dbb0f..733e183a8fd0eab603fface55b05bdb20b7efb03 100644
--- a/src/array.c
+++ b/src/array.c
@@ -23,7 +23,7 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: array.c,v 1.86 2000/09/08 16:19:42 grubba Exp $");
+RCSID("$Id: array.c,v 1.87 2000/09/14 19:58:43 mast Exp $");
 
 PMOD_EXPORT struct array empty_array=
 {
@@ -103,7 +103,7 @@ static void array_free_no_free(struct array *v)
 
   free((char *)v);
 
-  GC_FREE();
+  GC_FREE(v);
 }
 
 /*
diff --git a/src/gc.h b/src/gc.h
index e16bc238ba485744a2c9982be4a77517e79134fd..6bb08272452df600a613f3902c0f5310e2568f50 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -1,5 +1,5 @@
 /*
- * $Id: gc.h,v 1.64 2000/09/03 23:09:38 mast Exp $
+ * $Id: gc.h,v 1.65 2000/09/14 19:58:43 mast Exp $
  */
 #ifndef GC_H
 #define GC_H
@@ -49,15 +49,27 @@ extern void *gc_svalue_location;
 } while(0)
 #endif
 
-#define GC_FREE() do {							\
-  DO_IF_DEBUG(								\
-    extern int d_flag;							\
-    if(d_flag) CHECK_INTERPRETER_LOCK();				\
+#ifdef PIKE_DEBUG
+#define GC_FREE_BLOCK(PTR) do {						\
+  extern int d_flag;							\
+  if(d_flag) CHECK_INTERPRETER_LOCK();					\
+  if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_ZAP_WEAK) {	\
     if(Pike_in_gc == GC_PASS_CHECK)					\
       fatal("Freeing objects in this gc pass is not allowed.\n");	\
+    else								\
+      remove_marker(PTR);						\
+  }									\
+} while (0)
+#else
+#define GC_FREE_BLOCK(PTR) do {} while (0)
+#endif
+
+#define GC_FREE(PTR) do {						\
+  GC_FREE_BLOCK(PTR);							\
+  DO_IF_DEBUG(								\
     if(num_objects < 1)							\
       fatal("Panic!! less than zero objects!\n");			\
-  )									\
+  );									\
   num_objects-- ;							\
 }while(0)
 
diff --git a/src/mapping.c b/src/mapping.c
index f10d28817ae8006baa64e1a1a854d48e18f3d42c..d0fa83f5995a6734fae3c442bca47cc10aa498a4 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.104 2000/09/14 15:23:41 mast Exp $");
+RCSID("$Id: mapping.c,v 1.105 2000/09/14 19:58:43 mast Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -67,7 +67,7 @@ DO_IF_DEBUG(								\
   }									\
   DOUBLEUNLINK(first_mapping, m);					\
 									\
-  GC_FREE();
+  GC_FREE(m);
 
 
 #undef COUNT_OTHER
@@ -199,9 +199,6 @@ PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md)
   debug_malloc_touch(md);
 
 #ifdef PIKE_DEBUG
-  if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_ZAP_WEAK)
-    fatal("Can't free a mapping_data inside gc.\n");
-
   if (md->refs) {
     fatal("really_free_mapping_data(): md has non-zero refs: %d\n",
 	  md->refs);
@@ -215,6 +212,7 @@ PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md)
   }
 
   free((char *) md);
+  GC_FREE_BLOCK(md);
 }
 
 PMOD_EXPORT void do_free_mapping(struct mapping *m)
@@ -311,9 +309,6 @@ static struct mapping *rehash(struct mapping *m, int new_size)
   if(md->refs <=0)
     fatal("Zero refs in mapping->data\n");
 
-  if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_ZAP_WEAK)
-    fatal("Can't rehash a mapping inside gc.\n");
-
   if(d_flag>1)  check_mapping(m);
 #endif
 
@@ -336,6 +331,7 @@ static struct mapping *rehash(struct mapping *m, int new_size)
       mapping_rehash_backwards_evil(new_md, md->hash[e]);
 
     free((char *)md);
+    GC_FREE_BLOCK(md);
   }
 
 #ifdef PIKE_DEBUG
diff --git a/src/multiset.c b/src/multiset.c
index 63ff5260247b61533111d5c9daec4ee98a338218..d916baa318c26057f62d735798773567b896784a 100644
--- a/src/multiset.c
+++ b/src/multiset.c
@@ -17,7 +17,7 @@
 #include "gc.h"
 #include "security.h"
 
-RCSID("$Id: multiset.c,v 1.27 2000/08/23 18:53:47 grubba Exp $");
+RCSID("$Id: multiset.c,v 1.28 2000/09/14 19:58:43 mast Exp $");
 
 struct multiset *first_multiset;
 
@@ -68,7 +68,7 @@ PMOD_EXPORT void really_free_multiset(struct multiset *l)
   DOUBLEUNLINK(first_multiset, l);
 
   free((char *)l);
-  GC_FREE();
+  GC_FREE(l);
 }
 
 PMOD_EXPORT void do_free_multiset(struct multiset *l)
diff --git a/src/object.c b/src/object.c
index 05d52d8c6ea17f7b6db2c3ee41456b9737a8ad6e..91d78a11d705599eee38451d701cffcdac3dee2b 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.147 2000/09/11 18:50:17 grubba Exp $");
+RCSID("$Id: object.c,v 1.148 2000/09/14 19:58:43 mast Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -743,7 +743,7 @@ PMOD_EXPORT void schedule_really_free_object(struct object *o)
       /* It's a fake object which isn't counted by the gc, so
        * counteract the num_objects-- done by GC_FREE. */
       num_objects++;
-    GC_FREE();
+    GC_FREE(o);
 
     FREE_PROT(o);
 
diff --git a/src/program.c b/src/program.c
index 9d3a0578e23c6d7cd934cab80dadb4368217d4c7..6977f09c86206854b0ae2860d8fe7458988ea2e5 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.271 2000/09/05 20:24:42 grubba Exp $");
+RCSID("$Id: program.c,v 1.272 2000/09/14 19:58:44 mast Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -970,7 +970,7 @@ PMOD_EXPORT void really_free_program(struct program *p)
   FREE_PROT(p);
   dmfree((char *)p);
 
-  GC_FREE();
+  GC_FREE(p);
 }
 
 #ifdef PIKE_DEBUG
diff --git a/src/stralloc.c b/src/stralloc.c
index f9511d706a6e0cbbb6d36a6de139eaff66c78dce..e41e056c082201572e6e200f3b3c4825518ae245 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -25,7 +25,7 @@
 #define HUGE HUGE_VAL
 #endif /*!HUGE*/
 
-RCSID("$Id: stralloc.c,v 1.99 2000/09/03 23:20:12 mast Exp $");
+RCSID("$Id: stralloc.c,v 1.100 2000/09/14 19:58:44 mast Exp $");
 
 #define BEGIN_HASH_SIZE 997
 #define MAX_AVG_LINK_LENGTH 3
@@ -742,6 +742,7 @@ PMOD_EXPORT void really_free_string(struct pike_string *s)
 #endif
   unlink_pike_string(s);
   debug_free((char *)s,DMALLOC_LOCATION(),1);
+  GC_FREE_BLOCK(s);
 }
 
 PMOD_EXPORT void debug_free_string(struct pike_string *s)