Round up all string length requests to malloc()/realloc() to the next
Nicholas Clark [Wed, 1 Jun 2005 20:46:02 +0000 (20:46 +0000)]
multiple of 4/8 bytes [sizeof(size_t)] on the assumption that malloc()
internally will quantise, and so we're going to use space that
otherwise would be wasted. Hopefully this will save realloc()ing.

p4raw-id: //depot/perl@24665

ext/Devel/Peek/t/Peek.t
handy.h
perl.h
sv.c

index c59b9f5..d4b9c06 100644 (file)
@@ -400,7 +400,7 @@ do_test(20,
   NV = 0
   PV = $ADDR ""\\\0
   CUR = 0
-  LEN = 1
+  LEN = \d+
   MAGIC = $ADDR
     MG_VIRTUAL = &PL_vtbl_mglob
     MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
diff --git a/handy.h b/handy.h
index 067999a..da4ea66 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -605,6 +605,8 @@ hopefully catches attempts to access uninitialized memory.
        (void)((n)>((MEM_SIZE)~0)/sizeof(t)?(Perl_croak_nocontext(a,b),0):0)
 #define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
 
+#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > (MEM_SIZE)~0 - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (Perl_croak_nocontext(PL_memory_wrap),0):0),((n)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1))+PERL_STRLEN_ROUNDUP_QUANTUM)
+
 #else
 
 #define MEM_WRAP_CHECK(n,t)
@@ -612,8 +614,9 @@ hopefully catches attempts to access uninitialized memory.
 #define MEM_WRAP_CHECK_2(n,t,a,b)
 #define MEM_WRAP_CHECK_(n,t)
 
-#endif
+#define PERL_STRLEN_ROUNDUP(n) (((n)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1))+PERL_STRLEN_ROUNDUP_QUANTUM)
 
+#endif
 
 #define New(x,v,n,t)   (v = (MEM_WRAP_CHECK_(n,t) (t*)safemalloc((MEM_SIZE)((n)*sizeof(t)))))
 #define Newc(x,v,n,t,c)        (v = (MEM_WRAP_CHECK_(n,t) (c*)safemalloc((MEM_SIZE)((n)*sizeof(t)))))
diff --git a/perl.h b/perl.h
index bfa632f..aedc918 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -803,6 +803,13 @@ int usleep(unsigned int);
 
 #define MEM_SIZE Size_t
 
+/* Round all values passed to malloc up, by default to a multiple of
+   sizeof(size_t)
+*/
+#ifndef PERL_STRLEN_ROUNDUP_QUANTUM
+#define PERL_STRLEN_ROUNDUP_QUANTUM Size_t_size
+#endif
+
 #if defined(STANDARD_C) && defined(I_STDDEF)
 #   include <stddef.h>
 #   define STRUCT_OFFSET(s,m)  offsetof(s,m)
diff --git a/sv.c b/sv.c
index 30aa440..42320dd 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2038,6 +2038,7 @@ Perl_sv_grow(pTHX_ register SV *sv, register STRLEN newlen)
 
     if (newlen > SvLEN(sv)) {          /* need more room? */
        if (SvLEN(sv) && s) {
+           newlen = PERL_STRLEN_ROUNDUP(newlen);
 #ifdef MYMALLOC
            const STRLEN l = malloced_size((void*)SvPVX(sv));
            if (newlen <= l) {
@@ -2045,10 +2046,11 @@ Perl_sv_grow(pTHX_ register SV *sv, register STRLEN newlen)
                return s;
            } else
 #endif
-           Renew(s,newlen,char);
+           s = saferealloc(s, newlen);
        }
        else {
-           New(703, s, newlen, char);
+           newlen = PERL_STRLEN_ROUNDUP(newlen);
+           s = safemalloc(newlen);
            if (SvPVX(sv) && SvCUR(sv)) {
                Move(SvPVX(sv), s, (newlen < SvCUR(sv)) ? newlen : SvCUR(sv), char);
            }
@@ -4809,6 +4811,7 @@ See C<sv_usepvn_mg>.
 void
 Perl_sv_usepvn(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
 {
+    STRLEN allocate;
     SV_CHECK_THINKFIRST_COW_DROP(sv);
     (void)SvUPGRADE(sv, SVt_PV);
     if (!ptr) {
@@ -4817,10 +4820,12 @@ Perl_sv_usepvn(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
     }
     if (SvPVX(sv))
        SvPV_free(sv);
-    Renew(ptr, len+1, char);
+
+    allocate = PERL_STRLEN_ROUNDUP(len + 1);
+    ptr = safesysrealloc (ptr, allocate);
     SvPV_set(sv, ptr);
     SvCUR_set(sv, len);
-    SvLEN_set(sv, len+1);
+    SvLEN_set(sv, allocate);
     *SvEND(sv) = '\0';
     (void)SvPOK_only_UTF8(sv);         /* validate pointer */
     SvTAINT(sv);