From: Nicholas Clark Date: Mon, 18 May 2009 15:12:21 +0000 (+0100) Subject: Add S_sv_dup_inc_multiple(), used in place of loops that call sv_dup_inc(). X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=538f2e763fb7d8e8be3faeafc31371e06e22ce2b;p=p5sagit%2Fp5-mst-13.2.git Add S_sv_dup_inc_multiple(), used in place of loops that call sv_dup_inc(). Just 4 uses already give a size saving with gcc -Os. --- diff --git a/embed.fnc b/embed.fnc index 6cda6ce..5f02822 100644 --- a/embed.fnc +++ b/embed.fnc @@ -1290,6 +1290,10 @@ Ap |PerlIO*|fp_dup |NULLOK PerlIO *const fp|const char type|NN CLONE_PARAMS *co ApR |DIR* |dirp_dup |NULLOK DIR *const dp ApR |GP* |gp_dup |NULLOK GP *const gp|NN CLONE_PARAMS *const param ApR |MAGIC* |mg_dup |NULLOK MAGIC *mg|NN CLONE_PARAMS *const param +#if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) +s |SV ** |sv_dup_inc_multiple|NN SV *const *source|NN SV **dest \ + |SSize_t items|NN CLONE_PARAMS *const param +#endif ApR |SV* |sv_dup |NULLOK const SV *const sstr|NN CLONE_PARAMS *const param Ap |void |rvpv_dup |NN SV *const dstr|NN const SV *const sstr|NN CLONE_PARAMS *const param Ap |yy_parser*|parser_dup |NULLOK const yy_parser *const proto|NN CLONE_PARAMS *const param diff --git a/embed.h b/embed.h index 605cf22..e320dc5 100644 --- a/embed.h +++ b/embed.h @@ -1125,6 +1125,11 @@ #define dirp_dup Perl_dirp_dup #define gp_dup Perl_gp_dup #define mg_dup Perl_mg_dup +#if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) +#ifdef PERL_CORE +#define sv_dup_inc_multiple S_sv_dup_inc_multiple +#endif +#endif #define sv_dup Perl_sv_dup #define rvpv_dup Perl_rvpv_dup #define parser_dup Perl_parser_dup @@ -3454,6 +3459,11 @@ #define dirp_dup(a) Perl_dirp_dup(aTHX_ a) #define gp_dup(a,b) Perl_gp_dup(aTHX_ a,b) #define mg_dup(a,b) Perl_mg_dup(aTHX_ a,b) +#if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) +#ifdef PERL_CORE +#define sv_dup_inc_multiple(a,b,c,d) S_sv_dup_inc_multiple(aTHX_ a,b,c,d) +#endif +#endif #define sv_dup(a,b) Perl_sv_dup(aTHX_ a,b) #define rvpv_dup(a,b,c) Perl_rvpv_dup(aTHX_ a,b,c) #define parser_dup(a,b) Perl_parser_dup(aTHX_ a,b) diff --git a/proto.h b/proto.h index 8e177f0..3f95eb5 100644 --- a/proto.h +++ b/proto.h @@ -4089,6 +4089,15 @@ PERL_CALLCONV MAGIC* Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) #define PERL_ARGS_ASSERT_MG_DUP \ assert(param) +#if defined(PERL_IN_SV_C) || defined(PERL_DECL_PROT) +STATIC SV ** S_sv_dup_inc_multiple(pTHX_ SV *const *source, SV **dest, SSize_t items, CLONE_PARAMS *const param) + __attribute__nonnull__(pTHX_1) + __attribute__nonnull__(pTHX_2) + __attribute__nonnull__(pTHX_4); +#define PERL_ARGS_ASSERT_SV_DUP_INC_MULTIPLE \ + assert(source); assert(dest); assert(param) + +#endif PERL_CALLCONV SV* Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) __attribute__warn_unused_result__ __attribute__nonnull__(pTHX_2); diff --git a/sv.c b/sv.c index 9c38fce..c7468ec 100644 --- a/sv.c +++ b/sv.c @@ -10297,7 +10297,8 @@ ptr_table_* functions. /* Certain cases in Perl_ss_dup have been merged, by relying on the fact that currently av_dup, gv_dup and hv_dup are the same as sv_dup. - If this changes, please unmerge ss_dup. */ + If this changes, please unmerge ss_dup. + Likewise, sv_dup_inc_multiple() relies on this fact. */ #define sv_dup_inc(s,t) SvREFCNT_inc(sv_dup(s,t)) #define sv_dup_inc_NN(s,t) SvREFCNT_inc_NN(sv_dup(s,t)) #define av_dup(s,t) MUTABLE_AV(sv_dup((const SV *)s,t)) @@ -10552,10 +10553,8 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) AMT_AMAGIC((AMT*)nmg->mg_ptr)) { AMT * const namtp = (AMT*)nmg->mg_ptr; - I32 i; - for (i = 1; i < NofAMmeth; i++) { - namtp->table[i] = cv_dup_inc(namtp->table[i], param); - } + sv_dup_inc_multiple((SV**)(namtp->table), + (SV**)(namtp->table), NofAMmeth, param); } } else if (nmg->mg_len == HEf_SVKEY) @@ -10771,6 +10770,20 @@ Perl_rvpv_dup(pTHX_ SV *const dstr, const SV *const sstr, CLONE_PARAMS *const pa } } +/* duplicate a list of SVs. source and dest may point to the same memory. */ +static SV ** +S_sv_dup_inc_multiple(pTHX_ SV *const *source, SV **dest, + SSize_t items, CLONE_PARAMS *const param) +{ + PERL_ARGS_ASSERT_SV_DUP_INC_MULTIPLE; + + while (items-- > 0) { + *dest++ = sv_dup_inc(*source++, param); + } + + return dest; +} + /* duplicate an SV of any type (including AV, HV etc) */ SV * @@ -10994,8 +11007,8 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) AvARRAY(MUTABLE_AV(dstr)) = dst_ary; AvALLOC((const AV *)dstr) = dst_ary; if (AvREAL((const AV *)sstr)) { - while (items-- > 0) - *dst_ary++ = sv_dup_inc(*src_ary++, param); + dst_ary = sv_dup_inc_multiple(src_ary, dst_ary, items, + param); } else { while (items-- > 0) @@ -12175,10 +12188,10 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, if (proto_perl->Ipsig_ptr) { Newx(PL_psig_ptr, SIG_SIZE, SV*); Newx(PL_psig_name, SIG_SIZE, SV*); - for (i = 1; i < SIG_SIZE; i++) { - PL_psig_ptr[i] = sv_dup_inc(proto_perl->Ipsig_ptr[i], param); - PL_psig_name[i] = sv_dup_inc(proto_perl->Ipsig_name[i], param); - } + sv_dup_inc_multiple(proto_perl->Ipsig_ptr, PL_psig_ptr, SIG_SIZE, + param); + sv_dup_inc_multiple(proto_perl->Ipsig_name, PL_psig_name, SIG_SIZE, + param); } else { PL_psig_ptr = (SV**)NULL;