+static void morecore (register int bucket);
+# if defined(DEBUGGING)
+static void botch (char *diag, char *s, char *file, int line);
+# 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);
+
+#ifdef PERL_CORE
+
+#ifdef I_MACH_CTHREADS
+# undef MUTEX_LOCK
+# define MUTEX_LOCK(m) STMT_START { if (*m) mutex_lock(*m); } STMT_END
+# undef MUTEX_UNLOCK
+# define MUTEX_UNLOCK(m) STMT_START { if (*m) mutex_unlock(*m); } STMT_END
+#endif
+
+#endif /* defined PERL_CORE */
+
+#ifndef PTRSIZE
+# define PTRSIZE sizeof(void*)
+#endif
+
+#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 (BITS_IN_PTR*BUCKETS_PER_POW2 + 1)
+static union overhead *nextf[NBUCKETS];
+
+#if defined(PURIFY) && !defined(USE_PERL_SBRK)
+# define USE_PERL_SBRK
+#endif
+
+#ifdef USE_PERL_SBRK
+# define sbrk(a) Perl_sbrk(a)
+Malloc_t Perl_sbrk (int size);
+#else
+# ifndef HAS_SBRK_PROTO /* <unistd.h> usually takes care of this */
+extern Malloc_t sbrk(int);
+# endif
+#endif
+
+#ifndef MIN_SBRK_FRAC1000 /* Backward compatibility */
+# define MIN_SBRK_FRAC1000 (MIN_SBRK_FRAC * 10)
+#endif
+
+#ifndef START_EXTERN_C
+# ifdef __cplusplus
+# define START_EXTERN_C extern "C" {
+# else
+# define START_EXTERN_C
+# endif
+#endif
+
+#ifndef END_EXTERN_C
+# ifdef __cplusplus
+# define END_EXTERN_C };
+# else
+# define END_EXTERN_C
+# endif
+#endif
+
+#include "malloc_ctl.h"
+
+#ifndef NO_MALLOC_DYNAMIC_CFG
+# define PERL_MALLOC_OPT_CHARS "FMfAPGdac"
+
+# ifndef FILL_DEAD_DEFAULT
+# define FILL_DEAD_DEFAULT 1
+# endif
+# ifndef FILL_ALIVE_DEFAULT
+# define FILL_ALIVE_DEFAULT 1
+# endif
+# ifndef FILL_CHECK_DEFAULT
+# define FILL_CHECK_DEFAULT 1
+# endif
+
+static IV MallocCfg[MallocCfg_last] = {
+ FIRST_SBRK,
+ MIN_SBRK,
+ MIN_SBRK_FRAC,
+ SBRK_ALLOW_FAILURES,
+ SBRK_FAILURE_PRICE,
+ SBRK_ALLOW_FAILURES * SBRK_FAILURE_PRICE, /* sbrk_goodness */
+ FILL_DEAD_DEFAULT, /* FILL_DEAD */
+ FILL_ALIVE_DEFAULT, /* FILL_ALIVE */
+ FILL_CHECK_DEFAULT, /* FILL_CHECK */
+ 0, /* MallocCfg_skip_cfg_env */
+ 0, /* MallocCfg_cfg_env_read */
+ 0, /* MallocCfg_emergency_buffer_size */
+ 0, /* MallocCfg_emergency_buffer_prepared_size */
+ 0 /* MallocCfg_emergency_buffer_last_req */
+};
+IV *MallocCfg_ptr = MallocCfg;
+
+static char* MallocCfgP[MallocCfg_last] = {
+ 0, /* MallocCfgP_emergency_buffer */
+ 0, /* MallocCfgP_emergency_buffer_prepared */
+};
+char **MallocCfgP_ptr = MallocCfgP;
+
+# undef MIN_SBRK
+# undef FIRST_SBRK
+# undef MIN_SBRK_FRAC1000
+# undef SBRK_ALLOW_FAILURES
+# undef SBRK_FAILURE_PRICE
+
+# define MIN_SBRK MallocCfg[MallocCfg_MIN_SBRK]
+# define FIRST_SBRK MallocCfg[MallocCfg_FIRST_SBRK]
+# define MIN_SBRK_FRAC1000 MallocCfg[MallocCfg_MIN_SBRK_FRAC1000]
+# define SBRK_ALLOW_FAILURES MallocCfg[MallocCfg_SBRK_ALLOW_FAILURES]
+# define SBRK_FAILURE_PRICE MallocCfg[MallocCfg_SBRK_FAILURE_PRICE]
+
+# define sbrk_goodness MallocCfg[MallocCfg_sbrk_goodness]
+
+# define emergency_buffer_size MallocCfg[MallocCfg_emergency_buffer_size]
+# define emergency_buffer_last_req MallocCfg[MallocCfg_emergency_buffer_last_req]
+
+# define FILL_DEAD MallocCfg[MallocCfg_filldead]
+# define FILL_ALIVE MallocCfg[MallocCfg_fillalive]
+# define FILL_CHECK_CFG MallocCfg[MallocCfg_fillcheck]
+# define FILL_CHECK (FILL_DEAD && FILL_CHECK_CFG)
+
+# define emergency_buffer MallocCfgP[MallocCfgP_emergency_buffer]
+# define emergency_buffer_prepared MallocCfgP[MallocCfgP_emergency_buffer_prepared]
+
+#else /* defined(NO_MALLOC_DYNAMIC_CFG) */
+
+# define FILL_DEAD 1
+# define FILL_ALIVE 1
+# define FILL_CHECK 1
+static int sbrk_goodness = SBRK_ALLOW_FAILURES * SBRK_FAILURE_PRICE;
+
+# define NO_PERL_MALLOC_ENV
+
+#endif
+
+#ifdef DEBUGGING_MSTATS
+/*
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+ */
+static u_int nmalloc[NBUCKETS];
+static u_int sbrk_slack;
+static u_int start_slack;
+#else /* !( defined DEBUGGING_MSTATS ) */
+# define sbrk_slack 0
+#endif
+
+static u_int goodsbrk;
+
+#ifdef PERL_EMERGENCY_SBRK