Re: Mr Bloaty...

[email protected] (Ilya Zakharevich) Tue, 22 Feb 2000 15:00:00 -0500
Newsgroups perl.64bit,perl.perl5.porters
Message-ID <[email protected]>
On Tue, Feb 22, 2000 at 12:33:55PM +0000, Alan Burlison wrote:
> Ilya Zakharevich wrote:
> 
> > Now please change 32
> > 
> > #define NBUCKETS (32*BUCKETS_PER_POW2 + 1)
> > 
> > to 64, and try this with Perl's malloc.  ;-)
> 
> SEGVs after allocating about 2Gb of heap.  Perhaps Perl's malloc isn't
> always better than the system one... ;-)

This should be easily fixable... ;-)

> write(1, " b i g   i s   1 . 7 5  ".., 20)      = 20
> big is 2.00 Gb long
> write(1, " b i g   i s   2 . 0 0  ".., 20)      = 20
>     Incurred fault #6, FLTBOUNDS  %pc = 0xFFFFFFFF7E2009A8
>       siginfo: SIGSEGV SEGV_MAPERR addr=0x1A0128000
>     Received signal #11, SIGSEGV [default]
>       siginfo: SIGSEGV SEGV_MAPERR addr=0x1A0128000

Can you backtrace it?  I have a vague conjecture that we are not ready
for intptr_t in

     void *sbrk(intptr_t incr);

Yes, I see a lot of C<int> in the API of getpages() etc...

Try this (I also removed some dead code):

--- ./malloc.c~	Sun Feb 13 01:04:12 2000
+++ ./malloc.c	Tue Feb 22 14:52:00 2000
@@ -125,6 +125,9 @@
      # Type of size argument for allocation functions
      MEM_SIZE				unsigned long
 
+     # size of void*
+     PTRSIZE				4
+
      # Maximal value in LONG
      LONG_MAX				0x7FFFFFFF
 
@@ -245,6 +248,9 @@
 #    ifndef Malloc_t
 #      define Malloc_t void *
 #    endif
+#    ifndef PTRSIZE
+#      define PTRSIZE 4
+#    endif
 #    ifndef MEM_SIZE
 #      define MEM_SIZE unsigned long
 #    endif
@@ -831,7 +837,6 @@ static char bucket_of[] =
 static char *emergency_buffer;
 static MEM_SIZE emergency_buffer_size;
 
-static int	findbucket	(union overhead *freep, int srchlen);
 static void	morecore	(register int bucket);
 #  if defined(DEBUGGING)
 static void	botch		(char *diag, char *s);
@@ -840,8 +845,8 @@ static void	add_to_chain	(void *p, MEM_S
 static Malloc_t	emergency_sbrk	(MEM_SIZE size);
 static void*	get_from_chain	(MEM_SIZE size);
 static void*	get_from_bigger_buckets(int bucket, MEM_SIZE size);
-static union overhead *getpages	(int needed, int *nblksp, int bucket);
-static int	getpages_adjacent(int require);
+static union overhead *getpages	(MEM_SIZE needed, int *nblksp, int bucket);
+static int	getpages_adjacent(MEM_SIZE require);
 
 static Malloc_t
 emergency_sbrk(MEM_SIZE size)
@@ -908,12 +913,16 @@ emergency_sbrk(MEM_SIZE size)
 #  define emergency_sbrk(size)	-1
 #endif /* !(defined(PERL_EMERGENCY_SBRK) && defined(PERL_CORE)) */
 
+#ifndef BITS_IN_PTR
+#  define BITS_IN_PTR (8*PTRSIZE)
+#endif
+
 /*
  * nextf[i] is the pointer to the next free block of size 2^i.  The
  * smallest allocatable block is 8 bytes.  The overhead information
  * precedes the data area returned to the user.
  */
-#define	NBUCKETS (32*BUCKETS_PER_POW2 + 1)
+#define	NBUCKETS (BITS_IN_PTR*BUCKETS_PER_POW2 + 1)
 static	union overhead *nextf[NBUCKETS];
 
 #ifdef USE_PERL_SBRK
@@ -1178,14 +1187,14 @@ get_from_bigger_buckets(int bucket, MEM_
 }
 
 static union overhead *
-getpages(int needed, int *nblksp, int bucket)
+getpages(MEM_SIZE needed, int *nblksp, int bucket)
 {
     /* Need to do (possibly expensive) system call. Try to
        optimize it for rare calling. */
     MEM_SIZE require = needed - sbrked_remains;
     char *cp;
     union overhead *ovp;
-    int slack = 0;
+    MEM_SIZE slack = 0;
 
     if (sbrk_good > 0) {
 	if (!last_sbrk_top && require < FIRST_SBRK) 
@@ -1331,7 +1340,7 @@ getpages(int needed, int *nblksp, int bu
 }
 
 static int
-getpages_adjacent(int require)
+getpages_adjacent(MEM_SIZE require)
 {	    
     if (require <= sbrked_remains) {
 	sbrked_remains -= require;
@@ -1714,28 +1723,6 @@ Perl_realloc(void *mp, size_t nbytes)
 	    Perl_mfree(cp);
 	}
   	return ((Malloc_t)res);
-}
-
-/*
- * Search ``srchlen'' elements of each free list for a block whose
- * header starts at ``freep''.  If srchlen is -1 search the whole list.
- * Return bucket number, or -1 if not found.
- */
-static int
-findbucket(union overhead *freep, int srchlen)
-{
-	register union overhead *p;
-	register int i, j;
-
-	for (i = 0; i < NBUCKETS; i++) {
-		j = 0;
-		for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
-			if (p == freep)
-				return (i);
-			j++;
-		}
-	}
-	return (-1);
 }
 
 Malloc_t