From 4a9a56a75c57646b348598f90875415e994d2f65 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Tue, 4 Dec 2012 11:32:39 +0000 Subject: [PATCH] add SvREFCNT_dec_NN() Like SvREFCNT_dec(), but skips the not null check, making code potentially smaller and faster. Also as proof of concept, updates the SvREFCNT_dec's in scope.c where it's obvious the value can't be NULL. There are still 500+ uses in the perl core that need evaluating! --- inline.h | 10 ++++++++++ scope.c | 12 ++++++------ sv.h | 6 ++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/inline.h b/inline.h index 5e11b69..776a304 100644 --- a/inline.h +++ b/inline.h @@ -64,6 +64,16 @@ S_SvREFCNT_dec(pTHX_ SV *sv) } PERL_STATIC_INLINE void +S_SvREFCNT_dec_NN(pTHX_ SV *sv) +{ + U32 rc = SvREFCNT(sv); + if (rc > 1) + SvREFCNT(sv) = rc - 1; + else + Perl_sv_free2(aTHX_ sv, rc); +} + +PERL_STATIC_INLINE void SvAMAGIC_on(SV *sv) { assert(SvROK(sv)); diff --git a/scope.c b/scope.c index 67fce5c..ab09eff 100644 --- a/scope.c +++ b/scope.c @@ -166,7 +166,7 @@ Perl_free_tmps(pTHX) #endif if (sv && sv != &PL_sv_undef) { SvTEMP_off(sv); - SvREFCNT_dec(sv); /* note, can modify tmps_ix!!! */ + SvREFCNT_dec_NN(sv); /* note, can modify tmps_ix!!! */ } } } @@ -837,7 +837,7 @@ Perl_leave_scope(pTHX_ I32 base) mg_set(ARG0_SV); PL_localizing = 0; } - SvREFCNT_dec(ARG0_SV); + SvREFCNT_dec_NN(ARG0_SV); SvREFCNT_dec(refsv); break; } @@ -895,7 +895,7 @@ Perl_leave_scope(pTHX_ I32 base) mg_set(ARG0_SV); PL_localizing = 0; } - SvREFCNT_dec(ARG1_GV); + SvREFCNT_dec_NN(ARG1_GV); break; case SAVEt_HV: /* hash reference */ SvREFCNT_dec(GvHV(ARG1_GV)); @@ -905,7 +905,7 @@ Perl_leave_scope(pTHX_ I32 base) mg_set(ARG0_SV); PL_localizing = 0; } - SvREFCNT_dec(ARG1_GV); + SvREFCNT_dec_NN(ARG1_GV); break; case SAVEt_INT_SMALL: *(int*)ARG0_PTR = (int)(uv >> SAVE_TIGHT_SHIFT); @@ -964,7 +964,7 @@ Perl_leave_scope(pTHX_ I32 base) /* putting a method back into circulation ("local")*/ gv_method_changed(ARG1_GV); } - SvREFCNT_dec(ARG1_GV); + SvREFCNT_dec_NN(ARG1_GV); break; } case SAVEt_FREESV: @@ -1073,7 +1073,7 @@ Perl_leave_scope(pTHX_ I32 base) } default: *svp = newSV(0); break; } - SvREFCNT_dec(sv); /* Cast current value to the winds. */ + SvREFCNT_dec_NN(sv); /* Cast current value to the winds. */ /* preserve pad nature, but also mark as not live * for any closure capturing */ SvFLAGS(*svp) |= (SVs_PADMY|SVs_PADSTALE); diff --git a/sv.h b/sv.h index cb5ac62..2576a65 100644 --- a/sv.h +++ b/sv.h @@ -286,6 +286,11 @@ and faster. =for apidoc Am|void|SvREFCNT_dec|SV* sv Decrements the reference count of the given SV. +=for apidoc Am|void|SvREFCNT_dec_NN|SV* sv +Same as SvREFCNT_dec, but can only be used if you know I +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + =for apidoc Am|svtype|SvTYPE|SV* sv Returns the type of the SV. See C. @@ -312,6 +317,7 @@ perform the upgrade if necessary. See C. #define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT(MUTABLE_SV(sv))) #define SvREFCNT_dec(sv) S_SvREFCNT_dec(aTHX_ MUTABLE_SV(sv)) +#define SvREFCNT_dec_NN(sv) S_SvREFCNT_dec_NN(aTHX_ MUTABLE_SV(sv)) #define SVTYPEMASK 0xff #define SvTYPE(sv) ((svtype)((sv)->sv_flags & SVTYPEMASK)) -- 1.8.3.1