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