diff --git a/src/Makefile.in b/src/Makefile.in
index 62ed0a8cd1307a252a1b0b5b92f6096b549f54b3..c6beadbcd07f1034522cb1c500d7141d4c7b6f9c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.193 2000/05/25 02:18:35 hubbe Exp $
+# $Id: Makefile.in,v 1.194 2000/06/23 06:17:58 hubbe Exp $
 #
 
 # This line is needed on some machines.
@@ -386,7 +386,7 @@ gdb_verify: module_testsuites testsuite master.pike
 	@echo >>.gdbinit handle SIGUSR2 nostop noprint pass
 	@echo >>.gdbinit handle SIGLWP nostop noprint pass
 	@echo >>.gdbinit break debug_fatal
-	@echo >>.gdbinit run -m$(TMP_BUILDDIR)/master.pike $(PIKEOPTS) $(TMP_BINDIR)/test_pike.pike --no-watchdog -v -v -f $(TESTARGS)
+	@echo >>.gdbinit run -m$(TMP_BUILDDIR)/master.pike $(PIKEOPTS) $(TMP_BINDIR)/test_pike.pike --no-watchdog -v -v $(TESTARGS)
 	gdb ./pike
 	@rm .gdbinit
 
diff --git a/src/main.c b/src/main.c
index d30865eb7ada6cc56006991b167dcc2fa746030d..389defd13a7fd82eb4f82634522c5e5e159c2778 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: main.c,v 1.90 2000/05/20 02:22:20 per Exp $");
+RCSID("$Id: main.c,v 1.91 2000/06/23 06:17:58 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -587,6 +587,7 @@ void low_exit_main(void)
   void cleanup_compiler(void);
   void cleanup_backend(void);
   void free_all_mapping_blocks(void);
+  void free_all_object_blocks(void);
 
 #ifdef AUTO_BIGNUM
   void exit_auto_bignum(void);
@@ -709,6 +710,7 @@ void low_exit_main(void)
   exit_destroy_called_mark_hash();
 
   free_all_mapping_blocks();
+  free_all_object_blocks();
   first_mapping=0;
 #endif
 }
diff --git a/src/object.c b/src/object.c
index 0bd7491f530f29a6e316b13b192f267f0149afd6..fb5dfcb12a73e689bead56f2981708bd50bdedbf 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.125 2000/06/17 00:25:20 hubbe Exp $");
+RCSID("$Id: object.c,v 1.126 2000/06/23 06:17:58 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -75,6 +75,20 @@ struct object *first_object;
 struct object *gc_internal_object = 0;
 static struct object *gc_mark_object_pos = 0;
 
+#undef COUNT_OTHER
+
+#define COUNT_OTHER() do{			\
+  struct object *o;                             \
+  for(o=first_object;o;o=o->next)		\
+    if(o->prog)					\
+      size+=o->prog->storage_needed;		\
+						\
+  for(o=objects_to_destruct;o;o=o->next)	\
+    if(o->prog)					\
+      size+=o->prog->storage_needed;		\
+}while(0)
+BLOCK_ALLOC(object, 511)
+
 struct object *low_clone(struct program *p)
 {
   int e;
@@ -87,7 +101,8 @@ struct object *low_clone(struct program *p)
   p->num_clones++;
 #endif /* PROFILING */
 
-  o=(struct object *)xalloc( ((long)(((struct object *)0)->storage))+p->storage_needed);
+  o=alloc_object();
+  o->storage=p->storage_needed ? (char *)xalloc(p->storage_needed) : (char *)0;
 
   GC_ALLOC(o);
 
@@ -254,6 +269,7 @@ struct object *debug_clone_object(struct program *p, int args)
   debug_malloc_touch(o);
   call_pike_initializers(o,args);
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
   UNSET_ONERROR(tmp);
   return o;
 }
@@ -267,6 +283,7 @@ struct object *fast_clone_object(struct program *p, int args)
   call_c_initializers(o);
   UNSET_ONERROR(tmp);
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
   return o;
 }
 
@@ -425,6 +442,7 @@ struct object *get_master(void)
   }
   master_object=low_clone(master_program);
   debug_malloc_touch(master_object);
+  debug_malloc_touch(master_object->storage);
 
   call_c_initializers(master_object);
   call_pike_initializers(master_object,0);
@@ -524,6 +542,7 @@ void low_destruct(struct object *o,int do_free)
   }
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
   o->prog=0;
 
   LOW_PUSH_FRAME(o);
@@ -546,6 +565,7 @@ void low_destruct(struct object *o,int do_free)
     if(!do_free)
     {
       debug_malloc_touch(o);
+      debug_malloc_touch(o->storage);
       continue;
     }
 
@@ -570,6 +590,7 @@ void low_destruct(struct object *o,int do_free)
   }
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
   if(o->parent)
   {
     /* fprintf(stderr, "destruct(): Zapping parent.\n"); */
@@ -592,7 +613,7 @@ struct object *objects_to_destruct = 0;
 static struct callback *destruct_object_evaluator_callback =0;
 
 /* This function destructs the objects that are scheduled to be
- * destructed by really_free_object. It links the object back into the
+ * destructed by schedule_really_free_object. It links the object back into the
  * list of objects first. Adds a reference, destructs it and then frees it.
  */
 void destruct_objects_to_destruct(void)
@@ -634,20 +655,21 @@ void destruct_objects_to_destruct(void)
 }
 
 
-/* really_free_object:
+/* schedule_really_free_object:
  * This function is called when an object runs out of references.
  * It frees the object if it is destructed, otherwise it moves it to
  * a separate list of objects which will be destructed later.
  */
 
-void really_free_object(struct object *o)
+void schedule_really_free_object(struct object *o)
 {
 #ifdef PIKE_DEBUG
   if (o->refs)
-    fatal("Object still got references in really_free_object().\n");
+    fatal("Object still got references in schedule_really_free_object().\n");
 #endif
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
 
   if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE) {
     /* It's easier for the gc if we just leave the object around for
@@ -670,6 +692,7 @@ void really_free_object(struct object *o)
   }
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
 
   DOUBLEUNLINK(first_object,o);
 
@@ -695,7 +718,7 @@ void really_free_object(struct object *o)
   } else {
     if(o->parent)
     {
-      /* fprintf(stderr, "really_free_object(): Zapping parent.\n"); */
+      /* fprintf(stderr, "schedule_really_free_object(): Zapping parent.\n"); */
 
       free_object(o->parent);
       o->parent=0;
@@ -708,7 +731,12 @@ void really_free_object(struct object *o)
 
     FREE_PROT(o);
 
-    free((char *)o);
+    if(o->storage)
+    {
+      free(o->storage);
+      o->storage=0;
+    }
+    really_free_object(o);
 
     GC_FREE();
   }
@@ -726,6 +754,7 @@ void low_object_index_no_free(struct svalue *to,
     error("Cannot access global variables in destructed object.\n");
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
 
   i=ID_FROM_INT(p, f);
 
@@ -861,6 +890,7 @@ void object_low_set_index(struct object *o,
   }
 
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
   check_destructed(from);
 
   i=ID_FROM_INT(p, f);
@@ -1096,6 +1126,7 @@ void cleanup_objects(void)
     if(o->prog && !(o->prog->flags & PROGRAM_NO_EXPLICIT_DESTRUCT))
     {
       debug_malloc_touch(o);
+      debug_malloc_touch(o->storage);
       call_destroy(o,1);
       low_destruct(o,1);
     }
@@ -1170,6 +1201,7 @@ struct array *object_values(struct object *o)
 void gc_mark_object_as_referenced(struct object *o)
 {
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
 
   if(gc_mark(o))
   {
@@ -1448,34 +1480,6 @@ void gc_free_all_unreferenced_objects(void)
   }
 }
 
-void count_memory_in_objects(INT32 *num_, INT32 *size_)
-{
-  INT32 num=0, size=0;
-  struct object *o;
-  for(o=first_object;o;o=o->next)
-  {
-    num++;
-    if(o->prog)
-    {
-      size+=sizeof(struct object)-1+o->prog->storage_needed;
-    }else{
-      size+=sizeof(struct object);
-    }
-  }
-  for(o=objects_to_destruct;o;o=o->next)
-  {
-    num++;
-    if(o->prog)
-    {
-      size+=sizeof(struct object)-1+o->prog->storage_needed;
-    }else{
-      size+=sizeof(struct object);
-    }
-  }
-  *num_=num;
-  *size_=size;
-}
-
 struct magic_index_struct
 {
   struct inherit *inherit;
@@ -1483,7 +1487,7 @@ struct magic_index_struct
 };
 
 #define MAGIC_THIS ((struct magic_index_struct *)(CURRENT_STORAGE))
-#define MAGIC_O2S(o) ((struct magic_index_struct *)&(o->storage))
+#define MAGIC_O2S(o) ((struct magic_index_struct *)(o->storage))
 
 struct program *magic_index_program=0;
 struct program *magic_set_index_program=0;
@@ -1668,6 +1672,7 @@ void check_object(struct object *o)
   int e;
   struct program *p;
   debug_malloc_touch(o);
+  debug_malloc_touch(o->storage);
 
   if(o == fake_object) return;
 
diff --git a/src/object.h b/src/object.h
index d5a387b372fe2085d41a1d9e0466bba5b6bf2f59..ce0646d4ca88a0885a3419873c79bc66e3ea36d4 100644
--- a/src/object.h
+++ b/src/object.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: object.h,v 1.46 2000/06/09 22:43:05 mast Exp $
+ * $Id: object.h,v 1.47 2000/06/23 06:17:58 hubbe Exp $
  */
 #ifndef OBJECT_H
 #define OBJECT_H
@@ -32,7 +32,7 @@ struct object
 #if PIKE_DEBUG
   long program_id;
 #endif
-  char storage[1];
+  char *storage;
 };
 
 extern struct object *first_object;
@@ -43,7 +43,7 @@ extern struct program *master_program;
 extern struct program *magic_index_program;
 extern struct program *magic_set_index_program;
 
-#define free_object(O) do{ struct object *o_=(O); debug_malloc_touch(o_); if(!--o_->refs) really_free_object(o_); }while(0)
+#define free_object(O) do{ struct object *o_=(O); debug_malloc_touch(o_); debug_malloc_touch(o_->storage); if(!--o_->refs) schedule_really_free_object(o_); }while(0)
 
 #define LOW_GET_GLOBAL(O,I,ID) ((O)->storage+INHERIT_FROM_INT((O)->prog, (I))->storage_offset+(ID)->func.offset)
 #define GET_GLOBAL(O,I) LOW_GET_GLOBAL(O,I,ID_FROM_INT((O)->prog,I))
@@ -69,7 +69,7 @@ PTR_HASH_ALLOC(destroy_called_mark,128)
 void low_destruct(struct object *o,int do_free);
 void destruct(struct object *o);
 void destruct_objects_to_destruct(void);
-void really_free_object(struct object *o);
+void schedule_really_free_object(struct object *o);
 void low_object_index_no_free(struct svalue *to,
 			      struct object *o,
 			      INT32 f);
diff --git a/src/program.c b/src/program.c
index 53f483c21652c9d712522cdfc0c27cf90cc18151..48e7d9202d166b1bffec9ddd5d0a2eecfaa16839 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.241 2000/06/10 11:52:43 mast Exp $");
+RCSID("$Id: program.c,v 1.242 2000/06/23 06:17:58 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -658,7 +658,7 @@ void fixate_program(void)
 
 	dmalloc_add_mmap_entry(m,
 			       id->name->str,
-			       OFFSETOF(object,storage) + i->storage_offset + id->func.offset,
+			       /* OFFSETOF(object,storage) + */ i->storage_offset + id->func.offset,
 			       sizeof_variable(id->run_time_type),
 			       1, /* count */
 			       0,0);
@@ -675,7 +675,7 @@ void fixate_program(void)
       }
       dmalloc_add_mmap_entry(m,
 			     tmp,
-			     OFFSETOF(object, storage) + i->storage_offset,
+			     /* OFFSETOF(object, storage) + */ i->storage_offset,
 			     i->prog->storage_needed - i->prog->inherits[0].storage_offset,
 			     1, /* count */
 			     0,0);
@@ -781,11 +781,13 @@ void low_start_new_program(struct program *p,
 
   malloc_size_program = ALLOC_STRUCT(program);
 #ifdef PIKE_DEBUG
-  fake_object=(struct object *)xalloc(sizeof(struct object) + 256*sizeof(struct svalue));
+  fake_object=alloc_object();
+  fake_object->storage=(char *)xalloc(256 * sizeof(struct svalue));
   /* Stipple to find illegal accesses */
-  MEMSET(fake_object,0x55,sizeof(struct object) + 256*sizeof(struct svalue));
+  MEMSET(fake_object->storage,0x55,256*sizeof(struct svalue));
 #else
   fake_object=ALLOC_STRUCT(object);
+  fake_object->storage=0;
 #endif
   GC_ALLOC(fake_object);
 
@@ -805,6 +807,9 @@ void low_start_new_program(struct program *p,
   fake_object->prot=0;
 #endif
 
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
+
   if(name)
   {
     if((fake_object->parent=previous_program_state->fake_object))
@@ -827,6 +832,9 @@ void low_start_new_program(struct program *p,
 	     compilation_depth, "                ", new_program->id, compiler_pass);
 #endif
 
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
+
   if(new_program->program)
   {
 #define FOO(NUMTYPE,TYPE,NAME) \
@@ -885,6 +893,9 @@ void low_start_new_program(struct program *p,
 
   push_compiler_frame(0);
   add_ref(compiler_frame->current_return_type=void_type_string);
+
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
 }
 
 void debug_start_new_program(PROGRAM_LINE_ARGS)
@@ -1199,7 +1210,7 @@ void check_program(struct program *p)
 
     if(IDENTIFIER_IS_VARIABLE(p->identifiers[e].identifier_flags))
     {
-      if( (p->identifiers[e].func.offset + OFFSETOF(object,storage)) &
+      if( (p->identifiers[e].func.offset /* + OFFSETOF(object,storage)*/ ) &
 	 (alignof_variable(p->identifiers[e].run_time_type)-1))
       {
 	fatal("Variable %s offset is not properly aligned (%d).\n",p->identifiers[e].name->str,p->identifiers[e].func.offset);
@@ -1271,6 +1282,9 @@ struct program *end_first_pass(int finish)
   struct program *prog;
   struct pike_string *s;
 
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
+
   MAKE_CONSTANT_SHARED_STRING(s,"__INIT");
 
 
@@ -1395,7 +1409,7 @@ SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment, int modulo_orig)
   if(alignment <=0 || (alignment & (alignment-1)) || alignment > 256)
     fatal("Alignment must be 1,2,4,8,16,32,64,128 or 256 not %d\n",alignment);
 #endif
-  modulo=( modulo_orig+OFFSETOF(object,storage) ) % alignment;
+  modulo=( modulo_orig /* +OFFSETOF(object,storage) */ ) % alignment;
 
   offset=DO_ALIGN(new_program->storage_needed-modulo,alignment)+modulo;
 
@@ -1428,10 +1442,10 @@ SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment, int modulo_orig)
   if(offset < new_program->storage_needed)
     fatal("add_storage failed horribly!\n");
 
-  if( (offset + OFFSETOF(object,storage) - modulo_orig ) % alignment )
+  if( (offset /* + OFFSETOF(object,storage) */ - modulo_orig ) % alignment )
     fatal("add_storage failed horribly(2) %ld %ld %ld %ld!\n",
 	  (long)offset,
-	  (long)OFFSETOF(object,storage),
+	  (long)0 /* + OFFSETOF(object,storage) */,
 	  (long)modulo_orig,
 	  (long)alignment
 	  );
@@ -3466,12 +3480,16 @@ void init_program(void)
     free_string(key.u.string);
   }
   start_new_program();
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
   ADD_STORAGE(struct pike_trampoline);
   add_function("`()",apply_trampoline,"function(mixed...:mixed)",0);
   set_init_callback(init_trampoline);
   set_exit_callback(exit_trampoline);
   set_gc_check_callback(gc_check_trampoline);
   set_gc_recurse_callback(gc_recurse_trampoline);
+  debug_malloc_touch(fake_object);
+  debug_malloc_touch(fake_object->storage);
   pike_trampoline_program=end_program();
 }
 
diff --git a/src/svalue.c b/src/svalue.c
index 9acc459e8f206cfc7cfbef4656792223c922ecc3..305b64064429f5a8d8a0902c016a42b9cf8de36f 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -23,7 +23,7 @@
 #include "queue.h"
 #include "bignum.h"
 
-RCSID("$Id: svalue.c,v 1.76 2000/06/12 19:33:09 mast Exp $");
+RCSID("$Id: svalue.c,v 1.77 2000/06/23 06:17:58 hubbe Exp $");
 
 struct svalue dest_ob_zero = { T_INT, 0 };
 
@@ -51,7 +51,7 @@ void really_free_short_svalue(union anything *s, TYPE_T type)
       break;
       
     case T_OBJECT:
-      really_free_object(tmp.object);
+      schedule_really_free_object(tmp.object);
       break;
       
     case T_PROGRAM:
@@ -105,7 +105,7 @@ void really_free_svalue(struct svalue *s)
     /* fall through */
     
   case T_OBJECT:
-    really_free_object(s->u.object);
+    schedule_really_free_object(s->u.object);
     break;
     
   case T_PROGRAM:
@@ -226,7 +226,7 @@ void debug_free_svalues(struct svalue *s,INT32 num, INT32 type_hint DMALLOC_LINE
 	if(s->subtype == FUNCTION_BUILTIN)
 	  really_free_callable(s->u.efun);
 	else
-	  really_free_object(s->u.object);
+	  schedule_really_free_object(s->u.object);
 	DO_IF_DMALLOC(s->u.refs=0);
       }
       s++;
diff --git a/src/threads.h b/src/threads.h
index 4c96389fc7e4ee8a68c74c23f5d00301f21061b9..79a97e02f6b1100346ae6c45b78f0f838c511e0d 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.92 2000/06/09 22:46:59 mast Exp $
+ * $Id: threads.h,v 1.93 2000/06/23 06:17:58 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -494,7 +494,7 @@ struct thread_state {
 #define	OBJ2THREAD(X) \
   ((struct thread_state *)((X)->storage+thread_storage_offset))
 
-#define THREADSTATE2OBJ(X) BASEOF((X),object,storage[thread_storage_offset])
+#define THREADSTATE2OBJ(X) ((X)->thread_id)
 
 #define THREADS_ALLOW() do { \
      struct thread_state *_tmp=OBJ2THREAD(thread_id); \