diff --git a/src/pike_memory.c b/src/pike_memory.c
index e00e4e814d28e382df234eb64daa779220e789cf..f560b7545a88055b19b5172ce9cc79d7f7972893 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -452,32 +452,38 @@ static MUTEX_T debug_malloc_mutex;
 #undef strdup
 #undef main
 
-static void add_location(struct memhdr *mh, const char *fn, int line);
+static void add_location(struct memhdr *mh, int locnum);
 static struct memhdr *find_memhdr(void *p);
 
+#include "block_alloc.h"
+
 int verbose_debug_malloc = 0;
 int verbose_debug_exit = 1;
 
-#define BSIZE 16382
-#define HSIZE 65599
-#define LHSIZE 133153
+#define HSIZE 1109891
+#define LHSIZE 1109891
+#define FLSIZE 8803
 
-struct memloc
+struct fileloc
 {
-  struct memloc *next;
-  const char *filename;
-  struct memhdr *mh;
+  struct fileloc *next;
+  const char *file;
   int line;
-  int times;
+  int number;
 };
 
+BLOCK_ALLOC(fileloc, 4090)
 
-struct memloc_block
+struct memloc
 {
-  struct memloc_block *next;
-  struct memloc memlocs[BSIZE];
+  struct memloc *next;
+  struct memhdr *mh;
+  int locnum;
+  int times;
 };
 
+BLOCK_ALLOC(memloc, 16382)
+
 struct memhdr
 {
   struct memhdr *next;
@@ -486,60 +492,59 @@ struct memhdr
   struct memloc *locations;
 };
 
-
-struct memhdr_block
-{
-  struct memhdr_block *next;
-  struct memhdr memhdrs[BSIZE];
-};
-
-static struct memloc_block *memloc_blocks=0;
-static struct memloc *free_memlocs=0;
-static struct memhdr no_leak_memlocs;
-
+static struct fileloc *flhash[FLSIZE];
 static struct memloc *mlhash[LHSIZE];
 static struct memhdr *hash[HSIZE];
 
-static struct memhdr_block *memhdr_blocks=0;
-static struct memhdr *free_memhdrs=0;
+static struct memhdr no_leak_memlocs;
+static int file_location_number=0;
 
-struct memhdr *alloc_memhdr(void)
+static int location_number(const char *file, int line)
 {
-  struct memhdr *tmp;
-  if(!free_memhdrs)
+  struct fileloc *f,**prev;
+  unsigned long h=(long)file;
+  h*=4711;
+  h+=line;
+  h%=FLSIZE;
+  for(prev=flhash+h;(f=*prev);prev=&f->next)
   {
-    struct memhdr_block *n;
-    int e;
-    n=(struct memhdr_block *)malloc(sizeof(struct memhdr_block));
-    if(!n)
+    if(f->line == line && f->file == file)
     {
-      fprintf(stderr,"Fatal: out of memory.\n");
-      verbose_debug_exit=0;
-      exit(17);
-    }
-    n->next=memhdr_blocks;
-    memhdr_blocks=n;
-
-    for(e=0;e<BSIZE;e++)
-    {
-      n->memhdrs[e].next=free_memhdrs;
-      free_memhdrs=n->memhdrs+e;
+      *prev=f->next;
+      f->next=flhash[h];
+      flhash[h]=f;
+      return f->number;
     }
   }
 
-  tmp=free_memhdrs;
-  tmp->locations=0;
-  free_memhdrs=tmp->next;
-  return tmp;
+  f=alloc_fileloc();
+  f->line=line;
+  f->file=file;
+  f->number=++file_location_number;
+  f->next=flhash[h];
+  flhash[h]=f;
+  return f->number;
+}
+
+static struct fileloc *find_file_location(int locnum)
+{
+  int e;
+  struct fileloc *r;
+  for(e=0;e<FLSIZE;e++)
+    for(r=flhash[e];r;r=r->next)
+      if(r->number == locnum)
+	return r;
+  fprintf(stderr,"Internal error in DEBUG_MALLOC, failed to find location.\n");
+  exit(127);
 }
 
 void low_add_marks_to_memhdr(struct memhdr *to,
-				    struct memhdr *from)
+			     struct memhdr *from)
 {
   struct memloc *l;
   if(!from) return;
   for(l=from->locations;l;l=l->next)
-    add_location(to, l->filename, l->line);
+    add_location(to, l->locnum);
 }
 
 void add_marks_to_memhdr(struct memhdr *to, void *ptr)
@@ -547,132 +552,119 @@ void add_marks_to_memhdr(struct memhdr *to, void *ptr)
   low_add_marks_to_memhdr(to,find_memhdr(ptr));
 }
 
-static unsigned long lhash(struct memhdr *m,
-			   const char *fn,
-			   int line)
+static inline unsigned long lhash(struct memhdr *m, int locnum)
 {
   unsigned long l;
   l=(long)m;
   l*=53;
-  l+=(long)fn;
-  l*=4711;
-  l+=line;
+  l+=locnum;
   l%=LHSIZE;
   return l;
 }
 
-void free_memhdr(struct memhdr *mh)
-{
-  struct memloc *ml;
-  while((ml=mh->locations))
-  {
-    unsigned long l=lhash(mh,ml->filename, ml->line);
-    if(mlhash[l]==ml) mlhash[l]=0;
-    
-    mh->locations=ml->next;
-    ml->next=free_memlocs;
-    free_memlocs=ml;
-  }
-  mh->next=free_memhdrs;
-  free_memhdrs=mh;
-}
+#undef INIT_BLOCK
+#undef EXIT_BLOCK
 
-static struct memloc *alloc_memloc(void)
-{
-  struct memloc *tmp;
-  if(!free_memlocs)
-  {
-    struct memloc_block *n;
-    int e;
-    n=(struct memloc_block *)malloc(sizeof(struct memloc_block));
-    if(!n)
-    {
-      fprintf(stderr,"Fatal: out of memory.\n");
-      verbose_debug_exit=0;
-      exit(17);
-    }
-    n->next=memloc_blocks;
-    memloc_blocks=n;
+#define INIT_BLOCK(X) X->locations=0
+#define EXIT_BLOCK(X) do {				\
+  struct memloc *ml;					\
+  while((ml=X->locations))				\
+  {							\
+    unsigned long l=lhash(X,ml->locnum);		\
+    if(mlhash[l]==ml) mlhash[l]=0;			\
+							\
+    X->locations=ml->next;				\
+    free_memloc(ml);					\
+  }							\
+}while(0)
 
-    for(e=0;e<BSIZE;e++)
-    {
-      n->memlocs[e].next=free_memlocs;
-      free_memlocs=n->memlocs+e;
-    }
-  }
+BLOCK_ALLOC(memhdr,16382)
+
+#undef INIT_BLOCK
+#undef EXIT_BLOCK
+
+#define INIT_BLOCK(X)
+#define EXIT_BLOCK(X)
 
-  tmp=free_memlocs;
-  free_memlocs=tmp->next;
-  return tmp;
-}
 
 static struct memhdr *find_memhdr(void *p)
 {
-  struct memhdr *mh;
+  struct memhdr *mh,**prev;
   unsigned long h=(long)p;
   h%=HSIZE;
-  for(mh=hash[h]; mh; mh=mh->next)
+  for(prev=hash+h; (mh=*prev); prev=&mh->next)
+  {
     if(mh->data==p)
+    {
+      *prev=mh->next;
+      mh->next=hash[h];
+      hash[h]=mh;
       return mh;
+    }
+  }
   return NULL;
 }
 
 
-static void add_location(struct memhdr *mh, const char *fn, int line)
+static int find_location(struct memhdr *mh, int locnum)
 {
   struct memloc *ml;
-  unsigned long l=lhash(mh,fn,line);
+  unsigned long l=lhash(mh,locnum);
 
   if(mlhash[l] &&
      mlhash[l]->mh==mh &&
-     mlhash[l]->filename==fn &&
-     mlhash[l]->line==line)
-    return;
+     mlhash[l]->locnum==locnum)
+    return 1;
 
   for(ml=mh->locations;ml;ml=ml->next)
-    if(ml->filename==fn && ml->line==line)
-      break;
-
-  if(!ml)
   {
-    ml=alloc_memloc();
-    ml->line=line;
-    ml->filename=fn;
-    ml->next=mh->locations;
-    ml->times++;
-    ml->mh=mh;
-    mh->locations=ml;
+    if(ml->locnum==locnum)
+    {
+      mlhash[l]=ml;
+      return 1;
+    }
   }
-  mlhash[l]=ml;
+  return 0;
 }
 
-static int find_location(struct memhdr *mh, const char *fn, int line)
+static void add_location(struct memhdr *mh, int locnum)
 {
   struct memloc *ml;
-  unsigned long l=lhash(mh,fn,line);
+  unsigned long l;
 
-  if(mlhash[l] &&
-     mlhash[l]->mh==mh &&
-     mlhash[l]->filename==fn &&
-     mlhash[l]->line==line)
-    return 1;
+#if DEBUG_MALLOC - 0 < 2
+  if(find_location(&no_leak_memlocs, locnum)) return;
+#endif
+
+  l=lhash(mh,locnum);
+
+  if(mlhash[l] && mlhash[l]->mh==mh && mlhash[l]->locnum==locnum)
+  {
+    mlhash[l]->times++;
+    return;
+  }
 
   for(ml=mh->locations;ml;ml=ml->next)
+    if(ml->locnum==locnum)
+      break;
+
+  if(!ml)
   {
-    if(ml->filename==fn && ml->line==line)
-    {
-      mlhash[l]=ml;
-      return 1;
-    }
+    ml=alloc_memloc();
+    ml->locnum=locnum;
+    ml->next=mh->locations;
+    ml->mh=mh;
+    mh->locations=ml;
   }
-  return 0;
+  ml->times++;
+  mlhash[l]=ml;
 }
 
-static void make_memhdr(void *p, int s, const char *fn, int line)
+static void make_memhdr(void *p, int s, int locnum)
 {
   struct memhdr *mh=alloc_memhdr();
   struct memloc *ml=alloc_memloc();
-  unsigned long l=lhash(mh,fn,line);
+  unsigned long l=lhash(mh,locnum);
   unsigned long h=(long)p;
   h%=HSIZE;
 
@@ -680,8 +672,7 @@ static void make_memhdr(void *p, int s, const char *fn, int line)
   mh->data=p;
   mh->size=s;
   mh->locations=ml;
-  ml->filename=fn;
-  ml->line=line;
+  ml->locnum=locnum;
   ml->next=0;
   ml->times=1;
   hash[h]=mh;
@@ -710,9 +701,12 @@ static int remove_memhdr(void *p)
 void *debug_malloc(size_t s, const char *fn, int line)
 {
   void *m;
+
   mt_lock(&debug_malloc_mutex);
+
   m=malloc(s);
-  if(m) make_memhdr(m, s, fn, line);
+  if(m)
+    make_memhdr(m, s, location_number(fn,line));
 
   if(verbose_debug_malloc)
     fprintf(stderr, "malloc(%d) => %p  (%s:%d)\n", s, m, fn, line);
@@ -725,10 +719,11 @@ void *debug_malloc(size_t s, const char *fn, int line)
 void *debug_calloc(size_t a, size_t b, const char *fn, int line)
 {
   void *m;
+  int locnum;
   mt_lock(&debug_malloc_mutex);
   m=calloc(a, b);
 
-  if(m) make_memhdr(m, a*b, fn, line);
+  if(m) make_memhdr(m, a*b, location_number(fn,line));
 
   if(verbose_debug_malloc)
     fprintf(stderr, "calloc(%d,%d) => %p  (%s:%d)\n", a, b, m, fn, line);
@@ -744,7 +739,7 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line)
   m=realloc(p, s);
   if(m) {
     if(p) remove_memhdr(p);
-    make_memhdr(m, s, fn, line);
+    make_memhdr(m, s, location_number(fn,line));
   }
   if(verbose_debug_malloc)
     fprintf(stderr, "realloc(%p,%d) => %p  (%s:%d)\n", p, s, m, fn,line);
@@ -768,7 +763,7 @@ char *debug_strdup(const char *s, const char *fn, int line)
   mt_lock(&debug_malloc_mutex);
   m=strdup(s);
 
-  if(m) make_memhdr(m, strlen(s)+1, fn, line);
+  if(m) make_memhdr(m, strlen(s)+1, location_number(fn,line));
 
   if(verbose_debug_malloc)
     fprintf(stderr, "strdup(\"%s\") => %p  (%s:%d)\n", s, m, fn, line);
@@ -783,9 +778,12 @@ void dump_memhdr_locations(struct memhdr *from,
   struct memloc *l;
   for(l=from->locations;l;l=l->next)
   {
-    if(find_location(notfrom, l->filename, l->line))
+    struct fileloc *f;
+    if(notfrom && find_location(notfrom, l->locnum))
       continue;
-    fprintf(stderr," *** %s:%d (%d times)\n",l->filename,l->line,l->times);
+
+    f=find_file_location(l->locnum);
+    fprintf(stderr," *** %s:%d (%d times)\n",f->file,f->line,l->times);
   }
 }
 
@@ -807,16 +805,18 @@ void cleanup_memhdrs()
 	  fprintf(stderr,"\n");
 	  first=0;
 	}
+
 	
 	fprintf(stderr, "LEAK: (%p) %d bytes\n",m->data, m->size);
 	for(l=m->locations;l;l=l->next)
+	{
+	  struct fileloc *f=find_file_location(l->locnum);
 	  fprintf(stderr,"  *** %s:%d (%d times) %s\n",
-		  l->filename,
-		  l->line,
+		  f->file,
+		  f->line,
 		  l->times,
-		  find_location(&no_leak_memlocs,
-				l->filename,
-				l->line) ? "" : " *");
+		  find_location(&no_leak_memlocs, l->locnum) ? "" : " *");
+	}
       }
     }
   }
@@ -837,7 +837,7 @@ void * debug_malloc_update_location(void *p,const char *fn, int line)
   {
     struct memhdr *mh;
     if((mh=find_memhdr(p)))
-      add_location(mh, fn, line);
+      add_location(mh, location_number(fn,line));
   }
   return p;
 }