From e90e236463307bd7f53439b91573fe42e9cb8901 Mon Sep 17 00:00:00 2001 From: Nicholas Clark Date: Fri, 16 Jul 2004 11:04:37 +0000 Subject: [PATCH] Encourage compilers to tail call optimise in sv_savepv, sv_savepvn and sv_savesharedpv. Need to create non-void returning versions of Copy and Zero, as the existing macros deliberately cast to (void) p4raw-id: //depot/perl@23126 --- handy.h | 34 ++++++++++++++++++++++++++++++++++ malloc.c | 4 ++-- perl.c | 3 +-- pod/perlapi.pod | 30 ++++++++++++++++++++++++++++++ sv.c | 3 +-- util.c | 40 ++++++++++++++++++++-------------------- 6 files changed, 88 insertions(+), 26 deletions(-) diff --git a/handy.h b/handy.h index 19a5934..e5c7c45 100644 --- a/handy.h +++ b/handy.h @@ -559,16 +559,30 @@ The XSUB-writer's interface to the C C function. The C is the source, C is the destination, C is the number of items, and C is the type. Can do overlapping moves. See also C. +=for apidoc Am|void *|MoveD|void* src|void* dest|int nitems|type +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + =for apidoc Am|void|Copy|void* src|void* dest|int nitems|type The XSUB-writer's interface to the C C function. The C is the source, C is the destination, C is the number of items, and C is the type. May fail on overlapping copies. See also C. +=for apidoc Am|void *|CopyD|void* src|void* dest|int nitems|type + +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + =for apidoc Am|void|Zero|void* dest|int nitems|type The XSUB-writer's interface to the C C function. The C is the destination, C is the number of items, and C is the type. +=for apidoc Am|void *|ZeroD|void* dest|int nitems|type + +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + =for apidoc Am|void|StructCopy|type src|type dest|type This is an architecture-independent macro to copy one structure to another. @@ -605,6 +619,15 @@ hopefully catches attempts to access uninitialized memory. #define Copy(s,d,n,t) (MEM_WRAP_CHECK(n,t), (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t))) #define Zero(d,n,t) (MEM_WRAP_CHECK(n,t), (void)memzero((char*)(d), (n) * sizeof(t))) +#define MoveD(s,d,n,t) (MEM_WRAP_CHECK(n,t), memmove((char*)(d),(char*)(s), (n) * sizeof(t))) +#define CopyD(s,d,n,t) (MEM_WRAP_CHECK(n,t), memcpy((char*)(d),(char*)(s), (n) * sizeof(t))) +#ifdef HAS_MEMSET +#define ZeroD(d,n,t) (MEM_WRAP_CHECK(n,t), memzero((char*)(d), (n) * sizeof(t))) +#else +/* Using bzero(), which returns void. */ +#define ZeroD(d,n,t) (MEM_WRAP_CHECK(n,t), memzero((char*)(d), (n) * sizeof(t)),d) +#endif + #define Poison(d,n,t) (MEM_WRAP_CHECK(n,t), (void)memset((char*)(d), 0xAB, (n) * sizeof(t))) #else @@ -627,6 +650,14 @@ hopefully catches attempts to access uninitialized memory. #define Copy(s,d,n,t) (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) #define Zero(d,n,t) (void)memzero((char*)(d), (n) * sizeof(t)) +#define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) +#define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) +#ifdef HAS_MEMSET +#define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) +#else +#define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)),d) +#endif + #define Poison(d,n,t) (void)memset((char*)(d), 0xAB, (n) * sizeof(t)) #endif @@ -640,6 +671,9 @@ hopefully catches attempts to access uninitialized memory. #define Move(s,d,n,t) #define Copy(s,d,n,t) #define Zero(d,n,t) +#define MoveD(s,d,n,t) d +#define CopyD(s,d,n,t) d +#define ZeroD(d,n,t) d #define Poison(d,n,t) #define Safefree(d) (d) = (d) diff --git a/malloc.c b/malloc.c index 6013e40..e5f58e4 100644 --- a/malloc.c +++ b/malloc.c @@ -357,6 +357,7 @@ # 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 @@ -2311,8 +2312,7 @@ Perl_strdup(const char *s) 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 diff --git a/perl.c b/perl.c index f387cf1..7eb121e 100644 --- a/perl.c +++ b/perl.c @@ -190,8 +190,7 @@ perl_alloc(void) my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter)); INIT_TLS_AND_INTERP; - Zero(my_perl, 1, PerlInterpreter); - return my_perl; + return ZeroD(my_perl, 1, PerlInterpreter); } #endif /* PERL_IMPLICIT_SYS */ diff --git a/pod/perlapi.pod b/pod/perlapi.pod index 512ee44..fb22429 100644 --- a/pod/perlapi.pod +++ b/pod/perlapi.pod @@ -1554,6 +1554,16 @@ the type. May fail on overlapping copies. See also C. =for hackers Found in file handy.h +=item CopyD + +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + + void * CopyD(void* src, void* dest, int nitems, type) + +=for hackers +Found in file handy.h + =item Move The XSUB-writer's interface to the C C function. The C is the @@ -1565,6 +1575,16 @@ the type. Can do overlapping moves. See also C. =for hackers Found in file handy.h +=item MoveD + +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + + void * MoveD(void* src, void* dest, int nitems, type) + +=for hackers +Found in file handy.h + =item New The XSUB-writer's interface to the C C function. @@ -1685,6 +1705,16 @@ destination, C is the number of items, and C is the type. =for hackers Found in file handy.h +=item ZeroD + +Like C but returns dest. Useful for encouraging compilers to tail-call +optimise. + + void * ZeroD(void* dest, int nitems, type) + +=for hackers +Found in file handy.h + =back diff --git a/sv.c b/sv.c index 50501e7..9079315 100644 --- a/sv.c +++ b/sv.c @@ -3742,9 +3742,8 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags) *lp = len; s = SvGROW(sv, len + 1); SvCUR_set(sv, len); - (void)strcpy(s, t); SvPOKp_on(sv); - return s; + return strcpy(s, t); } } diff --git a/util.c b/util.c index 030c706..b3375de 100644 --- a/util.c +++ b/util.c @@ -751,12 +751,12 @@ be freed with the C function. char * Perl_savepv(pTHX_ const char *pv) { - register char *newaddr = Nullch; - if (pv) { - New(902,newaddr,strlen(pv)+1,char); - (void)strcpy(newaddr,pv); - } - return newaddr; + register char *newaddr; + if (!pv) + return Nullch; + + New(902,newaddr,strlen(pv)+1,char); + return strcpy(newaddr,pv); } /* same thing but with a known length */ @@ -780,13 +780,13 @@ Perl_savepvn(pTHX_ const char *pv, register I32 len) New(903,newaddr,len+1,char); /* Give a meaning to NULL pointer mainly for the use in sv_magic() */ if (pv) { - Copy(pv,newaddr,len,char); /* might not be null terminated */ - newaddr[len] = '\0'; /* is now */ + /* might not be null terminated */ + newaddr[len] = '\0'; + return CopyD(pv,newaddr,len,char); } else { - Zero(newaddr,len+1,char); + return ZeroD(newaddr,len+1,char); } - return newaddr; } /* @@ -800,17 +800,17 @@ which is shared between threads. char * Perl_savesharedpv(pTHX_ const char *pv) { - register char *newaddr = Nullch; - if (pv) { - newaddr = (char*)PerlMemShared_malloc(strlen(pv)+1); - if (!newaddr) { - PerlLIO_write(PerlIO_fileno(Perl_error_log), - PL_no_mem, strlen(PL_no_mem)); - my_exit(1); - } - (void)strcpy(newaddr,pv); + register char *newaddr; + if (!pv) + return Nullch; + + newaddr = (char*)PerlMemShared_malloc(strlen(pv)+1); + if (!newaddr) { + PerlLIO_write(PerlIO_fileno(Perl_error_log), + PL_no_mem, strlen(PL_no_mem)); + my_exit(1); } - return newaddr; + return strcpy(newaddr,pv); } -- 2.7.4