diff --git a/src/block_alloc.h b/src/block_alloc.h
index 081393f1e9451ae25470dc3425aeab85515a7a50..372b7f4df40d52b79ee2cfab2dff61c23b4c452b 100644
--- a/src/block_alloc.h
+++ b/src/block_alloc.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: block_alloc.h,v 1.73 2004/06/02 00:07:20 nilsson Exp $
+|| $Id: block_alloc.h,v 1.74 2004/12/07 21:18:14 grubba Exp $
 */
 
 #undef PRE_INIT_BLOCK
@@ -95,10 +95,18 @@ struct PIKE_CONCAT(DATA,_block)						\
   INT32 used;								\
   DO_IF_DMALLOC(INT32 real_used;)					\
   struct DATA x[BSIZE];							\
+};									\
+struct PIKE_CONCAT(DATA,_context)					\
+{									\
+  struct PIKE_CONCAT(DATA,_context) *next;				\
+  struct PIKE_CONCAT(DATA, _block) *blocks, *free_blocks;		\
+  INT32 num_empty_blocks;						\
 };									\
 									\
+static struct PIKE_CONCAT(DATA,_context) *PIKE_CONCAT(DATA,_ctxs)=0;	\
 static struct PIKE_CONCAT(DATA,_block) *PIKE_CONCAT(DATA,_blocks)=0;	\
-static struct PIKE_CONCAT(DATA,_block) *PIKE_CONCAT(DATA,_free_blocks)=(void*)-1;  \
+static struct PIKE_CONCAT(DATA,_block) *PIKE_CONCAT(DATA,_free_blocks)=	\
+  (void*)-1;								\
 static INT32 PIKE_CONCAT3(num_empty_,DATA,_blocks)=0;			\
 DO_IF_RUN_UNLOCKED(static PIKE_MUTEX_T PIKE_CONCAT(DATA,_mutex);)       \
 DO_IF_DMALLOC(								\
@@ -106,6 +114,25 @@ DO_IF_DMALLOC(								\
   static size_t PIKE_CONCAT(DATA,s_to_free_ptr) = 0;			\
 )									\
 									\
+void PIKE_CONCAT3(new_,DATA,_context)(void)				\
+{									\
+  struct PIKE_CONCAT(DATA, _context) *ctx =				\
+    (struct PIKE_CONCAT(DATA, _context) *)				\
+    malloc(sizeof(struct PIKE_CONCAT(DATA, _context)));			\
+  if (!ctx) {								\
+    fprintf(stderr, "Fatal: out of memory.\n");				\
+    exit(17);								\
+  }									\
+  ctx->next = PIKE_CONCAT(DATA, _ctxs);					\
+  PIKE_CONCAT(DATA, _ctxs) = ctx;					\
+  ctx->blocks = PIKE_CONCAT(DATA,_blocks);				\
+  ctx->free_blocks = PIKE_CONCAT(DATA,_free_blocks);			\
+  ctx->num_empty_blocks = PIKE_CONCAT3(num_empty_,DATA,_blocks);	\
+  PIKE_CONCAT(DATA,_blocks) = 0;					\
+  PIKE_CONCAT(DATA,_free_blocks) = (void *)-1;				\
+  PIKE_CONCAT3(num_empty_,DATA,_blocks) = 0;				\
+}									\
+									\
 static void PIKE_CONCAT(alloc_more_,DATA)(void)				\
 {                                                                       \
   struct PIKE_CONCAT(DATA,_block) *n;					\
@@ -184,6 +211,7 @@ DO_IF_DMALLOC(                                                          \
 static void PIKE_CONCAT(check_free_,DATA)(struct DATA *d)               \
 {                                                                       \
   struct PIKE_CONCAT(DATA,_block) *tmp;					\
+  struct PIKE_CONCAT(DATA,_context) *ctx = PIKE_CONCAT(DATA,_ctxs);	\
   for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next)                  \
   {                                                                     \
     if( (char *)d < (char *)tmp) continue;                              \
@@ -192,6 +220,17 @@ static void PIKE_CONCAT(check_free_,DATA)(struct DATA *d)               \
 	(d - tmp->x) * (ptrdiff_t) sizeof (struct DATA)) break;		\
     return;                                                             \
   }                                                                     \
+  while (ctx) {								\
+    for(tmp=ctx->blocks; tmp; tmp=tmp->next)				\
+    {									\
+      if( (char *)d < (char *)tmp) continue;				\
+      if( (char *)d >= (char *)(tmp->x+(BSIZE))) continue;		\
+      if ((char *) d - (char *) tmp->x !=				\
+	  (d - tmp->x) * (ptrdiff_t) sizeof (struct DATA)) break;	\
+      return;								\
+    }									\
+    ctx = ctx->next;							\
+  }									\
   Pike_fatal("really_free_%s called on non-block_alloc region (%p).\n",	\
 	     #DATA, d);							\
 }                                                                       \
@@ -319,9 +358,18 @@ static void PIKE_CONCAT3(free_all_,DATA,_blocks_unlocked)(void)		\
     PIKE_MEM_RW(tmp->x);						\
     free((char *)tmp);							\
   }									\
-  PIKE_CONCAT(DATA,_blocks)=0;						\
-  PIKE_CONCAT(DATA,_free_blocks)=0;					\
-  PIKE_CONCAT3(num_empty_,DATA,_blocks)=0;				\
+  if (PIKE_CONCAT(DATA,_ctxs)) {					\
+    struct PIKE_CONCAT(DATA, _context) *ctx = PIKE_CONCAT(DATA,_ctxs);	\
+    PIKE_CONCAT(DATA,_blocks)=ctx->blocks;				\
+    PIKE_CONCAT(DATA,_free_blocks)=ctx->free_blocks;			\
+    PIKE_CONCAT3(num_empty_,DATA,_blocks)=ctx->num_empty_blocks;	\
+    PIKE_CONCAT(DATA,_ctxs) = ctx->next;				\
+    free(ctx);								\
+  } else {								\
+    PIKE_CONCAT(DATA,_blocks)=0;					\
+    PIKE_CONCAT(DATA,_free_blocks)=0;					\
+    PIKE_CONCAT3(num_empty_,DATA,_blocks)=0;				\
+  }									\
 }									\
 									\
 void PIKE_CONCAT3(free_all_,DATA,_blocks)(void)				\
@@ -335,6 +383,7 @@ void PIKE_CONCAT3(count_memory_in_,DATA,s)(INT32 *num_, INT32 *size_)	\
 {									\
   INT32 num=0, size=0;							\
   struct PIKE_CONCAT(DATA,_block) *tmp;					\
+  struct PIKE_CONCAT(DATA,_context) *ctx = PIKE_CONCAT(DATA,_ctxs);	\
   DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex)));               \
   for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next)			\
   {									\
@@ -342,6 +391,15 @@ void PIKE_CONCAT3(count_memory_in_,DATA,s)(INT32 *num_, INT32 *size_)	\
     num+=tmp->used;							\
     COUNT_BLOCK(tmp);                                                   \
   }									\
+  while (ctx) {								\
+    for(tmp=ctx->blocks;tmp;tmp=tmp->next)				\
+    {									\
+      size+=sizeof(struct PIKE_CONCAT(DATA,_block));			\
+      num+=tmp->used;							\
+      COUNT_BLOCK(tmp);							\
+    }									\
+    ctx = ctx->next;							\
+  }									\
   COUNT_OTHER();                                                        \
   *num_=num;								\
   *size_=size;								\
diff --git a/src/block_alloc_h.h b/src/block_alloc_h.h
index 3ded4e2a1eb68ddc69749b81df6d1b3cedfeb498..ae4c1292f4f8fc4f95e43c44c2c4559101d5c8e4 100644
--- a/src/block_alloc_h.h
+++ b/src/block_alloc_h.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: block_alloc_h.h,v 1.21 2004/02/06 12:26:15 grubba Exp $
+|| $Id: block_alloc_h.h,v 1.22 2004/12/07 21:18:34 grubba Exp $
 */
 
 #undef BLOCK_ALLOC
@@ -22,6 +22,7 @@
 
 #define BLOCK_ALLOC(DATA,SIZE)						\
 struct DATA *PIKE_CONCAT(alloc_,DATA)(void);				\
+void PIKE_CONCAT3(new_,DATA,_context)(void);				\
 void PIKE_CONCAT3(really_free_,DATA,_unlocked)(struct DATA *d);		\
 void PIKE_CONCAT(really_free_,DATA)(struct DATA *d);			\
 void PIKE_CONCAT3(free_all_,DATA,_blocks)(void);			\