Have symbols for the IoTYPEs.
[p5sagit/p5-mst-13.2.git] / malloc.c
index c4a7a90..57ca5a1 100644 (file)
--- a/malloc.c
+++ b/malloc.c
      # Type of size argument for allocation functions
      MEM_SIZE                          unsigned long
 
+     # size of void*
+     PTRSIZE                           4
+
      # Maximal value in LONG
      LONG_MAX                          0x7FFFFFFF
 
      warn(format, arg)                 fprintf(stderr, idem)
 
      # Locking/unlocking for MT operation
-     MALLOC_LOCK                       MUTEX_LOCK_NOCONTEXT(&PL_malloc_mutex)
-     MALLOC_UNLOCK                     MUTEX_UNLOCK_NOCONTEXT(&PL_malloc_mutex)
+     MALLOC_LOCK                       MUTEX_LOCK(&PL_malloc_mutex)
+     MALLOC_UNLOCK                     MUTEX_UNLOCK(&PL_malloc_mutex)
 
      # Locking/unlocking mutex for MT operation
      MUTEX_LOCK(l)                     void
 #    ifndef Malloc_t
 #      define Malloc_t void *
 #    endif
+#    ifndef PTRSIZE
+#      define PTRSIZE 4
+#    endif
 #    ifndef MEM_SIZE
 #      define MEM_SIZE unsigned long
 #    endif
 #endif 
 
 #ifndef MALLOC_LOCK
-#  define MALLOC_LOCK          MUTEX_LOCK_NOCONTEXT(&PL_malloc_mutex)
+#  define MALLOC_LOCK          MUTEX_LOCK(&PL_malloc_mutex)
 #endif 
 
 #ifndef MALLOC_UNLOCK
-#  define MALLOC_UNLOCK                MUTEX_UNLOCK_NOCONTEXT(&PL_malloc_mutex)
+#  define MALLOC_UNLOCK                MUTEX_UNLOCK(&PL_malloc_mutex)
 #endif 
 
 #  ifndef fatalcroak                           /* make depend */
     } STMT_END
 #endif
 
+#ifdef PERL_IMPLICIT_CONTEXT
+#  define PERL_IS_ALIVE                aTHX
+#else
+#  define PERL_IS_ALIVE                TRUE
+#endif
+    
+
 /*
  * Layout of memory:
  * ~~~~~~~~~~~~~~~~
@@ -428,8 +441,8 @@ union       overhead {
        double  strut;                  /* alignment problems */
 #endif
        struct {
-               u_char  ovu_magic;      /* magic number */
                u_char  ovu_index;      /* bucket # */
+               u_char  ovu_magic;      /* magic number */
 #ifdef RCHECK
                u_short ovu_size;       /* actual block size */
                u_int   ovu_rmagic;     /* range magic number */
@@ -815,6 +828,16 @@ static char bucket_of[] =
 #  define SBRK_FAILURE_PRICE 50
 #endif 
 
+static void    morecore        (register int bucket);
+#  if defined(DEBUGGING)
+static void    botch           (char *diag, char *s);
+#  endif
+static void    add_to_chain    (void *p, MEM_SIZE size, MEM_SIZE chip);
+static void*   get_from_chain  (MEM_SIZE size);
+static void*   get_from_bigger_buckets(int bucket, MEM_SIZE size);
+static union overhead *getpages        (MEM_SIZE needed, int *nblksp, int bucket);
+static int     getpages_adjacent(MEM_SIZE require);
+
 #if defined(PERL_EMERGENCY_SBRK) && defined(PERL_CORE)
 
 #  ifndef BIG_SIZE
@@ -831,18 +854,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);
-#  endif
-static void    add_to_chain    (void *p, MEM_SIZE size, MEM_SIZE chip);
-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 Malloc_t
 emergency_sbrk(MEM_SIZE size)
 {
@@ -908,12 +919,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];
 
 #if defined(PURIFY) && !defined(USE_PERL_SBRK)
@@ -951,7 +966,7 @@ static      u_int goodsbrk;
 static void
 botch(char *diag, char *s)
 {
-       dTHXo;
+       dTHX;
        PerlIO_printf(PerlIO_stderr(), "assertion botched (%s?): %s\n", diag, s);
        PerlProc_abort();
 }
@@ -1036,13 +1051,13 @@ Perl_malloc(register size_t nbytes)
        /* remove from linked list */
 #if defined(RCHECK)
        if ((PTR2UV(p)) & (MEM_ALIGNBYTES - 1)) {
-           dTHXo;
+           dTHX;
            PerlIO_printf(PerlIO_stderr(),
                          "Unaligned pointer in the free chain 0x%"UVxf"\n",
                          PTR2UV(p));
        }
        if ((PTR2UV(p->ov_next)) & (MEM_ALIGNBYTES - 1)) {
-           dTHXo;
+           dTHX;
            PerlIO_printf(PerlIO_stderr(),
                          "Unaligned `next' pointer in the free "
                          "chain 0x"UVxf" at 0x%"UVxf"\n",
@@ -1183,14 +1198,14 @@ get_from_bigger_buckets(int bucket, MEM_SIZE size)
 }
 
 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) 
@@ -1336,7 +1351,7 @@ getpages(int needed, int *nblksp, int bucket)
 }
 
 static int
-getpages_adjacent(int require)
+getpages_adjacent(MEM_SIZE require)
 {          
     if (require <= sbrked_remains) {
        sbrked_remains -= require;
@@ -1506,18 +1521,36 @@ Perl_mfree(void *mp)
            {
                static int bad_free_warn = -1;
                if (bad_free_warn == -1) {
-                   dTHXo;
+                   dTHX;
                    char *pbf = PerlEnv_getenv("PERL_BADFREE");
                    bad_free_warn = (pbf) ? atoi(pbf) : 1;
                }
                if (!bad_free_warn)
                    return;
 #ifdef RCHECK
+#ifdef PERL_CORE
+               {
+                   dTHX;
+                   if (!PERL_IS_ALIVE || !PL_curcop || ckWARN_d(WARN_MALLOC))
+                       Perl_warner(aTHX_ WARN_MALLOC, "%s free() ignored",
+                                   ovp->ov_rmagic == RMAGIC - 1 ?
+                                   "Duplicate" : "Bad");
+               }
+#else
                warn("%s free() ignored",
                    ovp->ov_rmagic == RMAGIC - 1 ? "Duplicate" : "Bad");
+#endif         
+#else
+#ifdef PERL_CORE
+               {
+                   dTHX;
+                   if (!PERL_IS_ALIVE || !PL_curcop || ckWARN_d(WARN_MALLOC))
+                       Perl_warner(aTHX_ WARN_MALLOC, "%s", "Bad free() ignored");
+               }
 #else
                warn("%s", "Bad free() ignored");
 #endif
+#endif
                return;                         /* sanity */
            }
 #ifdef RCHECK
@@ -1588,19 +1621,39 @@ Perl_realloc(void *mp, size_t nbytes)
            {
                static int bad_free_warn = -1;
                if (bad_free_warn == -1) {
-                   dTHXo;
+                   dTHX;
                    char *pbf = PerlEnv_getenv("PERL_BADFREE");
                    bad_free_warn = (pbf) ? atoi(pbf) : 1;
                }
                if (!bad_free_warn)
                    return Nullch;
 #ifdef RCHECK
+#ifdef PERL_CORE
+               {
+                   dTHX;
+                   if (!PERL_IS_ALIVE || !PL_curcop || ckWARN_d(WARN_MALLOC))
+                       Perl_warner(aTHX_ WARN_MALLOC, "%srealloc() %signored",
+                                   (ovp->ov_rmagic == RMAGIC - 1 ? "" : "Bad "),
+                                   ovp->ov_rmagic == RMAGIC - 1
+                                   ? "of freed memory " : "");
+               }
+#else
                warn("%srealloc() %signored",
                    (ovp->ov_rmagic == RMAGIC - 1 ? "" : "Bad "),
                     ovp->ov_rmagic == RMAGIC - 1 ? "of freed memory " : "");
+#endif
+#else
+#ifdef PERL_CORE
+               {
+                   dTHX;
+                   if (!PERL_IS_ALIVE || !PL_curcop || ckWARN_d(WARN_MALLOC))
+                       Perl_warner(aTHX_ WARN_MALLOC, "%s",
+                                   "Bad realloc() ignored");
+               }
 #else
                warn("%s", "Bad realloc() ignored");
 #endif
+#endif
                return Nullch;                  /* sanity */
            }
 
@@ -1721,28 +1774,6 @@ Perl_realloc(void *mp, size_t nbytes)
        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
 Perl_calloc(register size_t elements, register size_t size)
 {
@@ -1899,7 +1930,7 @@ Perl_dump_mstats(pTHX_ char *s)
                          (long)BUCKET_SIZE(MIN_BUCKET),
                          (long)BUCKET_SIZE_REAL(buffer.topbucket), 
                          (long)BUCKET_SIZE(buffer.topbucket));
-       PerlIO_printf(Perl_error_log, "%8d free:", buffer.totfree);
+       PerlIO_printf(Perl_error_log, "%8ld free:", buffer.totfree);
        for (i = MIN_EVEN_REPORT; i <= buffer.topbucket; i += BUCKETS_PER_POW2) {
                PerlIO_printf(Perl_error_log, 
                              ((i < 8*BUCKETS_PER_POW2 || i == 10*BUCKETS_PER_POW2)
@@ -1917,7 +1948,7 @@ Perl_dump_mstats(pTHX_ char *s)
                              buffer.nfree[i]);
        }
 #endif 
-       PerlIO_printf(Perl_error_log, "\n%8d used:", buffer.total - buffer.totfree);
+       PerlIO_printf(Perl_error_log, "\n%8ld used:", buffer.total - buffer.totfree);
        for (i = MIN_EVEN_REPORT; i <= buffer.topbucket; i += BUCKETS_PER_POW2) {
                PerlIO_printf(Perl_error_log, 
                              ((i < 8*BUCKETS_PER_POW2 || i == 10*BUCKETS_PER_POW2)
@@ -1935,7 +1966,7 @@ Perl_dump_mstats(pTHX_ char *s)
                              buffer.ntotal[i] - buffer.nfree[i]);
        }
 #endif 
-       PerlIO_printf(Perl_error_log, "\nTotal sbrk(): %d/%d:%d. Odd ends: pad+heads+chain+tail: %d+%d+%d+%d.\n",
+       PerlIO_printf(Perl_error_log, "\nTotal sbrk(): %ld/%ld:%ld. Odd ends: pad+heads+chain+tail: %ld+%ld+%ld+%ld.\n",
                      buffer.total_sbrk, buffer.sbrks, buffer.sbrk_good,
                      buffer.sbrk_slack, buffer.start_slack,
                      buffer.total_chain, buffer.sbrked_remains);
@@ -1947,17 +1978,6 @@ Perl_dump_mstats(pTHX_ char *s)
 
 #   if defined(__MACHTEN_PPC__) || defined(NeXT) || defined(__NeXT__) || defined(PURIFY)
 #      define PERL_SBRK_VIA_MALLOC
-/*
- * MachTen's malloc() returns a buffer aligned on a two-byte boundary.
- * While this is adequate, it may slow down access to longer data
- * types by forcing multiple memory accesses.  It also causes
- * complaints when RCHECK is in force.  So we allocate six bytes
- * more than we need to, and return an address rounded up to an
- * eight-byte boundary.
- *
- * 980701 Dominic Dunlop <domo@computer.org>
- */
-#      define SYSTEM_ALLOC_ALIGNMENT 2
 #   endif
 
 #   ifdef PERL_SBRK_VIA_MALLOC