* "'The Chamber of Records,' said Gimli. 'I guess that is where we now stand.'"
*/
+/* This file contains Perl's own implementation of the malloc library.
+ * It is used if Configure decides that, on your platform, Perl's
+ * version is better than the OS's, or if you give Configure the
+ * -Dusemymalloc command-line option.
+ */
+
/*
Here are some notes on configuring Perl's malloc. (For non-perl
usage see below.)
# define LOG_OF_MIN_ARENA 14
#endif
-#ifndef lint
-# if defined(DEBUGGING) && !defined(NO_RCHECK)
-# define RCHECK
-# endif
-# if defined(DEBUGGING) && !defined(NO_RCHECK) && !defined(NO_MFILL) && !defined(MALLOC_FILL)
-# define MALLOC_FILL
-# endif
-# if defined(DEBUGGING) && !defined(NO_RCHECK) && !defined(NO_FILL_CHECK) && !defined(MALLOC_FILL_CHECK)
-# define MALLOC_FILL_CHECK
-# endif
-# if defined(RCHECK) && defined(IGNORE_SMALL_BAD_FREE)
-# undef IGNORE_SMALL_BAD_FREE
-# endif
+#if defined(DEBUGGING) && !defined(NO_RCHECK)
+# define RCHECK
+#endif
+#if defined(DEBUGGING) && !defined(NO_RCHECK) && !defined(NO_MFILL) && !defined(MALLOC_FILL)
+# define MALLOC_FILL
+#endif
+#if defined(DEBUGGING) && !defined(NO_RCHECK) && !defined(NO_FILL_CHECK) && !defined(MALLOC_FILL_CHECK)
+# define MALLOC_FILL_CHECK
+#endif
+#if defined(RCHECK) && defined(IGNORE_SMALL_BAD_FREE)
+# undef IGNORE_SMALL_BAD_FREE
+#endif
/*
* malloc.c (Caltech) 2/21/82
* Chris Kingsley, kingsley@cit-20.
# define Free_t void
# endif
# define Copy(s,d,n,t) (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t))
+# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t))
# define PerlEnv_getenv getenv
# define PerlIO_printf fprintf
# define PerlIO_stderr() stderr
# ifndef pTHX
# define pTHX void
# define pTHX_
-# ifdef HASATTRIBUTE
+# ifdef HASATTRIBUTE_UNUSED
# define dTHX extern int Perl___notused PERL_UNUSED_DECL
# else
# define dTHX extern int Perl___notused
union overhead *ov_next; /* when free */
#if MEM_ALIGNBYTES > 4
double strut; /* alignment problems */
+# if MEM_ALIGNBYTES > 8
+ char sstrut[MEM_ALIGNBYTES]; /* for the sizing */
+# endif
#endif
struct {
/*
#ifdef BUCKETS_ROOT2
# define MAX_BUCKET_BY_TABLE 13
-static u_short buck_size[MAX_BUCKET_BY_TABLE + 1] =
+static const u_short buck_size[MAX_BUCKET_BY_TABLE + 1] =
{
0, 0, 0, 0, 4, 4, 8, 12, 16, 24, 32, 48, 64, 80,
};
# define N_BLKS(bucket) n_blks[bucket]
#endif
-static u_short n_blks[LOG_OF_MIN_ARENA * BUCKETS_PER_POW2] =
+static const u_short n_blks[LOG_OF_MIN_ARENA * BUCKETS_PER_POW2] =
{
# if BUCKETS_PER_POW2==1
0, 0,
# define BLK_SHIFT(bucket) blk_shift[bucket]
#endif
-static u_short blk_shift[LOG_OF_MIN_ARENA * BUCKETS_PER_POW2] =
+static const u_short blk_shift[LOG_OF_MIN_ARENA * BUCKETS_PER_POW2] =
{
# if BUCKETS_PER_POW2==1
0, 0,
# else
# define SIZE_TABLE_MAX 64
# endif
-static char bucket_of[] =
+static const char bucket_of[] =
{
# ifdef BUCKETS_ROOT2 /* Chunks of size 3*2^n. */
/* 0 to 15 in 4-byte increments. */
};
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
# 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 BIG_SIZE (1<<16) /* 64K */
# endif
-static char *emergency_buffer;
-static char *emergency_buffer_prepared;
-
# ifdef NO_MALLOC_DYNAMIC_CFG
static MEM_SIZE emergency_buffer_size;
/* 0 if the last request for more memory succeeded.
Otherwise the size of the failing request. */
static MEM_SIZE emergency_buffer_last_req;
+static char *emergency_buffer;
+static char *emergency_buffer_prepared;
# endif
# ifndef emergency_sbrk_croak
dTHX;
/* First offense, give a possibility to recover by dieing. */
/* No malloc involved here: */
- GV **gvp = (GV**)hv_fetch(PL_defstash, "^M", 2, 0);
SV *sv;
char *pv;
- STRLEN n_a;
+ GV **gvp = (GV**)hv_fetchs(PL_defstash, "^M", FALSE);
- if (!gvp) gvp = (GV**)hv_fetch(PL_defstash, "\015", 1, 0);
+ if (!gvp) gvp = (GV**)hv_fetchs(PL_defstash, "\015", FALSE);
if (!gvp || !(sv = GvSV(*gvp)) || !SvPOK(sv)
|| (SvLEN(sv) < (1<<LOG_OF_MIN_ARENA) - M_OVERHEAD))
return NULL; /* Now die die die... */
/* Got it, now detach SvPV: */
- pv = SvPV(sv, n_a);
+ pv = SvPV_nolen(sv);
/* Check alignment: */
if ((PTR2UV(pv) - sizeof(union overhead)) & (NEEDED_ALIGNMENT - 1)) {
PerlIO_puts(PerlIO_stderr(),"Bad alignment of $^M!\n");
}
SvPOK_off(sv);
- SvPVX(sv) = Nullch;
- SvCUR(sv) = SvLEN(sv) = 0;
+ SvPV_set(sv, NULL);
+ SvCUR_set(sv, 0);
+ SvLEN_set(sv, 0);
*size = malloced_size(pv) + M_OVERHEAD;
return pv - sizeof(union overhead);
}
MEM_SIZE rsize = (((size - 1)>>LOG_OF_MIN_ARENA) + 1)<<LOG_OF_MIN_ARENA;
if (size >= BIG_SIZE
- && (!emergency_buffer_last_req || (size < emergency_buffer_last_req))) {
+ && (!emergency_buffer_last_req ||
+ (size < (MEM_SIZE)emergency_buffer_last_req))) {
/* Give the possibility to recover, but avoid an infinite cycle. */
MALLOC_UNLOCK;
emergency_buffer_last_req = size;
emergency_sbrk_croak("Out of memory during \"large\" request for %"UVuf" bytes, total sbrk() is %"UVuf" bytes", (UV)size, (UV)(goodsbrk + sbrk_slack));
}
- if (emergency_buffer_size >= rsize) {
+ if ((MEM_SIZE)emergency_buffer_size >= rsize) {
char *old = emergency_buffer;
emergency_buffer_size -= rsize;
if (emergency_buffer_size) {
add_to_chain(emergency_buffer, emergency_buffer_size, 0);
emergency_buffer_size = 0;
- emergency_buffer = Nullch;
+ emergency_buffer = NULL;
have = 1;
}
MALLOC_UNLOCK;
emergency_sbrk_croak("Out of memory during request for %"UVuf" bytes, total sbrk() is %"UVuf" bytes", (UV)size, (UV)(goodsbrk + sbrk_slack));
/* NOTREACHED */
- return Nullch;
+ return NULL;
}
#else /* !defined(PERL_EMERGENCY_SBRK) */
{
unsigned char *e = s + nbytes;
long *lp;
- long lfill = *(long*)fill;
+ const long lfill = *(long*)fill;
if (PTR2UV(s) & (sizeof(long)-1)) { /* Align the pattern */
int shift = sizeof(long) - (PTR2UV(s) & (sizeof(long)-1));
{
unsigned char *e = s + nbytes;
long *lp;
- long lfill = *(long*)fill;
+ const long lfill = *(long*)fill;
if (PTR2UV(s) & (sizeof(long)-1)) { /* Align the pattern */
int shift = sizeof(long) - (PTR2UV(s) & (sizeof(long)-1));
|| (p->ov_next && PTR2UV(p->ov_next) < (1<<LOG_OF_MIN_ARENA)) ) {
dTHX;
PerlIO_printf(PerlIO_stderr(),
- "Unaligned `next' pointer in the free "
+ "Unaligned \"next\" pointer in the free "
"chain 0x%"UVxf" at 0x%"UVxf"\n",
PTR2UV(p->ov_next), PTR2UV(p));
}
MEM_SIZE slack = 0;
if (sbrk_goodness > 0) {
- if (!last_sbrk_top && require < FIRST_SBRK)
+ if (!last_sbrk_top && require < (MEM_SIZE)FIRST_SBRK)
require = FIRST_SBRK;
- else if (require < MIN_SBRK) require = MIN_SBRK;
+ else if (require < (MEM_SIZE)MIN_SBRK) require = MIN_SBRK;
if (require < goodsbrk * MIN_SBRK_FRAC1000 / 1000)
require = goodsbrk * MIN_SBRK_FRAC1000 / 1000;
# endif
}
#endif
- ; /* Finish `else' */
+ ; /* Finish "else" */
sbrked_remains = require - needed;
last_op = cp;
}
}
}
if (t && *t) {
- write2("Unrecognized part of PERL_MALLOC_OPT: `");
+ write2("Unrecognized part of PERL_MALLOC_OPT: \"");
write2(t);
- write2("'\n");
+ write2("\"\n");
}
if (changed)
MallocCfg[MallocCfg_cfg_env_read] = 1;
bad_free_warn = (pbf) ? atoi(pbf) : 1;
}
if (!bad_free_warn)
- return Nullch;
+ return NULL;
#ifdef RCHECK
#ifdef PERL_CORE
{
warn("%s", "Bad realloc() ignored");
#endif
#endif
- return Nullch; /* sanity */
+ return NULL; /* sanity */
}
onb = BUCKET_SIZE_REAL(bucket);
MEM_SIZE l = strlen(s);
char *s1 = (char *)Perl_malloc(l+1);
- Copy(s, s1, (MEM_SIZE)(l+1), char);
- return s1;
+ return CopyD(s, s1, (MEM_SIZE)(l+1), char);
}
#ifdef PERL_CORE
MEM_SIZE
Perl_malloced_size(void *p)
{
- union overhead *ovp = (union overhead *)
+ union overhead * const ovp = (union overhead *)
((caddr_t)p - sizeof (union overhead) * CHUNK_SHIFT);
- int bucket = OV_INDEX(ovp);
+ const int bucket = OV_INDEX(ovp);
#ifdef RCHECK
/* The caller wants to have a complete control over the chunk,
disable the memory checking inside the chunk. */
if (bucket <= MAX_SHORT_BUCKET) {
- MEM_SIZE size = BUCKET_SIZE_REAL(bucket);
+ const MEM_SIZE size = BUCKET_SIZE_REAL(bucket);
ovp->ov_size = size + M_OVERHEAD - 1;
*((u_int *)((caddr_t)ovp + size + M_OVERHEAD - RMAGIC_SZ)) = RMAGIC;
}
buffer.total_chain, buffer.sbrked_remains);
#endif /* DEBUGGING_MSTATS */
}
-#endif /* lint */
#ifdef USE_PERL_SBRK
}
#endif /* ! defined USE_PERL_SBRK */
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * ex: set ts=8 sts=4 sw=4 noet:
+ */