diff --git a/src/Makefile.in b/src/Makefile.in
index b4af76d5ff995af137dfb9f7b4de8eaf295df826..c1839d20673dbad9f5349afa388e925d02533f2a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.84 1998/04/27 15:18:09 grubba Exp $
+# $Id: Makefile.in,v 1.85 1998/04/29 02:45:21 hubbe Exp $
 #
 
 # This line is needed on some machines.
@@ -121,6 +121,7 @@ OBJ= \
  stuff.o \
  threads.o \
  version.o \
+ queue.o \
  svalue.o @EXTRA_OBJS@
 
 #
diff --git a/src/gc.c b/src/gc.c
index c2fcd938454433bca982577a4c50770f20f3c314..056dbb1a49c839960ff08964ac838216795b5bae 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -25,7 +25,7 @@ struct callback *gc_evaluator_callback=0;
 #include "main.h"
 #include <math.h>
 
-RCSID("$Id: gc.c,v 1.36 1998/04/24 00:32:08 hubbe Exp $");
+RCSID("$Id: gc.c,v 1.37 1998/04/29 02:45:21 hubbe Exp $");
 
 /* Run garbage collect approximate every time we have
  * 20 percent of all arrays, objects and programs is
@@ -42,6 +42,7 @@ INT32 num_objects =0;
 INT32 num_allocs =0;
 INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
 static int in_gc = 0;
+struct queue gc_mark_queue;
 
 static double objects_alloced = 0.0;
 static double objects_freed = 0.0;
@@ -609,10 +610,15 @@ void do_gc(void)
 
   /* Next we mark anything with external references */
   gc_mark_all_arrays();
+  run_queue(&gc_mark_queue);
   gc_mark_all_multisets();
+  run_queue(&gc_mark_queue);
   gc_mark_all_mappings();
+  run_queue(&gc_mark_queue);
   gc_mark_all_programs();
+  run_queue(&gc_mark_queue);
   gc_mark_all_objects();
+  run_queue(&gc_mark_queue);
 
   if(d_flag)
     gc_mark_all_strings();
diff --git a/src/gc.h b/src/gc.h
index 4e72c2f0bf4ddf0906c8ca774fcb894261e5b133..4a0400fed17c42b343ed5f3a6ba35895808331c2 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -1,12 +1,14 @@
 /*
- * $Id: gc.h,v 1.17 1998/04/06 04:25:27 hubbe Exp $
+ * $Id: gc.h,v 1.18 1998/04/29 02:45:22 hubbe Exp $
  */
 #ifndef GC_H
 #define GC_H
 
 #include "global.h"
 #include "callback.h"
+#include "queue.h"
 
+extern struct queue gc_mark_queue;
 extern INT32 num_objects;
 extern INT32 num_allocs;
 extern INT32 alloc_threshold;
diff --git a/src/queue.c b/src/queue.c
new file mode 100644
index 0000000000000000000000000000000000000000..f2dc7fca66b51c5815c78a6ee81ef8b60be9626c
--- /dev/null
+++ b/src/queue.c
@@ -0,0 +1,53 @@
+#include "global.h"
+#include "pike_macros.h"
+#include "queue.h"
+
+struct queue_entry
+{
+  queue_call call;
+  void *data;
+};
+
+#define QUEUE_ENTRIES 8192
+
+struct queue_block
+{
+  struct queue_block *next;
+  int used;
+  struct queue_entry entries[QUEUE_ENTRIES];
+};
+
+void run_queue(struct queue *q)
+{
+  struct queue_block *b;
+  while((b=q->first))
+  {
+    int e;
+    for(e=0;e<b->used;e++)
+      b->entries[e].call(b->entries[e].data);
+
+    q->first=b->next;
+    free((char *)b);
+  }
+  q->last=0;
+}
+
+void enqueue(struct queue *q, queue_call call, void *data)
+{
+  struct queue_block *b=q->last;
+  if(!b || b->used >= QUEUE_ENTRIES)
+  {
+    b=ALLOC_STRUCT(queue_block);
+    b->used=0;
+    b->next=0;
+    if(q->first)
+      q->last->next=b;
+    else
+      q->first=b;
+    q->last=b;
+  }
+
+  b->entries[b->used].call=call;
+  b->entries[b->used].data=data;
+  b->used++;
+}
diff --git a/src/queue.h b/src/queue.h
new file mode 100644
index 0000000000000000000000000000000000000000..2dc43f261b6216cf28b7c3e07bc5471fc96e4b2f
--- /dev/null
+++ b/src/queue.h
@@ -0,0 +1,20 @@
+#ifndef QUEUE_H
+#define QUEUE_H
+
+struct queue;
+typedef void (*queue_call)(void *data);
+
+/* Prototypes begin here */
+struct queue_entry;
+struct queue_block;
+void run_queue(struct queue *q);
+void enqueue(struct queue *q, queue_call call, void *data);
+/* Prototypes end here */
+
+struct queue
+{
+  struct queue_block *first, *last;
+};
+
+
+#endif /* QUEUE_H */
diff --git a/src/svalue.c b/src/svalue.c
index cd18e902dd472be37cbef5eadd6efee205b1ed4a..4fe027eb39775a2ae0f4d99971c1f51c2a738317 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -19,8 +19,9 @@
 #include "gc.h"
 #include "pike_macros.h"
 #include <ctype.h>
+#include "queue.h"
 
-RCSID("$Id: svalue.c,v 1.30 1998/04/28 22:34:18 hubbe Exp $");
+RCSID("$Id: svalue.c,v 1.31 1998/04/29 02:45:22 hubbe Exp $");
 
 struct svalue dest_ob_zero = { T_INT, 0 };
 
@@ -1066,10 +1067,26 @@ void gc_mark_svalues(struct svalue *s, int num)
   {
     switch(s->type)
     {
-    case T_ARRAY:   gc_mark_array_as_referenced(s->u.array);     break;
-    case T_MULTISET:    gc_mark_multiset_as_referenced(s->u.multiset);       break;
-    case T_MAPPING: gc_mark_mapping_as_referenced(s->u.mapping); break;
-    case T_PROGRAM: gc_mark_program_as_referenced(s->u.program); break;
+    case T_ARRAY: 
+      enqueue(&gc_mark_queue,
+	      (queue_call)gc_mark_array_as_referenced,
+	      s->u.array);
+      break;
+    case T_MULTISET:
+      enqueue(&gc_mark_queue,
+	      (queue_call)gc_mark_multiset_as_referenced,
+	      s->u.multiset);
+      break;
+    case T_MAPPING:
+      enqueue(&gc_mark_queue,
+	      (queue_call)gc_mark_mapping_as_referenced,
+	      s->u.mapping);
+      break;
+    case T_PROGRAM:
+      enqueue(&gc_mark_queue,
+	      (queue_call)gc_mark_program_as_referenced,
+	      s->u.program);
+      break;
 
     case T_FUNCTION:
       if(s->subtype == FUNCTION_BUILTIN) break;
@@ -1077,7 +1094,9 @@ void gc_mark_svalues(struct svalue *s, int num)
     case T_OBJECT:
       if(s->u.object->prog)
       {
-	gc_mark_object_as_referenced(s->u.object);
+	enqueue(&gc_mark_queue,
+		(queue_call)gc_mark_object_as_referenced,
+		s->u.object);
       }else{
 	free_svalue(s);
 	s->type=T_INT;