diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 80b96aac1be9381bcd90e4ce9385cd6a14e0d1c1..985735cf8d62adfb6a623e4fa23c4bb61d5be745 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -5,27 +5,9 @@ inherit "/precompiled/regexp";
 
 string current_file, current_mode;
 
-static int open(string file, string how)
-{
-  if(file == current_file && how == current_mode)
-  {
-    seek(0);
-    return 1;
-  }else{
-    if(file::open(file,how))
-    {
-      current_file=file;
-      current_mode=how;
-      return 1;
-    }else{
-      current_file=current_mode=0;
-      return 0;
-    }
-  }
-}
-
 string read_bytes(string filename,void|int start,void|int len)
 {
+  string ret;
   if(!open(filename,"r"))
     error("Couldn't open file "+filename+".\n");
   
@@ -37,16 +19,20 @@ string read_bytes(string filename,void|int start,void|int len)
   case 3:
     seek(start);
   }
-  return read(len);
+  ret=read(len);
+  close();
+  return ret;
 }
 
 int write_file(string filename,string what)
 {
-  if(!open(filename,"wc"))
+  int ret;
+  if(!open(filename,"awc"))
     error("Couldn't open file "+filename+".\n");
   
-  seek(-1);
-  return write(what);
+  ret=write(what);
+  close();
+  return ret;
 }
 
 mixed *map_array(mixed *arr, mixed fun, mixed ... args)
diff --git a/src/ChangeLog b/src/ChangeLog
index 482ff040beb73e8387f8c986bdf12320640a4cb9..6e349ca19ee5eba384af994294b872508e647867 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Sat Feb 24 04:12:52 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* program.c, array.c, object.c, gc.c: 
+	  Added routines to remove cyclic structures.
+
 Sat Feb 17 23:05:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* sprintf: added support for %2c
diff --git a/src/Makefile.in b/src/Makefile.in
index aae59ad77d578911ee4266c27ff0d923a354a939..fbfd057af6a905fd05479c34eee0d9c5e3d2bed8 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -72,7 +72,7 @@ OBJ=language.o add_efun.o array.o builtin_efuns.o backend.o \
     fsort.o hashtable.o interpret.o lex.o las.o list.o \
     lpc_types.o main.o mapping.o memory.o module.o object.o \
     opcodes.o operators.o port.o program.o rusage.o stralloc.o \
-    stuff.o svalue.o debug.o callback.o lpc_signal.o @EXTRA_OBJS@
+    stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@
 
 #
 MODULES=@subdirs@
@@ -145,11 +145,11 @@ TAGS:
 verify_manual:
 	$(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR)
 
-verify:
+verify: $(SRCDIR)/test/testsuite
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite
 
 # verify / debug verbose
-verbose_verify:
+verbose_verify: $(SRCDIR)/test/testsuite
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose
 
 # verify & debug VERBOSE
@@ -214,250 +214,423 @@ $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 language.o: language.c global.h machine.h \
-  config.h debug.h \
-  port.h interpret.h \
-  program.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h object.h \
-  stralloc.h lex.h \
-  lpc_types.h add_efun.h \
-  hashtable.h macros.h \
-  error.h docode.h
-add_efun.o: add_efun.c add_efun.h \
-  svalue.h types.h machine.h \
-  hashtable.h las.h \
-  config.h dynamic_buffer.h \
-  program.h macros.h \
-  memory.h lpc_types.h \
-  stralloc.h interpret.h
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  object.h \
+  stralloc.h \
+  lex.h \
+  lpc_types.h \
+  add_efun.h \
+  hashtable.h \
+  macros.h \
+  error.h \
+  docode.h
+add_efun.o: add_efun.c \
+  add_efun.h \
+  svalue.h \
+  types.h machine.h \
+  hashtable.h \
+  las.h \
+  config.h \
+  dynamic_buffer.h \
+  program.h \
+  macros.h \
+  memory.h \
+  lpc_types.h \
+  stralloc.h \
+  interpret.h
 alloca.o: alloca.c
-array.o: array.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
+array.o: array.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
   array.h las.h \
-  dynamic_buffer.h program.h \
-  object.h stralloc.h \
-  interpret.h language.h error.h \
-  lpc_types.h fsort.h \
-  builtin_efuns.h
-backend.o: backend.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h object.h \
-  svalue.h error.h \
-  call_out.h backend.h \
-  fd_control.h main.h \
-  callback.h array.h \
-  las.h dynamic_buffer.h
+  dynamic_buffer.h \
+  program.h \
+  object.h \
+  stralloc.h \
+  interpret.h language.h \
+  error.h \
+  lpc_types.h \
+  fsort.h \
+  builtin_efuns.h \
+  gc.h
 builtin_efuns.o: builtin_efuns.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  interpret.h program.h \
-  svalue.h macros.h \
-  object.h array.h \
-  las.h dynamic_buffer.h \
-  error.h add_efun.h \
-  hashtable.h mapping.h \
-  stralloc.h lex.h \
-  list.h lpc_types.h \
-  rusage.h operators.h \
-  fsort.h call_out.h \
-  callback.h
-call_out.o: call_out.c global.h \
-  machine.h config.h debug.h \
-  port.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  call_out.h object.h \
-  interpret.h error.h \
-  builtin_efuns.h main.h
-callback.o: callback.c macros.h \
-  memory.h types.h machine.h \
-  callback.h array.h \
-  las.h config.h \
-  svalue.h dynamic_buffer.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
+  macros.h \
+  object.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  error.h \
+  add_efun.h \
+  hashtable.h \
+  mapping.h \
+  stralloc.h \
+  lex.h list.h \
+  lpc_types.h \
+  rusage.h \
+  operators.h \
+  fsort.h \
+  call_out.h \
+  callback.h \
+  gc.h
+call_out.o: call_out.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  call_out.h \
+  object.h \
+  interpret.h \
+  error.h \
+  builtin_efuns.h \
+  main.h
+callback.o: callback.c \
+  macros.h \
+  memory.h \
+  types.h machine.h \
+  callback.h \
+  array.h las.h \
+  config.h \
+  svalue.h \
+  dynamic_buffer.h \
   program.h
-debug.o: debug.c global.h \
-  machine.h config.h debug.h \
-  port.h
-docode.o: docode.c global.h \
-  machine.h config.h debug.h \
+docode.o: docode.c \
+  global.h machine.h \
+  config.h \
   port.h las.h \
-  svalue.h dynamic_buffer.h \
+  svalue.h \
+  dynamic_buffer.h \
   program.h language.h \
-  lpc_types.h stralloc.h \
-  interpret.h add_efun.h \
-  hashtable.h array.h \
-  macros.h error.h \
+  lpc_types.h \
+  stralloc.h \
+  interpret.h \
+  add_efun.h \
+  hashtable.h \
+  array.h \
+  macros.h \
+  error.h \
   main.h lex.h \
   builtin_efuns.h
 dynamic_buffer.o: dynamic_buffer.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  dynamic_buffer.h stralloc.h \
-  error.h svalue.h
-error.o: error.c global.h \
-  machine.h config.h debug.h \
-  port.h macros.h \
-  error.h svalue.h \
-  interpret.h program.h \
-  stralloc.h builtin_efuns.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  dynamic_buffer.h \
+  stralloc.h \
+  error.h \
+  svalue.h
+error.o: error.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  macros.h \
+  error.h \
+  svalue.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  builtin_efuns.h \
   array.h las.h \
-  dynamic_buffer.h object.h
+  dynamic_buffer.h \
+  object.h
 fd_control.o: fd_control.c \
-  fd_control.h global.h \
-  machine.h config.h debug.h \
+  fd_control.h \
+  global.h machine.h \
+  config.h \
   port.h
-fsort.o: fsort.c global.h \
-  machine.h config.h debug.h \
-  port.h fsort.h
-hashtable.o: hashtable.c global.h \
-  machine.h config.h debug.h \
-  port.h hashtable.h \
-  stralloc.h stuff.h \
-  error.h svalue.h
-interpret.o: interpret.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h object.h \
-  svalue.h array.h \
-  las.h dynamic_buffer.h \
-  mapping.h error.h language.h \
-  stralloc.h add_efun.h \
-  hashtable.h macros.h \
-  list.h backend.h \
-  operators.h opcodes.h \
+fsort.o: fsort.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  fsort.h
+gc.o: gc.c \
+  global.h machine.h \
+  config.h \
+  port.h gc.h \
+  main.h
+hashtable.o: hashtable.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  hashtable.h \
+  stralloc.h \
+  stuff.h \
+  error.h \
+  svalue.h
+interpret.o: interpret.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  object.h \
+  svalue.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  mapping.h \
+  error.h language.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  macros.h \
+  list.h \
+  backend.h \
+  operators.h \
+  opcodes.h \
   main.h lex.h \
-  builtin_efuns.h lpc_signal.h
-las.o: las.c global.h machine.h \
-  config.h debug.h \
-  port.h language.h interpret.h \
-  program.h las.h \
-  svalue.h dynamic_buffer.h \
-  array.h object.h \
-  stralloc.h lex.h \
-  lpc_types.h add_efun.h \
-  hashtable.h mapping.h \
-  list.h error.h \
-  docode.h main.h
-lex.o: lex.c global.h machine.h \
-  config.h debug.h \
-  port.h language.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  lex.h stralloc.h \
-  add_efun.h hashtable.h \
-  stuff.h interpret.h \
-  error.h object.h \
-  operators.h opcodes.h \
-  builtin_efuns.h macros.h
-list.o: list.c global.h \
-  machine.h config.h debug.h \
-  port.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  list.h macros.h \
-  error.h interpret.h \
+  builtin_efuns.h \
+  lpc_signal.h
+las.o: las.c \
+  global.h machine.h \
+  config.h \
+  port.h language.h \
+  interpret.h \
+  program.h \
+  las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  array.h \
+  object.h \
+  stralloc.h \
+  lex.h \
+  lpc_types.h \
+  add_efun.h \
+  hashtable.h \
+  mapping.h \
+  list.h \
+  error.h \
+  docode.h \
+  main.h
+lex.o: lex.c \
+  global.h machine.h \
+  config.h \
+  port.h language.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  lex.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  stuff.h \
+  interpret.h \
+  error.h \
+  object.h \
+  operators.h \
+  opcodes.h \
+  builtin_efuns.h \
+  macros.h
+list.o: list.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  list.h \
+  macros.h \
+  error.h \
+  interpret.h \
   builtin_efuns.h
 lpc_signal.o: lpc_signal.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  svalue.h interpret.h \
-  program.h stralloc.h \
-  add_efun.h hashtable.h \
-  las.h dynamic_buffer.h \
-  macros.h backend.h
-lpc_types.o: lpc_types.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
-  lpc_types.h stralloc.h \
-  stuff.h array.h \
-  las.h dynamic_buffer.h \
-  program.h add_efun.h \
-  hashtable.h object.h \
-  list.h mapping.h \
-  macros.h error.h
-main.o: main.c global.h \
-  machine.h config.h debug.h \
-  port.h backend.h \
-  module.h object.h \
-  svalue.h lex.h \
-  lpc_types.h builtin_efuns.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  las.h \
+  dynamic_buffer.h \
+  macros.h \
+  backend.h
+lpc_types.o: lpc_types.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  lpc_types.h \
+  stralloc.h \
+  stuff.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  program.h \
+  add_efun.h \
+  hashtable.h \
+  object.h \
+  list.h \
+  mapping.h \
+  macros.h \
+  error.h
+main.o: main.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  backend.h \
+  module.h \
+  object.h \
+  svalue.h \
+  lex.h \
+  lpc_types.h \
+  builtin_efuns.h \
   array.h las.h \
-  dynamic_buffer.h program.h \
-  stralloc.h interpret.h \
-  error.h macros.h \
-  callback.h lpc_signal.h
-mapping.o: mapping.c global.h \
-  machine.h config.h debug.h \
-  port.h mapping.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  array.h macros.h language.h \
-  error.h interpret.h
-memory.o: memory.c global.h \
-  machine.h config.h debug.h \
-  port.h error.h \
+  dynamic_buffer.h \
+  program.h \
+  stralloc.h \
+  interpret.h \
+  error.h \
+  macros.h \
+  callback.h \
+  lpc_signal.h
+mapping.o: mapping.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  mapping.h \
+  las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  array.h \
+  macros.h language.h \
+  error.h \
+  interpret.h
+memory.o: memory.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  error.h \
   svalue.h
-module.o: module.c module.h \
-  types.h machine.h macros.h \
-  memory.h error.h \
+module.o: module.c \
+  module.h \
+  types.h machine.h \
+  macros.h \
+  memory.h \
+  error.h \
   svalue.h modlist.h
-object.o: object.c global.h \
-  machine.h config.h debug.h \
-  port.h object.h \
-  svalue.h dynamic_buffer.h \
-  interpret.h program.h \
-  stralloc.h macros.h \
-  error.h main.h
-opcodes.o: opcodes.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h svalue.h \
+object.o: object.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  object.h \
+  svalue.h \
+  dynamic_buffer.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  macros.h \
+  error.h \
+  main.h \
+  array.h las.h \
+  gc.h
+opcodes.o: opcodes.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
   array.h las.h \
-  dynamic_buffer.h stralloc.h \
-  mapping.h list.h \
-  opcodes.h object.h \
-  error.h lpc_types.h
-operators.o: operators.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h svalue.h \
+  dynamic_buffer.h \
+  stralloc.h \
+  mapping.h \
+  list.h \
+  opcodes.h \
+  object.h \
+  error.h \
+  lpc_types.h
+operators.o: operators.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
   list.h las.h \
-  dynamic_buffer.h mapping.h \
-  array.h stralloc.h \
-  opcodes.h operators.h \
-  language.h error.h
-port.o: port.c global.h \
-  machine.h config.h debug.h \
-  port.h macros.h
-program.o: program.c global.h \
-  machine.h config.h debug.h \
-  port.h program.h \
-  object.h svalue.h \
-  dynamic_buffer.h lpc_types.h \
-  stralloc.h las.h language.h \
-  lex.h macros.h \
-  fsort.h error.h \
-  docode.h interpret.h \
-  hashtable.h compilation.h
-rusage.o: rusage.c global.h \
-  machine.h config.h debug.h \
-  port.h rusage.h
-stralloc.o: stralloc.c global.h \
-  machine.h config.h debug.h \
-  port.h stralloc.h \
-  macros.h dynamic_buffer.h \
-  error.h svalue.h
-stuff.o: stuff.c stuff.h \
+  dynamic_buffer.h \
+  mapping.h \
+  array.h \
+  stralloc.h \
+  opcodes.h \
+  operators.h language.h \
+  error.h \
+  docode.h \
+  add_efun.h \
+  hashtable.h
+port.o: port.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  macros.h
+program.o: program.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  program.h \
+  object.h \
+  svalue.h \
+  dynamic_buffer.h \
+  lpc_types.h \
+  stralloc.h \
+  las.h language.h \
+  lex.h \
+  macros.h \
+  fsort.h \
+  error.h \
+  docode.h \
+  interpret.h \
+  hashtable.h \
+  main.h gc.h \
+  compilation.h
+rusage.o: rusage.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  rusage.h
+stralloc.o: stralloc.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  stralloc.h \
+  macros.h \
+  dynamic_buffer.h \
+  error.h \
+  svalue.h
+stuff.o: stuff.c \
+  stuff.h \
   types.h machine.h
-svalue.o: svalue.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
-  stralloc.h array.h \
-  las.h dynamic_buffer.h \
-  program.h mapping.h \
-  list.h object.h \
-  add_efun.h hashtable.h \
+svalue.o: svalue.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  stralloc.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  program.h \
+  mapping.h \
+  list.h \
+  object.h \
+  add_efun.h \
+  hashtable.h \
   error.h
 ualarm.o: ualarm.c
diff --git a/src/array.c b/src/array.c
index e2e2a865926220e948c692a0f625123ef08cc6ac..2697bdeb8bc8d560ba06877f1b4ac0cf474f0fe7 100644
--- a/src/array.c
+++ b/src/array.c
@@ -16,6 +16,7 @@
 #include "fsort.h"
 #include "builtin_efuns.h"
 #include "memory.h"
+#include "gc.h"
 
 struct array empty_array=
 {
@@ -46,10 +47,13 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
     return &empty_array;
   }
 
+  GC_ALLOC();
+
   v=(struct array *)malloc(sizeof(struct array)+
 			   (size+extra_space-1)*sizeof(struct svalue));
   if(!v)
     error("Couldn't allocate array, out of memory.\n");
+  
 
   /* for now, we don't know what will go in here */
   v->type_field=BIT_MIXED;
@@ -94,6 +98,8 @@ static void array_free_no_free(struct array *v)
   v->next->prev=prev;
 
   free((char *)v);
+
+  GC_FREE();
 }
 
 /*
@@ -1245,138 +1251,111 @@ void array_replace(struct array *a,
   while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);
 }
 
-#ifdef GC
-
-void array_gc_clear_mark()
-{
-  struct array *a;
-  a=&empty_array;
-  do
-  {
-    a->flags &=~ ARRAY_FLAG_MARK;
-    check_array(a, pass);
-
-    a=a->next;
-
 #ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
-  } while (a != & empty_array);
-}
-
-void array_gc_mark(struct array *a)
+void check_array(struct array *a)
 {
   INT32 e;
-  if(a->flags & ARRAY_FLAG_MARK) return;
-  a->flags |= ARRAY_FLAG_MARK;
 
-  if(!(a->type_field & ~(BIT_STRING|BIT_INT|BIT_FLOAT)))
-    return 0;
+  if(a->next->prev != a)
+    fatal("Array check: a->next->prev != a\n");
 
-  for(e=0;e<a->size;e++) svalue_gc_sweep(ITEM(a) + e);
-}
+  if(a->size > a->malloced_size)
+    fatal("Array is larger than malloced block!\n");
 
-void array_gc_sweep()
-{
-  struct array *a, *next;
+  if(a->refs <=0 )
+    fatal("Array has zero refs.\n");
 
-  a=&empty_array;
-  do
+  for(e=0;e<a->size;e++)
   {
-    a->refs++;
-
-    if(!(a->flags & ARRAY_FLAG_MARK))
-    {
-      free_svalues(ITEM(a), a->size, a->type_field);
-      a->size=0; /* Don't free them again */
-    }
+    if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
+      fatal("Type field lies.\n");
     
-    next=a->next;
-    free_array(a);
-
-    a=next;
-#ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
-  } while (a != & empty_array);
+    check_svalue(ITEM(a)+e);
+  }
 }
 
-
-#ifdef DEBUG
-void array_gc_sweep2()
+void check_all_arrays()
 {
   struct array *a;
-  if(!d_flag) return;
 
   a=&empty_array;
   do
   {
-    if(!(a->flags & ARRAY_FLAG_MARK))
-      fatal("Array ref count incorrect!\n");
+    check_array(a);
 
-    a=a->next
-    
-#ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
+    a=a->next;
+    if(!a)
+      fatal("Null pointer in array list.\n");
   } while (a != & empty_array);
 }
 #endif /* DEBUG */
-#endif /* GC */
 
+#ifdef GC2
 
-#ifdef DEBUG
-void check_array(struct array *a, int pass)
+void gc_check_array(struct array *a)
 {
-  INT32 e;
-  if(pass)
-  {
-    e=checked((void *)a,0);
-    if(e!=a->refs)
-    {
-      simple_describe_array(a);
-      fatal("Above array has wrong number of references. (%ld != %ld)\n",
-	    (long)e,(long)a->refs);
-    }
-    return;
-  }
-
-  if(a->next->prev != a)
-    fatal("Array check: a->next->prev != a\n");
+  if(a == gc_ptr) gc_refs++;
+  if(a->flags & GC_MARK) return;
+  a->flags |= GC_MARK;
+  if(!(a->type_field & BIT_COMPLEX)) return;
+  gc_check_svalues(ITEM(a), a->size);
+}
 
-  if(a->size > a->malloced_size)
-    fatal("Array is larger than malloced block!\n");
 
-  if(a->refs <=0 )
-    fatal("Array has zero refs.\n");
+void gc_check_all_arrays()
+{
+  struct array *a,*n;
 
-  for(e=0;e<a->size;e++)
+  a=&empty_array;
+  do
   {
-    if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
-      fatal("Type field lies.\n");
-    
-    check_svalue(ITEM(a)+e);
-  }
+    if(!(a->flags & GC_MARK) && a->type_field & BIT_COMPLEX)
+    {
+      gc_ptr=a;
+      gc_refs=0;
+      
+      gc_check_array(a);
+      
+      a->refs++;
+      
+      if(gc_refs == a->refs)
+      {
+	/* This structure contains as many references to itself as
+	 * it has referenes, which means that it is circular and
+	 * should be destroyed, so please go away.
+	 */
+	
+	free_svalues(ITEM(a), a->size, a->type_field);
+	
+	a->size=0;
+	
+      }
+      
+      if(!(n=a->next))
+	fatal("Null pointer in array list.\n");
+      
+      free_array(a);
+      a=n;
+    }else{
+      a=a->next;
+    }
+  } while (a != & empty_array);
 }
 
-void check_all_arrays(int pass)
+void gc_clear_array_marks()
 {
   struct array *a;
 
   a=&empty_array;
   do
   {
-    check_array(a, pass);
-
+    a->flags &=~ GC_MARK;
     a=a->next;
-    if(!a)
-      fatal("Null pointer in array list.\n");
-  } while (a != & empty_array);
 
-  if(!pass)
-  {
-    checked((void *)&empty_array,1);
-  }
+  } while (a != & empty_array);
 }
-#endif /* DEBUG */
+
+
+
+#endif /* GC2 */
 
diff --git a/src/array.h b/src/array.h
index 34f74e4baab7cf09d2c0d5b3040ada29ed436c57..758fc6cbad1414fcfdfc21b02845b52f7785b53f 100644
--- a/src/array.h
+++ b/src/array.h
@@ -117,12 +117,11 @@ struct array *reverse_array(struct array *a);
 void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to);
-void array_gc_clear_mark();
-void array_gc_mark(struct array *a);
-void array_gc_sweep();
-void array_gc_sweep2();
-void check_array(struct array *a, int pass);
-void check_all_arrays(int pass);
+void check_array(struct array *a);
+void check_all_arrays();
+void gc_check_array(struct array *a);
+void gc_check_all_arrays();
+void gc_clear_array_marks();
 /* Prototypes end here */
 
 
diff --git a/src/backend.c b/src/backend.c
index f3a47a4d036a83a35dc66af00932052a742e9260..f8cb88b7af848a66a7b8b5d1198ac9e9db9182ef 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -157,40 +157,22 @@ void *query_write_callback_data(int fd)
 }
 
 #ifdef DEBUG
-void do_debug(int check_refs)
+void do_debug()
 {
-  extern void check_all_arrays(int);
-  extern void check_all_mappings(int);
-  extern void check_all_programs(int);
-  extern void check_all_objects(int);
-  extern void verify_shared_strings_tables(int);
-  extern void slow_check_stack(int);
-
-#if 0
-  if(d_flag>1)
-    init_checked();
-#endif
-
-  slow_check_stack(0);
-  check_all_arrays(0);
-  check_all_mappings(0);
-  check_all_programs(0);
-  verify_all_objects(0);
-  verify_shared_strings_tables(0);
+  extern void check_all_arrays();
+  extern void check_all_mappings();
+  extern void check_all_programs();
+  extern void check_all_objects();
+  extern void verify_shared_strings_tables();
+  extern void slow_check_stack();
+
+  slow_check_stack();
+  check_all_arrays();
+  check_all_mappings();
+  check_all_programs();
+  verify_all_objects();
+  verify_shared_strings_tables();
   verify_all_call_outs();
-
-#if 0
-  if(d_flag>1)
-  {
-    check_all_arrays(1);
-    check_all_mappings(1);
-    check_all_programs(1);
-    verify_all_objects(1);
-    verify_shared_strings_tables(1);
-    exit_checked();
-  }
-#endif
-
 }
 #endif
 
@@ -263,7 +245,7 @@ void backend()
     alloca(0);			/* Do garbage collect */
 #ifdef DEBUG
     if(d_flag > 1)
-      do_debug(1);
+      do_debug();
 #endif
   }
 
diff --git a/src/backend.h b/src/backend.h
index b69daeb74c97fd73537675309b3be5025a47a36e..a80179d81ded3e5fa637bd3e33cf340952b1caf1 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -26,7 +26,7 @@ callback query_read_callback(int fd);
 callback query_write_callback(int fd);
 void *query_read_callback_data(int fd);
 void *query_write_callback_data(int fd);
-void do_debug(int check_refs);
+void do_debug();
 void backend();
 int write_to_stderr(char *a, INT32 len);
 /* Prototypes end here */
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index aa094a6853eb609b693ce2cdb0eb4256d8416039..e5428f0b44296f36c6769636ba5a864fd5e8d0f1 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -22,6 +22,7 @@
 #include "fsort.h"
 #include "call_out.h"
 #include "callback.h"
+#include "gc.h"
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
@@ -1210,6 +1211,15 @@ void f_sleep(INT32 args)
   }
 }
 
+void f_gc(INT32 args)
+{
+  INT32 tmp;
+  pop_n_elems(args);
+  tmp=num_objects;
+  do_gc();
+  push_int(tmp - num_objects);
+}
+
 #ifdef TYPEP
 #undef TYPEP
 #endif
@@ -1296,6 +1306,7 @@ void init_builtin_efuns()
   add_efun("upper_case",f_upper_case,"function(string:string)",0);
   add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
   add_efun("zero_type",f_zero_type,"function(int:int)",0);
+  add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
 }
 
 
diff --git a/src/call_out.c b/src/call_out.c
index cfda6cc07156adb29adeea114c9278f04eadf418..f596c0ce30e2b410ce7e759c883d70d1bf968bcb 100644
--- a/src/call_out.c
+++ b/src/call_out.c
@@ -308,12 +308,6 @@ time_t get_next_call_out()
 #ifdef DEBUG
 void verify_all_call_outs()
 {
-  int e;
   verify_call_outs();
-  for(e=0;e<num_pending_calls;e++)
-  {
-    checked((void *)pending_calls[e]->caller,1);
-    checked((void *)pending_calls[e]->args,1);
-  }
 }
 #endif
diff --git a/src/config.h b/src/config.h
index fcb99f4b9ab47993a6e74af777c87fbae55d8762..d905a755de9f2ddb1e75645488916210c2703b45 100644
--- a/src/config.h
+++ b/src/config.h
@@ -32,6 +32,11 @@
  * Define the size of the cache that is used for method lookup.
  */
 #define FIND_FUNCTION_HASHSIZE 4711
+
+/*
+ * Undefine this to disable garabge collection
+ */
+#define GC2
    
 
 /*
diff --git a/src/debug.c b/src/debug.c
deleted file mode 100644
index c11c55f0825eb9abfbd59a0f65b3a2d6595c0dff..0000000000000000000000000000000000000000
--- a/src/debug.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#include "global.h"
-#include "types.h"
-#include "memory.h"
-
-#define MARKER_CHUNK_SIZE 4096
-#define REHASH_LIMIT 16
-#define REHASH_FORMULA(X) ((X)*4-1)
-
-struct marker
-{
-  struct marker *next;
-  void *marked;
-  INT32 refs;
-};
-
-struct marker_chunk
-{
-  struct marker_chunk *next;
-  struct marker markers[MARKER_CHUNK_SIZE];
-};
-
-static struct marker_chunk *chunk=0;
-static int markers_left_in_chunk=0;
-
-static struct marker *new_marker()
-{
-  if(!markers_left_in_chunk)
-  {
-    struct marker_chunk *m;
-    m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk));
-    m->next=chunk;
-    chunk=m;
-    markers_left_in_chunk=MARKER_CHUNK_SIZE;
-  }
-  markers_left_in_chunk--;
-
-  return chunk->markers + markers_left_in_chunk;
-}
-
-static struct marker **hash=0;
-static int hashsize=0;
-static int hashed=0;
-
-INT32 checked(void *a,INT32 delta)
-{
-  int hashval;
-  struct marker *m;
-
-  if(!hash) return 0;
-
-  hashval=((long)a)%hashsize;
-
-  for(m=hash[hashval];m;m=m->next)
-  {
-    if(m->marked == a)
-    {
-      m->refs+=delta;
-      return m->refs;
-    }
-  }
-  if(!delta) return 0;
-
-  m=new_marker();
-  m->marked=a;
-  m->next=hash[hashval];
-  m->refs=delta;
-  hash[hashval]=m;
-
-  hashed++;
-  if(hashed / REHASH_LIMIT > hashsize)
-  {
-    struct marker **new_hash,*next;
-    int new_hashsize;
-    int e;
-
-    new_hashsize=REHASH_FORMULA(hashsize);
-    new_hash=(struct marker **)xalloc(sizeof(struct marker **)*new_hashsize);
-    memset((char *)new_hash,0,sizeof(struct marker **)*new_hashsize);
-
-    for(e=0;e<hashsize;e++)
-    {
-      for(m=hash[e];m;m=next)
-      {
-	next=m->next;
-	m->next=new_hash[((long)m->marked)%new_hashsize];
-	new_hash[((long)m->marked)%new_hashsize]=m;
-      }
-    }
-
-    free((char *)hash);
-    hash=new_hash;
-    hashsize=new_hashsize;
-  }
-
-  return m->refs;
-}
-
-void init_checked()
-{
-  /* init hash*/
-  hashsize=4711;
-  hashed=0;
-  hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize);
-  memset((char *)hash,0,sizeof(struct marker **)*hashsize);
-  markers_left_in_chunk=0;
-}
-
-void exit_checked()
-{
-  struct marker_chunk *m;
-
-  if(!hash) return;
-  free((char *)hash);
-  while(m=chunk)
-  {
-    chunk=m->next;
-    free((char *)m);
-  }
-  hash=0;
-}
diff --git a/src/debug.h b/src/debug.h
deleted file mode 100644
index 7e482708e773dec0d9c3dcfb7199bc07720e458c..0000000000000000000000000000000000000000
--- a/src/debug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include "types.h"
-
-/* Prototypes begin here */
-struct marker;
-struct marker_chunk;
-INT32 checked(void *a,INT32 delta);
-void init_checked();
-void exit_checked();
-/* Prototypes end here */
-
-#endif
diff --git a/src/global.h b/src/global.h
index 7eca62d6c8978880663061fcac16e0c861e35d8a..e8be108dbfb013f052ecdfa7cb0e1f2a9ff22dc5 100644
--- a/src/global.h
+++ b/src/global.h
@@ -66,10 +66,6 @@ char *alloca ();
 #include <memory.h>
 #endif
 
-#ifdef DEBUG
-#include "debug.h"
-#endif
-
 #if defined(__GNUC__) && !defined(DEBUG) && !defined(lint)
 #define INLINE inline
 #else
diff --git a/src/mapping.c b/src/mapping.c
index de252f7fbf13fcd8e2f357c117a8e1b32491eade..b23d2bdff5355ca6e7f97728164d7932547e0f35 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -411,15 +411,8 @@ void mapping_search_no_free(struct svalue *to,
 
 #ifdef DEBUG
 
-void check_mapping(struct mapping *m,int pass)
+void check_mapping(struct mapping *m)
 {
-  if(pass)
-  {
-    if(checked((void *)m,0) != m->refs)
-      fatal("Mapping has wrong number of refs.\n");
-    return;
-  }
-
   if(m->refs <=0)
     fatal("Mapping has zero refs.\n");
 
@@ -434,17 +427,12 @@ void check_mapping(struct mapping *m,int pass)
     if(first_mapping != m)
       fatal("Mapping ->prev == 0 but first_mapping != mapping.\n");
   }
-  checked((void *)m->ind,1);
-  checked((void *)m->val,1);
 }
 
-void check_all_mappings(int pass)
+void check_all_mappings()
 {
   struct mapping *m;
   for(m=first_mapping;m;m=m->next)
-    check_mapping(m,pass);
-
-  if(!pass)
-    checked((void *)first_mapping,1);
+    check_mapping(m);
 }
 #endif
diff --git a/src/mapping.h b/src/mapping.h
index 9a9132cb14296fa3db368201d0111f2edc5c11a0..8eb88ae8732822dc959257a27dc4e08e5ad00f81 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -53,5 +53,7 @@ void mapping_search_no_free(struct svalue *to,
 			    struct mapping *m,
 			    struct svalue *look_for,
 			    struct svalue *start);
+void check_mapping(struct mapping *m);
+void check_all_mappings();
 /* Prototypes end here */
 #endif
diff --git a/src/modules/efuns.c b/src/modules/efuns.c
deleted file mode 100644
index 16fb213bb3fa33a6f19458de6c7b7e9e7c7f814a..0000000000000000000000000000000000000000
--- a/src/modules/efuns.c
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* function *get_function_list(object); */
-void f_get_function_list(int num_arg,struct svalue *argp)
-{
-  int e;
-  int funs;
-  struct program *p;
-  struct vector *v;
-  struct object *o;
-  o=argp[0].u.ob;
-
-  p=o->prog;
-  for(funs=e=0;e<p->num_funindex;e++)
-    if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC))
-      funs++;
-
-  v=allocate_array_no_init(funs,0);
-  funs=0;
-
-  for(e=0;e<p->num_funindex;e++)
-  {
-    if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC))
-    {
-      v->item[funs].type=T_FUNCTION;
-      v->item[funs].u.ob=o;
-      v->item[funs].subtype=e;
-      add_ref(o,"get_function_list");
-      funs++;
-    }
-  }
-  v->types=BIT_FUNCTION;
-  free_svalue(argp);
-  argp->type=T_ARRAY;
-  argp->u.vec=v;
-}
-
-/* int function_args(function); */
-void f_function_args(int num_arg,struct svalue *argp)
-{
-  int i;
-  i=FUNC(argp[0].u.ob->prog,argp[0].subtype)->num_arg;
-  free_svalue(argp);
-  argp->type=T_INT;
-  argp->subtype=0;
-  argp->u.number=i;
-}
-
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
index cee0d455844eda7ca83bcf4f1dcf078221572501..9df921c43f36eb6af0039d6e75dbbe9ab6380ed7 100644
--- a/src/modules/files/Makefile.in
+++ b/src/modules/files/Makefile.in
@@ -21,9 +21,9 @@ depend:
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 datagram.o: datagram.c
 efuns.o: efuns.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -34,11 +34,12 @@ efuns.o: efuns.c \
   dynamic_buffer.h \
   mapping.h \
   macros.h \
-  fd_control.h file_machine.h
+  fd_control.h \
+  file_machine.h
 file.o: file.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -50,14 +51,14 @@ file.o: file.c \
   object.h \
   macros.h \
   backend.h \
-  fd_control.h file_machine.h \
-  file.h \
+  fd_control.h \
+  file_machine.h file.h \
   error.h \
   lpc_signal.h
 socket.o: socket.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -69,5 +70,5 @@ socket.o: socket.c \
   object.h \
   macros.h \
   backend.h \
-  fd_control.h file_machine.h \
-  file.h
+  fd_control.h \
+  file_machine.h file.h
diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in
index d2bc317acdf146b93a18476bacd5a5f1251b2549..f3a73a2b6c6d5c7c4d7447decdb242937568fbd2 100644
--- a/src/modules/regexp/Makefile.in
+++ b/src/modules/regexp/Makefile.in
@@ -19,9 +19,9 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 glue.o: glue.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -33,9 +33,9 @@ glue.o: glue.c \
   object.h \
   macros.h
 regexp.o: regexp.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   regexp.h \
   error.h \
diff --git a/src/modules/sprintf/Makefile.in b/src/modules/sprintf/Makefile.in
index 5ace6c5549a2de0443099b1cb62997cd78c6f1c0..56de303c762dc620fa81cd15bda65ef166dd9264 100644
--- a/src/modules/sprintf/Makefile.in
+++ b/src/modules/sprintf/Makefile.in
@@ -19,9 +19,9 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 sprintf.o: sprintf.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   error.h \
   svalue.h \
diff --git a/src/object.c b/src/object.c
index 7f24245964e1a7433b7b1d44722f924b510ffe0e..9d6e0ff0876f9a54d9937de3d1cb016c4baa737b 100644
--- a/src/object.c
+++ b/src/object.c
@@ -15,6 +15,7 @@
 #include "error.h"
 #include "main.h"
 #include "array.h"
+#include "gc.h"
 
 struct object *master_object = 0;
 struct object *first_object;
@@ -34,6 +35,8 @@ struct object *clone(struct program *p, int args)
   struct object *o;
   struct frame frame;
 
+  GC_ALLOC();
+
   o=(struct object *)xalloc(sizeof(struct object)-1+p->storage_needed);
 
   o->prog=p;
@@ -231,6 +234,8 @@ void really_free_object(struct object *o)
   if(o->next) o->next->prev=o->prev;
   
   free((char *)o);
+
+  GC_FREE();
 }
 
 void object_index_no_free(struct svalue *to,
@@ -463,22 +468,13 @@ union anything *object_get_item_ptr(struct object *o,
 }
 
 #ifdef DEBUG
-void verify_all_objects(int pass)
+void verify_all_objects()
 {
   struct object *o;
   struct frame frame;
 
   for(o=first_object;o;o=o->next)
   {
-    if(pass)
-    {
-      if(checked((void *)o, 0) != o->refs)
-      {
-	fatal("Object has wrong number of refs.\n");
-      }
-      continue;
-    }
-
     if(o->next && o->next->prev !=o)
       fatal("Object check: o->next->prev != o\n");
 
@@ -537,9 +533,6 @@ void verify_all_objects(int pass)
 	frame.context=o->prog->inherits[e];
 	frame.context.prog->refs++;
 	frame.current_storage=o->storage+frame.context.storage_offset;
-
-	if(frame.context.prog->checkrefs)
-	  frame.context.prog->checkrefs(frame.current_storage,o,pass);
       }
 
       free_object(frame.current_object);
@@ -647,19 +640,14 @@ struct array *object_values(struct object *o)
   return a;
 }
 
-#ifdef GC
-void object_gc_clear_mark()
-{
-  struct object *o;
-  for(o=first_object;o;o=o->next)
-    o->flags &=~ OBJECT_FLAG_MARK;
-}
+#ifdef GC2
 
-void object_gc_mark(struct object *o)
+void gc_check_object(struct object *o)
 {
   INT32 e;
-  if(o->flags & OBJECT_FLAG_MARK) return;
-  a->flags |= OBJECT_FLAG_MARK;
+  if(o == gc_ptr) gc_refs++;
+  if(o->flags & GC_MARK) return;
+  o->flags |= GC_MARK;
 
   if(!o->prog) return;
 
@@ -673,36 +661,41 @@ void object_gc_mark(struct object *o)
 
     if(i->run_time_type == T_MIXED)
     {
-      svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i));
+      gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
     }else{
-      short_svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i),
+      gc_check_short_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i),
 			    i->run_time_type);
     }
   }
 }
 
-void object_gc_sweep()
+void gc_check_all_objects()
 {
   struct object *o, *next;
   for(o=first_object;o;o=next)
   {
-    o->refs++;
-    if(!(o->flags & OBJECT_FLAG_MARK)) destruct(o);
-    next=o->next;
-    free_object(o);
+    if(!(o->flags & GC_MARK))
+    {
+      gc_ptr=o;
+      gc_refs=0;
+      
+      o->refs++;
+      
+      if(gc_refs == o->refs) destruct(o);
+      
+      next=o->next;
+      free_object(o);
+    }else{
+      next=o->next;
+    }
   }
 }
 
-#ifdef DEBUG
-void object_gc_sweep2()
+void gc_clear_object_marks()
 {
   struct object *o;
-  if(!d_flag) return;
 
-
-  for(o=first_object;o;o=o->next)
-    if(!(o->flags & OBJECT_FLAG_MARK)) 
-      fatal("Object ref count incorrect.\n");
+  for(o=first_object;o;o=o->next) o->flags &=~ GC_MARK;
 }
-#endif /* DEBUG */
-#endif /* GC */
+
+#endif /* GC2 */
diff --git a/src/object.h b/src/object.h
index 8d67f15dd0a0a6d6bf484205a6b9c839978002dc..32608e56ed1024f3e9f0caa00ee2d7c8b3802238 100644
--- a/src/object.h
+++ b/src/object.h
@@ -14,7 +14,9 @@
 struct object
 {
   INT32 refs;                    /* Reference count, must be first. */
+#ifdef GC2
   INT16 flags;
+#endif
   struct program *prog;
   struct object *next;
   struct object *prev;
@@ -55,11 +57,14 @@ union anything *object_low_get_item_ptr(struct object *o,
 union anything *object_get_item_ptr(struct object *o,
 				    struct svalue *index,
 				    TYPE_T type);
-void verify_all_objects(int pass);
+void verify_all_objects();
 int object_equal_p(struct object *a, struct object *b, struct processing *p);
 void cleanup_objects();
 struct array *object_indices(struct object *o);
 struct array *object_values(struct object *o);
+void gc_check_object(struct object *o);
+void gc_check_all_objects();
+void gc_clear_object_marks();
 /* Prototypes end here */
 
 #endif /* OBJECT_H */
diff --git a/src/program.c b/src/program.c
index 274f1e34a344ad1012fb2877674ea7e24a54480f..85de0f4f961d7ac359d02faba3b4d28f4c29ceba 100644
--- a/src/program.c
+++ b/src/program.c
@@ -19,6 +19,7 @@
 #include "interpret.h"
 #include "hashtable.h"
 #include "main.h"
+#include "gc.h"
 #include <stdio.h>
 #include <fcntl.h>
 
@@ -156,6 +157,8 @@ void really_free_program(struct program *p)
     p->next->prev=p->prev;
 
   free((char *)p);
+
+  GC_FREE();
 }
 
 #ifdef DEBUG
@@ -214,19 +217,11 @@ void toss_current_program()
 }
 
 #ifdef DEBUG
-void check_program(struct program *p, int pass)
+void check_program(struct program *p)
 {
   INT32 size,e;
   unsigned INT32 checksum;
 
-  if(pass)
-  {
-    if(checked((void *)p,0) != p->refs)
-      fatal("Program has wrong number of references.\n");
-
-    return;
-  }
-
   if(p->refs <=0)
     fatal("Program has zero refs.\n");
 
@@ -333,10 +328,7 @@ void check_program(struct program *p, int pass)
   {
     if(p->inherits[e].storage_offset < 0)
       fatal("Inherit->storage_offset is wrong.\n");
-
-    checked((void *)p->inherits[e].prog,1);
   }
-  checked((void *)p,-1); /* One too many were added above */
 }
 #endif
 
@@ -466,7 +458,7 @@ struct program *end_program()
     first_program=prog;
 
 #ifdef DEBUG
-    check_program(prog,0);
+    check_program(prog);
     if(l_flag)
       dump_program_desc(prog);
 #endif
@@ -1190,12 +1182,15 @@ struct program *compile_file(struct lpc_string *file_name)
 {
   int fd;
   struct program *p;
-  
+
   fd=open(file_name->str,O_RDONLY);
   if(fd < 0)
     error("Couldn't open file '%s'.\n",file_name->str);
 
 
+  GC_ALLOC();
+  
+
 #define FILE_STATE
 #define PUSH
 #include "compilation.h"
@@ -1226,6 +1221,8 @@ struct program *compile_string(struct lpc_string *prog,
 #include "compilation.h"
 #undef PUSH
 
+  GC_ALLOC();
+
   start_new_string(prog->str,prog->len,name);
   start_new_program();
   compile();
@@ -1281,23 +1278,11 @@ void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
 }
 
 #ifdef DEBUG
-void check_all_programs(int pass)
+void check_all_programs()
 {
   struct program *p;
   for(p=first_program;p;p=p->next)
-    check_program(p,pass);
-
-#ifdef FIND_FUNCTION_HASHSIZE
-  if(!pass)
-  {
-    int e;
-    for(e=0;e<FIND_FUNCTION_HASHSIZE;e++)
-    {
-      if(cache[e].name)
-	checked((void *)cache[e].name,1);
-    }
-  }
-#endif
+    check_program(p);
 }
 #endif
 
@@ -1315,3 +1300,47 @@ void cleanup_program()
   }
 #endif
 }
+
+#ifdef GC2
+
+void gc_check_program(struct program *p)
+{
+  if(p==gc_ptr) gc_refs++;
+  if(p->flags & GC_MARK) return;
+  p->flags |= GC_MARK;
+  gc_check_svalues(p->constants, p->num_constants);
+}
+
+void gc_check_all_programs()
+{
+  struct program *p, *next;
+  for(p=first_program;p;p=next)
+  {
+    if(!(p->flags & GC_MARK))
+    {
+      gc_ptr=p;
+      gc_refs=0;
+
+      gc_check_program(p);
+      
+      p->refs++;
+      
+      if(gc_refs == p->refs)
+	free_svalues(p->constants, p->num_constants, -1);
+      
+      next=p->next;
+      free_program(p);
+    }else{
+      next=p->next;
+    }
+  }
+}
+
+void gc_clear_program_marks()
+{
+  struct program *p;
+
+  for(p=first_program;p;p=p->next) p->flags &=~ GC_MARK;
+}
+
+#endif /* GC2 */
diff --git a/src/program.h b/src/program.h
index 0204f525483e6c88de5ca4bee9f2cc9e00a432d0..fe1c265aab35c35d732104281544b06c8e80ae27 100644
--- a/src/program.h
+++ b/src/program.h
@@ -111,7 +111,6 @@ struct program
   void (*init)(char *,struct object *);
   void (*exit)(char *,struct object *);
 #ifdef DEBUG
-  void (*checkrefs)(char *,struct object *,int pass);
   unsigned INT32 checksum;
 #endif
 
@@ -145,7 +144,7 @@ void start_new_program();
 void really_free_program(struct program *p);
 void dump_program_desc(struct program *p);
 void toss_current_program();
-void check_program(struct program *p, int pass);
+void check_program(struct program *p);
 struct program *end_program();
 SIZE_T add_storage(SIZE_T size);
 void set_init_callback(void (*init)(char *,struct object *));
@@ -181,8 +180,11 @@ struct program *compile_string(struct lpc_string *prog,
 			       struct lpc_string *name);
 struct program *end_c_program(char *name);
 void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
-void check_all_programs(int pass);
+void check_all_programs();
 void cleanup_program();
+void gc_check_program(struct program *p);
+void gc_check_all_programs();
+void gc_clear_program_marks();
 /* Prototypes end here */
 
 
diff --git a/src/stralloc.c b/src/stralloc.c
index c915693f90adc7e411e0686b517ec94177569e99..8c3d1317c5df0d1302e72159c702f1eeea999775 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -30,11 +30,9 @@ void check_string(struct lpc_string *s)
 
   if(s->str[s->len])
     fatal("Shared string is not zero terminated properly.\n");
-
-  checked((void *)s,1);
 }
 
-void verify_shared_strings_tables(int pass)
+void verify_shared_strings_tables()
 {
   unsigned int e, h;
   struct lpc_string *s;
@@ -44,14 +42,6 @@ void verify_shared_strings_tables(int pass)
     h=0;
     for(s=base_table[e];s;s=s->next)
     {
-      if(pass)
-      {
-	if(checked((void *)s,0)!=s->refs)
-	{
-	  fatal("Shared string has wrong number of refs '%s'.\n",s->str);
-	}
-	continue;
-      }
       h++;
       if(s->len < 0)
 	fatal("Shared string shorter than zero bytes.\n");
diff --git a/src/stralloc.h b/src/stralloc.h
index a2b626193549de54786fd04373525047918d3481..7da0aa5e98cc17ba27c85d4df92a3c3ff2a4d8bc 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -33,7 +33,7 @@ struct lpc_string *debug_findstring(const struct lpc_string *foo);
 
 /* Prototypes begin here */
 void check_string(struct lpc_string *s);
-void verify_shared_strings_tables(int pass);
+void verify_shared_strings_tables();
 struct lpc_string *findstring(const char *foo);
 struct lpc_string *debug_findstring(const struct lpc_string *foo);
 struct lpc_string *begin_shared_string(int len);
diff --git a/src/svalue.c b/src/svalue.c
index 04af973f0bdce8b8cadba257d3cf1bca207aa318..612ab00302229ed296953c159a555c9ca85971f7 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -639,11 +639,6 @@ void check_short_svalue(union anything *u,TYPE_T type)
   check_refs2(u,type);
   if(!u->refs) return;
 
-  if(type <= MAX_REF_TYPE)
-  {
-    checked((void *) u->refs,1);
-  }
-
   switch(type)
   {
   case T_STRING:
@@ -660,3 +655,56 @@ void check_svalue(struct svalue *s)
 }
 
 #endif
+
+#ifdef GC2
+void gc_check_svalues(struct svalue *s, int num)
+{
+  INT32 e;
+  for(e=0;e<num;e++,s++)
+  {
+    switch(s->type)
+    {
+    case T_ARRAY: gc_check_array(s->u.array); break;
+    case T_LIST:
+      gc_check_array(s->u.list->ind);
+      break;
+    case T_MAPPING:
+      gc_check_array(s->u.mapping->ind);
+      gc_check_array(s->u.mapping->val);
+      break;
+    case T_OBJECT:
+      if(s->u.object->prog)
+      {
+	gc_check_object(s->u.object);
+      }else{
+	free_svalue(s);
+      }
+      break;
+    case T_PROGRAM: gc_check_program(s->u.program); break;
+    }
+  }
+}
+
+void gc_check_short_svalue(union anything *u, TYPE_T type)
+{
+  if(!u->refs) return;
+  switch(type)
+  {
+  case T_ARRAY: gc_check_array(u->array); break;
+  case T_LIST: gc_check_array(u->list->ind); break;
+  case T_MAPPING:
+    gc_check_array(u->mapping->ind);
+    gc_check_array(u->mapping->val);
+    break;
+  case T_OBJECT:
+    if(u->object->prog)
+    {
+      gc_check_object(u->object);
+    }else{
+      free_short_svalue(u,T_OBJECT);
+    }
+    break;
+  case T_PROGRAM: gc_check_program(u->program); break;
+  }
+}
+#endif /* GC2 */
diff --git a/src/svalue.h b/src/svalue.h
index 09780754785a7177ba860bb5120eb47ffc4e3751..9e536ff2f14ca6db4848639f5ff48241ef7cb008 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -75,6 +75,9 @@ struct svalue
 
 #define BIT_NOTHING 0
 #define BIT_MIXED 0xffff
+#define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING)
+#define BIT_COMPLEX (BIT_ARRAY|BIT_LIST|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING)
+
 /* Max type with ref count */
 #define MAX_REF_TYPE T_STRING
 /* Max type handled by svalue primitives */
diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 18261c1d2398a49ea3c04d93563212685b15ce6c..5dbe7f6a33dbbce2e2a82fc073575b6c101739a7 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -63,6 +63,8 @@ test_compile([[while(0)if(0)continue;else;]])
 test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
 test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
+test_true(intp(gc()));
+test_any([[ gc(); array a=({0}); a[0]=a; a=0; return gc() > 0; ]],1);
 
 test_eq("\377"[0],255)
 test_do(add_efun("foo",clone(class {int i;})))