summaryrefslogtreecommitdiff
path: root/malloc.c
diff options
context:
space:
mode:
authorPerl 5 Porters <perl5-porters@africa.nicoh.com>1996-11-19 14:16:00 +1200
committerChip Salzenberg <chip@atlantic.net>1996-11-19 14:16:00 +1200
commit55497cffdd24c959994f9a8ddd56db8ce85e1c5b (patch)
tree444dfb8adc0e5b96d56e0532791122c366f50a3e /malloc.c
parentc822f08a5087943f7d9e2c36ce42ea035f03ab97 (diff)
downloadperl-55497cffdd24c959994f9a8ddd56db8ce85e1c5b.tar.gz
[inseparable changes from patch from perl5.003_07 to perl5.003_08]
CORE LANGUAGE CHANGES Subject: Bitwise op sign rationalization From: Chip Salzenberg <chip@atlantic.net> Files: op.c opcode.pl pod/perlop.pod pod/perltoc.pod pp.c pp.h pp_hot.c proto.h sv.c t/op/bop.t Make bitwise ops result in unsigned values, unless C<use integer> is in effect. Includes initial support for UVs. Subject: Defined scoping for C<my> in control structures From: Chip Salzenberg <chip@atlantic.net> Files: op.c perly.c perly.c.diff perly.h perly.y proto.h toke.c Finally defines semantics of "my" in control expressions, like the condition of "if" and "while". In all cases, scope of a "my" var extends to the end of the entire control structure. Also adds new construct "for my", which automatically declares the control variable "my" and limits its scope to the loop. Subject: Fix ++/-- after int conversion (e.g. 'printf "%d"') From: Chip Salzenberg <chip@atlantic.net> Files: pp.c pp_hot.c sv.c This patch makes Perl correctly ignore SvIVX() if either NOK or POK is true, since SvIVX() may be a truncated or overflowed version of the real value. Subject: Make code match Camel II re: functions that use $_ From: Paul Marquess <pmarquess@bfsec.bt.co.uk> Files: opcode.pl Subject: Provide scalar context on left side of "->" From: Chip Salzenberg <chip@atlantic.net> Files: perly.c perly.y Subject: Quote bearword package/handle FOO in "funcname FOO => 'bar'" From: Chip Salzenberg <chip@atlantic.net> Files: toke.c OTHER CORE CHANGES Subject: Warn on overflow of octal and hex integers From: Chip Salzenberg <chip@atlantic.net> Files: proto.h toke.c util.c Subject: If -w active, warn for commas and hashes ('#') in qw() From: Chip Salzenberg <chip@atlantic.net> Files: toke.c Subject: Fixes for pack('w') From: Ulrich Pfeifer <pfeifer@charly.informatik.uni-dortmund.de> Files: pp.c t/op/pack.t Subject: More complete output from sv_dump() From: Gurusamy Sarathy <gsar@engin.umich.edu> Files: sv.c Subject: Major '..' and debugger patches From: Ilya Zakharevich <ilya@math.ohio-state.edu> Files: lib/perl5db.pl op.c pp_ctl.c scope.c scope.h Subject: Fix for formline() From: Gurusamy Sarathy <gsar@engin.umich.edu> Files: global.sym mg.c perl.h pod/perldiag.pod pp_ctl.c proto.h sv.c t/op/write.t Subject: Fix stack botch in untie and binmode From: Gurusamy Sarathy <gsar@engin.umich.edu> Files: pp_sys.c Subject: Complete EMBED, including symbols from interp.sym From: Chip Salzenberg <chip@atlantic.net> Files: MANIFEST embed.pl ext/DynaLoader/dlutils.c ext/SDBM_File/sdbm/sdbm.h global.sym handy.h malloc.c perl.h pp_sys.c proto.h regexec.c toke.c util.c x2p/Makefile.SH x2p/a2p.h x2p/handy.h x2p/util.h New define EMBEDMYMALLOC makes embedding total by avoiding "Mymalloc" etc. Subject: Support old embedding for people who want it From: Chip Salzenberg <chip@atlantic.net> Files: MANIFEST Makefile.SH old_embed.pl old_global.sym PORTABILITY Subject: Miscellaneous VMS fixes From: Charles Bailey <bailey@HMIVAX.HUMGEN.UPENN.EDU> Files: lib/ExtUtils/Liblist.pm lib/ExtUtils/MM_VMS.pm lib/Math/Complex.pm lib/Time/Local.pm lib/timelocal.pl perl.h perl_exp.SH proto.h t/TEST t/io/read.t t/lib/findbin.t t/lib/getopt.t util.c utils/h2xs.PL vms/Makefile vms/config.vms vms/descrip.mms vms/ext/Stdio/Stdio.pm vms/ext/Stdio/Stdio.xs vms/perlvms.pod vms/test.com vms/vms.c Subject: DJGPP patches (MS-DOS) From: "Douglas E. Wegscheid" <wegscd@whirlpool.com> Files: doio.c dosish.h ext/SDBM_File/sdbm/sdbm.c handy.h lib/AutoSplit.pm lib/Cwd.pm lib/File/Find.pm malloc.c perl.c perl.h pp_sys.c proto.h sv.c util.c Subject: Patch to make Perl work under AmigaOS From: "Norbert Pueschel" <pueschel@imsdd.meb.uni-bonn.de> Files: MANIFEST hints/amigaos.sh installman lib/File/Basename.pm lib/File/Find.pm pod/pod2man.PL pp_sys.c util.c
Diffstat (limited to 'malloc.c')
-rw-r--r--malloc.c146
1 files changed, 124 insertions, 22 deletions
diff --git a/malloc.c b/malloc.c
index 680b73454b..042c233efc 100644
--- a/malloc.c
+++ b/malloc.c
@@ -145,6 +145,79 @@ static u_int start_slack;
# define M_OVERHEAD (sizeof(union overhead) + RSLOP)
/*
+ * Big allocations are often of the size 2^n bytes. To make them a
+ * little bit better, make blocks of size 2^n+pagesize for big n.
+ */
+
+#ifdef TWO_POT_OPTIMIZE
+
+# define PERL_PAGESIZE 4096
+# define FIRST_BIG_TWO_POT 14 /* 16K */
+# define FIRST_BIG_BLOCK (1<<FIRST_BIG_TWO_POT) /* 16K */
+/* If this value or more, check against bigger blocks. */
+# define FIRST_BIG_BOUND (FIRST_BIG_BLOCK - M_OVERHEAD)
+/* If less than this value, goes into 2^n-overhead-block. */
+# define LAST_SMALL_BOUND ((FIRST_BIG_BLOCK>>1) - M_OVERHEAD)
+
+#endif /* TWO_POT_OPTIMIZE */
+
+#ifdef PERL_EMERGENCY_SBRK
+
+#ifndef BIG_SIZE
+# define BIG_SIZE (1<<16) /* 64K */
+#endif
+
+static char *emergency_buffer;
+static MEM_SIZE emergency_buffer_size;
+
+static char *
+emergency_sbrk(size)
+ MEM_SIZE size;
+{
+ if (size >= BIG_SIZE) {
+ /* Give the possibility to recover: */
+ die("Out of memory during request for %i bytes", size);
+ /* croak may eat too much memory. */
+ }
+
+ if (!emergency_buffer) {
+ /* First offense, give a possibility to recover by dieing. */
+ /* No malloc involved here: */
+ GV **gvp = (GV**)hv_fetch(defstash, "^M", 2, 0);
+ SV *sv;
+ char *pv;
+
+ if (!gvp) gvp = (GV**)hv_fetch(defstash, "\015", 1, 0);
+ if (!gvp || !(sv = GvSV(*gvp)) || !SvPOK(sv)
+ || (SvLEN(sv) < (1<<11) - M_OVERHEAD))
+ return (char *)-1; /* Now die die die... */
+
+ /* Got it, now detach SvPV: */
+ pv = SvPV(sv);
+ /* Check alignment: */
+ if ((pv - M_OVERHEAD) & (1<<11 - 1)) {
+ PerlIO_puts(PerlIO_stderr(),"Bad alignment of $^M!\n");
+ return -1; /* die die die */
+ }
+
+ emergency_buffer = pv - M_OVERHEAD;
+ emergency_buffer_size = SvLEN(sv) + M_OVERHEAD;
+ SvPOK_off(sv);
+ SvREADONLY_on(sv);
+ die("Out of memory!"); /* croak may eat too much memory. */
+ } else if (emergency_buffer_size >= size) {
+ emergency_buffer_size -= size;
+ return emergency_buffer + emergency_buffer_size;
+ }
+
+ return (char *)-1; /* poor guy... */
+}
+
+#else /* !PERL_EMERGENCY_SBRK */
+# define emergency_sbrk(size) -1
+#endif /* !PERL_EMERGENCY_SBRK */
+
+/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
@@ -188,22 +261,22 @@ malloc(nbytes)
register int bucket = 0;
register MEM_SIZE shiftr;
-#ifdef safemalloc
+#ifdef PERL_CORE
#ifdef DEBUGGING
MEM_SIZE size = nbytes;
#endif
-#ifdef MSDOS
+#ifdef HAS_64K_LIMIT
if (nbytes > 0xffff) {
PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", (long)nbytes);
my_exit(1);
}
-#endif /* MSDOS */
+#endif /* HAS_64K_LIMIT */
#ifdef DEBUGGING
if ((long)nbytes < 0)
croak("panic: malloc");
#endif
-#endif /* safemalloc */
+#endif /* PERL_CORE */
/*
* Convert amount of memory requested into
@@ -214,6 +287,11 @@ malloc(nbytes)
#ifdef PACK_MALLOC
if (nbytes > MAX_2_POT_ALGO) {
#endif
+#ifdef TWO_POT_OPTIMIZE
+ if (nbytes >= FIRST_BIG_BOUND) {
+ nbytes -= PERL_PAGESIZE;
+ }
+#endif
nbytes += M_OVERHEAD;
nbytes = (nbytes + 3) &~ 3;
#ifdef PACK_MALLOC
@@ -232,7 +310,7 @@ malloc(nbytes)
if (nextf[bucket] == NULL)
morecore(bucket);
if ((p = (union overhead *)nextf[bucket]) == NULL) {
-#ifdef safemalloc
+#ifdef PERL_CORE
if (!nomemok) {
PerlIO_puts(PerlIO_stderr(),"Out of memory!\n");
my_exit(1);
@@ -242,10 +320,10 @@ malloc(nbytes)
#endif
}
-#ifdef safemalloc
+#ifdef PERL_CORE
DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",
(unsigned long)(p+1),an++,(long)size));
-#endif /* safemalloc */
+#endif /* PERL_CORE */
/* remove from linked list */
#ifdef RCHECK
@@ -289,6 +367,9 @@ morecore(bucket)
if (nextf[bucket])
return;
+ if (bucket == (sizeof(MEM_SIZE)*8 - 3)) {
+ croak("Allocation too large");
+ }
/*
* Insure memory is allocated
* on a page boundary. Should
@@ -323,9 +404,16 @@ morecore(bucket)
nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */
/* if (rnu < bucket)
rnu = bucket; Why anyone needs this? */
+#ifdef TWO_POT_OPTIMIZE
+ op = (union overhead *)sbrk((1L << rnu)
+ + ( bucket >= (FIRST_BIG_TWO_POT - 3)
+ ? PERL_PAGESIZE : 0));
+#else
op = (union overhead *)sbrk(1L << rnu);
+#endif
/* no more room! */
- if ((int)op == -1)
+ if ((int)op == -1 &&
+ (int)(op = (union overhead *)emergency_sbrk(size)) == -1)
return;
/*
* Round up to minimum allocation size boundary
@@ -390,9 +478,9 @@ free(mp)
u_char bucket;
#endif
-#ifdef safemalloc
+#ifdef PERL_CORE
DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",(unsigned long)cp,an++));
-#endif /* safemalloc */
+#endif /* PERL_CORE */
if (cp == NULL)
return;
@@ -461,30 +549,30 @@ realloc(mp, nbytes)
int was_alloced = 0;
char *cp = (char*)mp;
-#ifdef safemalloc
+#ifdef PERL_CORE
#ifdef DEBUGGING
MEM_SIZE size = nbytes;
#endif
-#ifdef MSDOS
+#ifdef HAS_64K_LIMIT
if (nbytes > 0xffff) {
PerlIO_printf(PerlIO_stderr(), "Reallocation too large: %lx\n", size);
my_exit(1);
}
-#endif /* MSDOS */
+#endif /* HAS_64K_LIMIT */
if (!cp)
return malloc(nbytes);
#ifdef DEBUGGING
if ((long)nbytes < 0)
croak("panic: realloc");
#endif
-#endif /* safemalloc */
+#endif /* PERL_CORE */
op = (union overhead *)((caddr_t)cp
- sizeof (union overhead) * CHUNK_SHIFT);
i = OV_INDEX(op);
if (OV_MAGIC(op, i) == MAGIC) {
- was_alloced++;
+ was_alloced = 1;
} else {
/*
* Already free, doing "compaction".
@@ -507,10 +595,24 @@ realloc(mp, nbytes)
#else
M_OVERHEAD
#endif
+#ifdef TWO_POT_OPTIMIZE
+ + (i >= (FIRST_BIG_TWO_POT - 3) ? PERL_PAGESIZE : 0)
+#endif
;
- /* avoid the copy if same size block */
+ /*
+ * avoid the copy if same size block.
+ * We are not agressive with boundary cases. Note that it is
+ * possible for small number of cases give false negative if
+ * both new size and old one are in the bucket for
+ * FIRST_BIG_TWO_POT, but the new one is near the lower end.
+ */
if (was_alloced &&
- nbytes <= onb && nbytes > (onb >> 1) - M_OVERHEAD) {
+ nbytes <= onb && (nbytes > ( (onb >> 1) - M_OVERHEAD )
+#ifdef TWO_POT_OPTIMIZE
+ || (i == (FIRST_BIG_TWO_POT - 3)
+ && nbytes >= LAST_SMALL_BOUND )
+#endif
+ )) {
#ifdef RCHECK
/*
* Record new allocated size of block and
@@ -540,7 +642,7 @@ realloc(mp, nbytes)
free(cp);
}
-#ifdef safemalloc
+#ifdef PERL_CORE
#ifdef DEBUGGING
if (debug & 128) {
PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05d) rfree\n",(unsigned long)res,an++);
@@ -548,7 +650,7 @@ realloc(mp, nbytes)
(unsigned long)res,an++,(long)size);
}
#endif
-#endif /* safemalloc */
+#endif /* PERL_CORE */
return ((Malloc_t)res);
}
@@ -681,7 +783,7 @@ int size;
int small, reqsize;
if (!size) return 0;
-#ifdef safemalloc
+#ifdef PERL_CORE
reqsize = size; /* just for the DEBUG_m statement */
#endif
if (size <= Perl_sbrk_oldsize) {
@@ -692,7 +794,7 @@ int size;
if (size >= PERLSBRK_32_K) {
small = 0;
} else {
-#ifndef safemalloc
+#ifndef PERL_CORE
reqsize = size;
#endif
size = PERLSBRK_64_K;
@@ -706,7 +808,7 @@ int size;
}
}
-#ifdef safemalloc
+#ifdef PERL_CORE
DEBUG_m(PerlIO_printf(PerlIO_stderr(), "sbrk malloc size %ld (reqsize %ld), left size %ld, give addr 0x%lx\n",
size, reqsize, Perl_sbrk_oldsize, got));
#endif