Speedups and shrinkages of SvREFCNT_inc
Andy Lester [Fri, 24 Feb 2006 14:54:35 +0000 (08:54 -0600)]
Message-ID: <20060224205434.GA17867@petdance.com>

p4raw-id: //depot/perl@27334

24 files changed:
av.c
cop.h
doio.c
doop.c
gv.c
hv.c
mg.c
op.c
pad.c
perl.c
perl.h
perlio.c
pod/perlapi.pod
pod/perlintern.pod
pp.c
pp_ctl.c
pp_hot.c
pp_sort.c
pp_sys.c
regcomp.c
scope.c
sv.c
sv.h
toke.c

diff --git a/av.c b/av.c
index ede01a7..423d006 100644 (file)
--- a/av.c
+++ b/av.c
@@ -42,7 +42,7 @@ Perl_av_reify(pTHX_ AV *av)
        SV * const sv = AvARRAY(av)[--key];
        assert(sv);
        if (sv != &PL_sv_undef)
-           (void)SvREFCNT_inc(sv);
+           SvREFCNT_inc_void_NN(sv);
     }
     key = AvARRAY(av) - AvALLOC(av);
     while (key)
diff --git a/cop.h b/cop.h
index 9296464..ef92d8e 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -254,8 +254,8 @@ struct block_sub {
        cx->blk_sub.hasargs = hasargs;                                  \
        cx->blk_sub.retop = NULL;                                       \
        if (!CvDEPTH(cv)) {                                             \
-           (void)SvREFCNT_inc(cv);                                     \
-           (void)SvREFCNT_inc(cv);                                     \
+           SvREFCNT_inc_void(cv);                                      \
+           SvREFCNT_inc_void(cv);                                      \
            SAVEFREESV(cv);                                             \
        }
 
@@ -277,7 +277,7 @@ struct block_sub {
        cx->blk_sub.retop = NULL;                                       \
        cx->blk_sub.hasargs = 0;                                        \
        cx->blk_sub.dfoutgv = PL_defoutgv;                              \
-       (void)SvREFCNT_inc(cx->blk_sub.dfoutgv)
+       SvREFCNT_inc_void(cx->blk_sub.dfoutgv)
 
 #define POP_SAVEARRAY()                                                \
     STMT_START {                                                       \
diff --git a/doio.c b/doio.c
index 328186a..0e9987d 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -740,7 +740,7 @@ Perl_nextargv(pTHX_ register GV *gv)
        if (PL_inplace) {
            if (!PL_argvout_stack)
                PL_argvout_stack = newAV();
-           av_push(PL_argvout_stack, SvREFCNT_inc(PL_defoutgv));
+           av_push(PL_argvout_stack, SvREFCNT_inc_simple(PL_defoutgv));
        }
     }
     if (PL_filemode & (S_ISUID|S_ISGID)) {
diff --git a/doop.c b/doop.c
index 0e9ddf1..2c1ce81 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -1396,7 +1396,7 @@ Perl_do_kv(pTHX)
            if (LvTARG(TARG) != (SV*)keys) {
                if (LvTARG(TARG))
                    SvREFCNT_dec(LvTARG(TARG));
-               LvTARG(TARG) = SvREFCNT_inc(keys);
+               LvTARG(TARG) = SvREFCNT_inc_simple(keys);
            }
            PUSHs(TARG);
            RETURN;
diff --git a/gv.c b/gv.c
index be5aeb7..2bbb97b 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -80,7 +80,8 @@ Perl_gv_IOadd(pTHX_ register GV *gv)
          * if it walks like a dirhandle, then let's assume that
          * this is a dirhandle.
          */
-        const char *fh = PL_op->op_type == OP_READDIR ||
+       const char * const fh =
+                        PL_op->op_type ==  OP_READDIR ||
                          PL_op->op_type ==  OP_TELLDIR ||
                          PL_op->op_type ==  OP_SEEKDIR ||
                          PL_op->op_type ==  OP_REWINDDIR ||
@@ -351,7 +352,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
                if (SvTYPE(gv) != SVt_PVGV)
                    gv_init(gv, stash, "ISA", 3, TRUE);
                SvREFCNT_dec(GvAV(gv));
-               GvAV(gv) = (AV*)SvREFCNT_inc(av);
+               GvAV(gv) = (AV*)SvREFCNT_inc_simple(av);
            }
        }
     }
@@ -508,7 +509,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
            --nsplit;
        if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) {
            /* ->SUPER::method should really be looked up in original stash */
-           SV *tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER",
+           SV * const tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER",
                                                  CopSTASHPV(PL_curcop)));
            /* __PACKAGE__::SUPER stash should be autovivified */
            stash = gv_stashpvn(SvPVX_const(tmpstr), SvCUR(tmpstr), TRUE);
@@ -1423,7 +1424,7 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg)
        int i;
        for (i = 1; i < NofAMmeth; i++) {
            CV * const cv = amtp->table[i];
-           if (cv != NULL) {
+           if (cv) {
                SvREFCNT_dec((SV *) cv);
                amtp->table[i] = NULL;
            }
@@ -1537,7 +1538,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
            cv = (CV*)gv;
            filled = 1;
        }
-       amt.table[i]=(CV*)SvREFCNT_inc(cv);
+       amt.table[i]=(CV*)SvREFCNT_inc_simple(cv);
     }
     if (filled) {
       AMT_AMAGIC_on(&amt);
@@ -1869,7 +1870,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     CATCH_SET(TRUE);
     Zero(&myop, 1, BINOP);
     myop.op_last = (OP *) &myop;
-    myop.op_next = Nullop;
+    myop.op_next = NULL;
     myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
 
     PUSHSTACKi(PERLSI_OVERLOAD);
@@ -1978,6 +1979,7 @@ pointers returned by SvPV.
 bool
 Perl_is_gv_magical(pTHX_ const char *name, STRLEN len, U32 flags)
 {
+    PERL_UNUSED_CONTEXT;
     PERL_UNUSED_ARG(flags);
 
     if (len > 1) {
diff --git a/hv.c b/hv.c
index 0923f90..1a93d3c 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -2062,7 +2062,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
        magic_nextpack((SV*) hv,mg,key);
        if (SvOK(key)) {
            /* force key to stay around until next time */
-           HeSVKEY_set(entry, SvREFCNT_inc(key));
+           HeSVKEY_set(entry, SvREFCNT_inc_simple_NN(key));
            return entry;               /* beware, hent_val is not set */
        }
        if (HeVAL(entry))
diff --git a/mg.c b/mg.c
index 760517c..8cc9d85 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -152,7 +152,7 @@ Perl_mg_get(pTHX_ SV *sv)
        cause the SV's buffer to get stolen (and maybe other stuff).
        So restore it.
     */
-    sv_2mortal(SvREFCNT_inc(sv));
+    sv_2mortal(SvREFCNT_inc_simple(sv));
     if (!was_temp) {
        SvTEMP_off(sv);
     }
@@ -1188,7 +1188,7 @@ Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
                sv_setpv(sv,"IGNORE");
            else
                sv_setsv(sv,&PL_sv_undef);
-           PL_psig_ptr[i] = SvREFCNT_inc(sv);
+           PL_psig_ptr[i] = SvREFCNT_inc_simple(sv);
            SvTEMP_off(sv);
        }
     }
@@ -1400,7 +1400,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
 #endif
        SvREFCNT_dec(PL_psig_name[i]);
        to_dec = PL_psig_ptr[i];
-       PL_psig_ptr[i] = SvREFCNT_inc(sv);
+       PL_psig_ptr[i] = SvREFCNT_inc_simple(sv);
        SvTEMP_off(sv); /* Make sure it doesn't go away on us */
        PL_psig_name[i] = newSVpvn(s, len);
        SvREADONLY_on(PL_psig_name[i]);
@@ -1413,7 +1413,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
 #endif
        }
        else
-           *svp = SvREFCNT_inc(sv);
+           *svp = SvREFCNT_inc_simple_NN(sv);
        if(to_dec)
            SvREFCNT_dec(to_dec);
        return 0;
@@ -1451,7 +1451,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
        if (i)
            (void)rsignal(i, PL_csighandlerp);
        else
-           *svp = SvREFCNT_inc(sv);
+           *svp = SvREFCNT_inc_simple(sv);
     }
 #ifdef HAS_SIGPROCMASK
     if(i)
@@ -1983,7 +1983,7 @@ Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
        if (targ && targ != &PL_sv_undef) {
            /* somebody else defined it for us */
            SvREFCNT_dec(LvTARG(sv));
-           LvTARG(sv) = SvREFCNT_inc(targ);
+           LvTARG(sv) = SvREFCNT_inc_simple_NN(targ);
            LvTARGLEN(sv) = 0;
            SvREFCNT_dec(mg->mg_obj);
            mg->mg_obj = NULL;
@@ -2036,7 +2036,7 @@ Perl_vivify_defelem(pTHX_ SV *sv)
                Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
        }
     }
-    (void)SvREFCNT_inc(value);
+    SvREFCNT_inc_simple_void(value);
     SvREFCNT_dec(LvTARG(sv));
     LvTARG(sv) = value;
     LvTARGLEN(sv) = 0;
@@ -2666,7 +2666,7 @@ Perl_sighandler(int sig)
     }
 
     if(PL_psig_name[sig]) {
-       sv = SvREFCNT_inc(PL_psig_name[sig]);
+       sv = SvREFCNT_inc_NN(PL_psig_name[sig]);
        flags |= 64;
 #if !defined(PERL_IMPLICIT_CONTEXT)
        PL_sig_sv = sv;
diff --git a/op.c b/op.c
index 70a2acf..a63b6ae 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1546,7 +1546,7 @@ S_dup_attrlist(pTHX_ OP *o)
      * are OP_CONST.  We need to push the OP_CONST values.
      */
     if (o->op_type == OP_CONST)
-       rop = newSVOP(OP_CONST, o->op_flags, SvREFCNT_inc(cSVOPo->op_sv));
+       rop = newSVOP(OP_CONST, o->op_flags, SvREFCNT_inc_NN(cSVOPo->op_sv));
     else {
        assert((o->op_type == OP_LIST) && (o->op_flags & OPf_KIDS));
        rop = NULL;
@@ -1554,7 +1554,7 @@ S_dup_attrlist(pTHX_ OP *o)
            if (o->op_type == OP_CONST)
                rop = append_elem(OP_LIST, rop,
                                  newSVOP(OP_CONST, o->op_flags,
-                                         SvREFCNT_inc(cSVOPo->op_sv)));
+                                         SvREFCNT_inc_NN(cSVOPo->op_sv)));
        }
     }
     return rop;
@@ -2124,7 +2124,7 @@ Perl_fold_constants(pTHX_ register OP *o)
     if (o->op_targ && sv == PAD_SV(o->op_targ))        /* grab pad temp? */
        pad_swipe(o->op_targ,  FALSE);
     else if (SvTEMP(sv)) {                     /* grab mortal temp? */
-       (void)SvREFCNT_inc(sv);
+       SvREFCNT_inc_simple_void(sv);
        SvTEMP_off(sv);
     }
     op_free(o);
@@ -2162,7 +2162,7 @@ Perl_gen_constant_list(pTHX_ register OP *o)
     o->op_flags |= OPf_PARENS; /* and flatten \(1..2,3) */
     o->op_opt = 0;             /* needs to be revisited in peep() */
     curop = ((UNOP*)o)->op_first;
-    ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, SvREFCNT_inc(*PL_stack_sp--));
+    ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(*PL_stack_sp--));
     op_free(curop);
     linklist(o);
     return list(o);
@@ -2629,8 +2629,7 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
        Safefree(cPVOPo->op_pv);
        cSVOPo->op_sv = (SV*)swash_init("utf8", "", listsv, bits, none);
        SvREFCNT_dec(listsv);
-       if (transv)
-           SvREFCNT_dec(transv);
+       SvREFCNT_dec(transv);
 
        if (!del && havefinal && rlen)
            (void)hv_store((HV*)SvRV((cSVOPo->op_sv)), "FINAL", 5,
@@ -2639,10 +2638,8 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
        if (grows)
            o->op_private |= OPpTRANS_GROWS;
 
-       if (tsave)
-           Safefree(tsave);
-       if (rsave)
-           Safefree(rsave);
+       Safefree(tsave);
+       Safefree(rsave);
 
        op_free(expr);
        op_free(repl);
@@ -2747,7 +2744,7 @@ Perl_newPMOP(pTHX_ I32 type, I32 flags)
        sv_setiv(repointer,0);
     } else {
        SV * const repointer = newSViv(0);
-       av_push(PL_regex_padav,SvREFCNT_inc(repointer));
+       av_push(PL_regex_padav, SvREFCNT_inc_simple_NN(repointer));
        pmop->op_pmoffset = av_len(PL_regex_padav);
        PL_regex_pad = AvARRAY(PL_regex_padav);
     }
@@ -3013,9 +3010,9 @@ Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv)
 #ifdef USE_ITHREADS
     if (gv)
        GvIN_PAD_on(gv);
-    return newPADOP(type, flags, SvREFCNT_inc(gv));
+    return newPADOP(type, flags, SvREFCNT_inc_simple(gv));
 #else
-    return newSVOP(type, flags, SvREFCNT_inc(gv));
+    return newSVOP(type, flags, SvREFCNT_inc_simple(gv));
 #endif
 }
 
@@ -4586,7 +4583,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        }
     }
     if (const_sv) {
-       (void)SvREFCNT_inc(const_sv);
+       SvREFCNT_inc_void_NN(const_sv);
        if (cv) {
            assert(!CvROOT(cv) && !CvCONST(cv));
            sv_setpvn((SV*)cv, "", 0);  /* prototype is "" */
@@ -5508,9 +5505,9 @@ Perl_ck_rvconst(pTHX_ register OP *o)
            kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP);
            SvREFCNT_dec(PAD_SVl(kPADOP->op_padix));
            GvIN_PAD_on(gv);
-           PAD_SETSV(kPADOP->op_padix, (SV*) SvREFCNT_inc(gv));
+           PAD_SETSV(kPADOP->op_padix, (SV*) SvREFCNT_inc_simple_NN(gv));
 #else
-           kid->op_sv = SvREFCNT_inc(gv);
+           kid->op_sv = SvREFCNT_inc_simple_NN(gv);
 #endif
            kid->op_private = 0;
            kid->op_ppaddr = PL_ppaddr[OP_GV];
@@ -5830,7 +5827,7 @@ Perl_ck_glob(pTHX_ OP *o)
        gv = gv_fetchpvs("CORE::GLOBAL::glob", 0, SVt_PVCV);
        glob_gv = gv_fetchpvs("File::Glob::csh_glob", 0, SVt_PVCV);
        GvCV(gv) = GvCV(glob_gv);
-       (void)SvREFCNT_inc((SV*)GvCV(gv));
+       SvREFCNT_inc_void((SV*)GvCV(gv));
        GvIMPORTED_CV_on(gv);
        LEAVE;
     }
diff --git a/pad.c b/pad.c
index 3a35673..10c82c5 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -272,37 +272,35 @@ Perl_pad_undef(pTHX_ CV* cv)
                    SvREFCNT_dec(innercv);
                    inner_rc--;
                }
-               if (inner_rc /* in use, not just a prototype */
-                   && CvOUTSIDE(innercv) == cv)
-               {
+
+               /* in use, not just a prototype */
+               if (inner_rc && (CvOUTSIDE(innercv) == cv)) {
                    assert(CvWEAKOUTSIDE(innercv));
                    /* don't relink to grandfather if he's being freed */
                    if (outercv && SvREFCNT(outercv)) {
                        CvWEAKOUTSIDE_off(innercv);
                        CvOUTSIDE(innercv) = outercv;
                        CvOUTSIDE_SEQ(innercv) = seq;
-                       (void)SvREFCNT_inc(outercv);
+                       SvREFCNT_inc_void_NN(outercv);
                    }
                    else {
                        CvOUTSIDE(innercv) = NULL;
                    }
-
                }
-
            }
        }
     }
 
     ix = AvFILLp(padlist);
     while (ix >= 0) {
-       SV* const sv = AvARRAY(padlist)[ix--];
-       if (!sv)
-           continue;
-       if (sv == (SV*)PL_comppad_name)
-           PL_comppad_name = NULL;
-       else if (sv == (SV*)PL_comppad) {
-           PL_comppad = Null(PAD*);
-           PL_curpad = Null(SV**);
+       const SV* const sv = AvARRAY(padlist)[ix--];
+       if (sv) {
+           if (sv == (SV*)PL_comppad_name)
+               PL_comppad_name = NULL;
+           else if (sv == (SV*)PL_comppad) {
+               PL_comppad = NULL;
+               PL_curpad = NULL;
+           }
        }
        SvREFCNT_dec(sv);
     }
@@ -343,12 +341,12 @@ Perl_pad_add_name(pTHX_ const char *name, HV* typestash, HV* ourstash, bool fake
 
     if (typestash) {
        SvPAD_TYPED_on(namesv);
-       SvSTASH_set(namesv, (HV*)SvREFCNT_inc((SV*) typestash));
+       SvSTASH_set(namesv, (HV*)SvREFCNT_inc_simple_NN((SV*)typestash));
     }
     if (ourstash) {
        SvPAD_OUR_on(namesv);
        OURSTASH_set(namesv, ourstash);
-       SvREFCNT_inc(ourstash);
+       SvREFCNT_inc_void_NN(ourstash);
     }
 
     av_store(PL_comppad_name, offset, namesv);
@@ -1455,7 +1453,7 @@ Perl_cv_clone(pTHX_ CV *proto)
     CvROOT(cv)         = OpREFCNT_inc(CvROOT(proto));
     OP_REFCNT_UNLOCK;
     CvSTART(cv)                = CvSTART(proto);
-    CvOUTSIDE(cv)      = (CV*)SvREFCNT_inc(outside);
+    CvOUTSIDE(cv)      = (CV*)SvREFCNT_inc_simple(outside);
     CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(proto);
 
     if (SvPOK(proto))
@@ -1487,7 +1485,7 @@ Perl_cv_clone(pTHX_ CV *proto)
                }
                else {
                    assert(!SvPADSTALE(sv));
-                   sv = SvREFCNT_inc(sv);
+                   SvREFCNT_inc_simple_void(sv);
                }
            }
            if (!sv) {
@@ -1591,10 +1589,7 @@ void
 Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
 {
     dVAR;
-    if (depth <= AvFILLp(padlist))
-       return;
-
-    {
+    if (depth > AvFILLp(padlist)) {
        SV** const svp = AvARRAY(padlist);
        AV* const newpad = newAV();
        SV** const oldpad = AvARRAY(svp[depth-1]);
diff --git a/perl.c b/perl.c
index d901cd5..7b6b4c7 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -3388,15 +3388,14 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n");
 void
 Perl_my_unexec(pTHX)
 {
+    PERL_UNUSED_CONTEXT;
 #ifdef UNEXEC
-    SV*    prog;
-    SV*    file;
+    SV *    prog = newSVpv(BIN_EXP, 0);
+    SV *    file = newSVpv(PL_origfilename, 0);
     int    status = 1;
     extern int etext;
 
-    prog = newSVpv(BIN_EXP, 0);
     sv_catpvs(prog, "/perl");
-    file = newSVpv(PL_origfilename, 0);
     sv_catpvs(file, ".perldump");
 
     unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0);
@@ -3468,18 +3467,18 @@ S_init_main_stash(pTHX)
        of the SvREFCNT_dec, only to add it again with hv_name_set */
     SvREFCNT_dec(GvHV(gv));
     hv_name_set(PL_defstash, "main", 4, 0);
-    GvHV(gv) = (HV*)SvREFCNT_inc(PL_defstash);
+    GvHV(gv) = (HV*)SvREFCNT_inc_simple(PL_defstash);
     SvREADONLY_on(gv);
     PL_incgv = gv_HVadd(gv_AVadd(gv_fetchpvs("INC", GV_ADD|GV_NOTQUAL,
                                             SVt_PVAV)));
-    SvREFCNT_inc(PL_incgv); /* Don't allow it to be freed */
+    SvREFCNT_inc_simple(PL_incgv); /* Don't allow it to be freed */
     GvMULTI_on(PL_incgv);
     PL_hintgv = gv_fetchpvs("\010", GV_ADD|GV_NOTQUAL, SVt_PV); /* ^H */
     GvMULTI_on(PL_hintgv);
     PL_defgv = gv_fetchpvs("_", GV_ADD|GV_NOTQUAL, SVt_PVAV);
-    SvREFCNT_inc(PL_defgv);
+    SvREFCNT_inc_simple(PL_defgv);
     PL_errgv = gv_HVadd(gv_fetchpvs("@", GV_ADD|GV_NOTQUAL, SVt_PV));
-    SvREFCNT_inc(PL_errgv);
+    SvREFCNT_inc_simple(PL_errgv);
     GvMULTI_on(PL_errgv);
     PL_replgv = gv_fetchpvs("\022", GV_ADD|GV_NOTQUAL, SVt_PV); /* ^R */
     GvMULTI_on(PL_replgv);
@@ -4513,7 +4512,7 @@ S_init_predump_symbols(pTHX)
     IoIFP(io) = PerlIO_stdin();
     tmpgv = gv_fetchpvs("stdin", GV_ADD|GV_NOTQUAL, SVt_PV);
     GvMULTI_on(tmpgv);
-    GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
+    GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io);
 
     tmpgv = gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
     GvMULTI_on(tmpgv);
@@ -4523,7 +4522,7 @@ S_init_predump_symbols(pTHX)
     setdefout(tmpgv);
     tmpgv = gv_fetchpvs("stdout", GV_ADD|GV_NOTQUAL, SVt_PV);
     GvMULTI_on(tmpgv);
-    GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
+    GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io);
 
     PL_stderrgv = gv_fetchpvs("STDERR", GV_ADD|GV_NOTQUAL, SVt_PVIO);
     GvMULTI_on(PL_stderrgv);
@@ -4532,7 +4531,7 @@ S_init_predump_symbols(pTHX)
     IoOFP(io) = IoIFP(io) = PerlIO_stderr();
     tmpgv = gv_fetchpvs("stderr", GV_ADD|GV_NOTQUAL, SVt_PV);
     GvMULTI_on(tmpgv);
-    GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
+    GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io);
 
     PL_statname = newSV(0);            /* last filename we did stat on */
 
diff --git a/perl.h b/perl.h
index 505c122..7d4180d 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -2957,11 +2957,19 @@ typedef pthread_key_t   perl_key;
    appropriate to call return.  In either case, include the lint directive.
  */
 #ifdef HASATTRIBUTE_NORETURN
-#  define NORETURN_FUNCTION_END /* NOT REACHED */
+#  define NORETURN_FUNCTION_END /* NOTREACHED */
 #else
-#  define NORETURN_FUNCTION_END /* NOT REACHED */ return 0
+#  define NORETURN_FUNCTION_END /* NOTREACHED */ return 0
 #endif
 
+#ifdef HASBUILTIN_EXPECT
+#  define EXPECT(expr,val)                  __builtin_expect(expr,val)
+#else
+#  define EXPECT(expr,val)                  (expr)
+#endif
+#define LIKELY(cond)                        EXPECT(cond,1)
+#define UNLIKELY(cond)                      EXPECT(cond,0)
+
 /* Some unistd.h's give a prototype for pause() even though
    HAS_PAUSE ends up undefined.  This causes the #define
    below to be rejected by the compiler.  Sigh.
index 92a2879..2c352f1 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -601,6 +601,8 @@ void
 PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
 {
     dVAR;
+    PERL_UNUSED_CONTEXT;
+
     PerlIO_pair_t *p;
     if (list->cur >= list->len) {
        list->len += 8;
@@ -612,14 +614,14 @@ PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
     p = &(list->array[list->cur++]);
     p->funcs = funcs;
     if ((p->arg = arg)) {
-       (void)SvREFCNT_inc(arg);
+       SvREFCNT_inc_void_NN(arg);
     }
 }
 
 PerlIO_list_t *
 PerlIO_clone_list(pTHX_ PerlIO_list_t *proto, CLONE_PARAMS *param)
 {
-    PerlIO_list_t *list = (PerlIO_list_t *) NULL;
+    PerlIO_list_t *list = NULL;
     if (proto) {
        int i;
        list = PerlIO_list_alloc(aTHX);
@@ -772,8 +774,7 @@ PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
            SAVEINT(PL_in_load_module);
            if (cv) {
                SAVEGENERICSV(PL_warnhook);
-               (void)SvREFCNT_inc(cv);
-               PL_warnhook = (SV *) cv;
+               PL_warnhook = (SV *) (SvREFCNT_inc_simple_NN(cv));
            }
            PL_in_load_module++;
            /*
@@ -856,7 +857,7 @@ XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
        const char * const name = SvPV_const(ST(i), len);
        SV * const layer = PerlIO_find_layer(aTHX_ name, len, 1);
        if (layer) {
-           av_push(av, SvREFCNT_inc(layer));
+           av_push(av, SvREFCNT_inc_simple_NN(layer));
        }
        else {
            ST(count) = ST(i);
@@ -1497,7 +1498,7 @@ PerlIO_resolve_layers(pTHX_ const char *layers,
        }
        else {
            PerlIO_list_free(aTHX_ av);
-           return (PerlIO_list_t *) NULL;
+           return NULL;
        }
     }
     else {
index a9dbc5c..756ffba 100644 (file)
@@ -4129,6 +4129,77 @@ Increments the reference count of the given SV.
 =for hackers
 Found in file sv.h
 
+=item SvREFCNT_inc_NN
+X<SvREFCNT_inc_NN>
+
+Same as SvREFCNT_inc, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+       SV*     SvREFCNT_inc_NN(SV* sv)
+
+=for hackers
+Found in file sv.h
+
+=item SvREFCNT_inc_simple
+X<SvREFCNT_inc_simple>
+
+Same as SvREFCNT_inc, but can only be used with simple variables, not
+expressions or pointer dereferences.  Since we don't have to store a
+temporary value, it's faster.
+
+       SV*     SvREFCNT_inc_simple(SV* sv)
+
+=for hackers
+Found in file sv.h
+
+=item SvREFCNT_inc_simple_NN
+X<SvREFCNT_inc_simple_NN>
+
+Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+       SV*     SvREFCNT_inc_simple_NN(SV* sv)
+
+=for hackers
+Found in file sv.h
+
+=item SvREFCNT_inc_simple_void
+X<SvREFCNT_inc_simple_void>
+
+Same as SvREFCNT_inc_simple, but can only be used if you don't need the
+return value.  The macro doesn't need to return a meaningful value.
+
+       SV*     SvREFCNT_inc_simple_void(SV* sv)
+
+=for hackers
+Found in file sv.h
+
+=item SvREFCNT_inc_void
+X<SvREFCNT_inc_void>
+
+Same as SvREFCNT_inc, but can only be used if you don't need the
+return value.  The macro doesn't need to return a meaningful value.
+
+       SV*     SvREFCNT_inc_void(SV* sv)
+
+=for hackers
+Found in file sv.h
+
+=item SvREFCNT_inc_void_NN
+X<SvREFCNT_inc_void_NN>
+
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL.  The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
+
+       SV*     SvREFCNT_inc_void_NN(SV* sv)
+
+=for hackers
+Found in file sv.h
+
 =item SvROK
 X<SvROK>
 
index 4e6119d..2cc6868 100644 (file)
@@ -562,10 +562,10 @@ in PL_op->op_targ), wasting a name SV for them doesn't make sense.
 The SVs in the names AV have their PV being the name of the variable.
 NV+1..IV inclusive is a range of cop_seq numbers for which the name is
 valid.  For typed lexicals name SV is SVt_PVMG and SvSTASH points at the
-type.  For C<our> lexicals, the type is SVt_PVGV, and GvSTASH points at the
-stash of the associated global (so that duplicate C<our> declarations in the
-same package can be detected).  SvCUR is sometimes hijacked to
-store the generation number during compilation.
+type.  For C<our> lexicals, the type is also SVt_PVGV, with the MAGIC slot
+pointing at the stash of the associated global (so that duplicate C<our>
+declarations in the same package can be detected).  SvCUR is sometimes
+hijacked to store the generation number during compilation.
 
 If SvFAKE is set on the name SV, then that slot in the frame AV is
 a REFCNT'ed reference to a lexical from "outside". In this case,
@@ -655,7 +655,7 @@ offset.
 If C<typestash> is valid, the name is for a typed lexical; set the
 name's stash to that value.
 If C<ourstash> is valid, it's an our lexical, set the name's
-GvSTASH to that value
+OURSTASH to that value
 
 If fake, it means we're cloning an existing entry
 
diff --git a/pp.c b/pp.c
index b1fa7bc..7a93883 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -138,7 +138,7 @@ PP(pp_rv2gv)
            GV * const gv = (GV*) sv_newmortal();
            gv_init(gv, 0, "", 0, 0);
            GvIOp(gv) = (IO *)sv;
-           (void)SvREFCNT_inc(sv);
+           SvREFCNT_inc_void_NN(sv);
            sv = (SV*) gv;
        }
        else if (SvTYPE(sv) != SVt_PVGV)
@@ -322,7 +322,7 @@ PP(pp_pos)
        if (LvTARG(TARG) != sv) {
            if (LvTARG(TARG))
                SvREFCNT_dec(LvTARG(TARG));
-           LvTARG(TARG) = SvREFCNT_inc(sv);
+           LvTARG(TARG) = SvREFCNT_inc_simple(sv);
        }
        PUSHs(TARG);    /* no SvSETMAGIC */
        RETURN;
@@ -489,19 +489,19 @@ S_refto(pTHX_ SV *sv)
        if (!(sv = LvTARG(sv)))
            sv = &PL_sv_undef;
        else
-           (void)SvREFCNT_inc(sv);
+           SvREFCNT_inc_void_NN(sv);
     }
     else if (SvTYPE(sv) == SVt_PVAV) {
        if (!AvREAL((AV*)sv) && AvREIFY((AV*)sv))
            av_reify((AV*)sv);
        SvTEMP_off(sv);
-       (void)SvREFCNT_inc(sv);
+       SvREFCNT_inc_void_NN(sv);
     }
     else if (SvPADTMP(sv) && !IS_PADGV(sv))
         sv = newSVsv(sv);
     else {
        SvTEMP_off(sv);
-       (void)SvREFCNT_inc(sv);
+       SvREFCNT_inc_void_NN(sv);
     }
     rv = sv_newmortal();
     sv_upgrade(rv, SVt_RV);
@@ -654,7 +654,7 @@ PP(pp_study)
        SvSCREAM_off(PL_lastscream);
        SvREFCNT_dec(PL_lastscream);
     }
-    PL_lastscream = SvREFCNT_inc(sv);
+    PL_lastscream = SvREFCNT_inc_simple(sv);
 
     s = (unsigned char*)(SvPV(sv, len));
     pos = len;
@@ -3035,7 +3035,7 @@ PP(pp_substr)
            if (LvTARG(TARG) != sv) {
                if (LvTARG(TARG))
                    SvREFCNT_dec(LvTARG(TARG));
-               LvTARG(TARG) = SvREFCNT_inc(sv);
+               LvTARG(TARG) = SvREFCNT_inc_simple(sv);
            }
            LvTARGOFF(TARG) = upos;
            LvTARGLEN(TARG) = urem;
@@ -3066,7 +3066,7 @@ PP(pp_vec)
        if (LvTARG(TARG) != src) {
            if (LvTARG(TARG))
                SvREFCNT_dec(LvTARG(TARG));
-           LvTARG(TARG) = SvREFCNT_inc(src);
+           LvTARG(TARG) = SvREFCNT_inc_simple(src);
        }
        LvTARGOFF(TARG) = offset;
        LvTARGLEN(TARG) = size;
@@ -4338,7 +4338,7 @@ PP(pp_split)
     const I32 oldsave = PL_savestack_ix;
     I32 make_mortal = 1;
     bool multiline = 0;
-    MAGIC *mg = (MAGIC *) NULL;
+    MAGIC *mg = NULL;
 
 #ifdef DEBUGGING
     Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
index 8d20d6f..ffc80c8 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2317,7 +2317,7 @@ PP(pp_goto)
            }
 
            /* First do some returnish stuff. */
-           (void)SvREFCNT_inc(cv); /* avoid premature free during unwind */
+           SvREFCNT_inc_simple_void(cv); /* avoid premature free during unwind */
            FREETMPS;
            cxix = dopoptosub(cxstack_ix);
            if (cxix < 0)
@@ -2373,7 +2373,7 @@ PP(pp_goto)
            SAVETMPS;
            SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
            if (CvISXSUB(cv)) {
-               OP* retop = cx->blk_sub.retop;
+               OP* const retop = cx->blk_sub.retop;
                SV **newsp;
                I32 gimme;
                if (reified) {
@@ -2382,20 +2382,17 @@ PP(pp_goto)
                        sv_2mortal(SP[-index]);
                }
 
-                   /* XS subs don't have a CxSUB, so pop it */
-                   POPBLOCK(cx, PL_curpm);
-                   /* Push a mark for the start of arglist */
-                   PUSHMARK(mark);
-                   PUTBACK;
-                   (void)(*CvXSUB(cv))(aTHX_ cv);
-                   /* Put these at the bottom since the vars are set but not used */
-                   PERL_UNUSED_VAR(newsp);
-                   PERL_UNUSED_VAR(gimme);
+               /* XS subs don't have a CxSUB, so pop it */
+               POPBLOCK(cx, PL_curpm);
+               /* Push a mark for the start of arglist */
+               PUSHMARK(mark);
+               PUTBACK;
+               (void)(*CvXSUB(cv))(aTHX_ cv);
                LEAVE;
                return retop;
            }
            else {
-               AV* padlist = CvPADLIST(cv);
+               AV* const padlist = CvPADLIST(cv);
                if (CxTYPE(cx) == CXt_EVAL) {
                    PL_in_eval = cx->blk_eval.old_in_eval;
                    PL_eval_root = cx->blk_eval.old_eval_root;
@@ -2407,7 +2404,7 @@ PP(pp_goto)
 
                CvDEPTH(cv)++;
                if (CvDEPTH(cv) < 2)
-                   (void)SvREFCNT_inc(cv);
+                   SvREFCNT_inc_void_NN(cv);
                else {
                    if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
                        sub_crush_depth(cv);
@@ -2417,16 +2414,15 @@ PP(pp_goto)
                PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
                if (cx->blk_sub.hasargs)
                {
-                   AV* av = (AV*)PAD_SVl(0);
-                   SV** ary;
+                   AV* const av = (AV*)PAD_SVl(0);
 
                    cx->blk_sub.savearray = GvAV(PL_defgv);
-                   GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+                   GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
                    CX_CURPAD_SAVE(cx->blk_sub);
                    cx->blk_sub.argarray = av;
 
                    if (items >= AvMAX(av) + 1) {
-                       ary = AvALLOC(av);
+                       SV **ary = AvALLOC(av);
                        if (AvARRAY(av) != ary) {
                            AvMAX(av) += AvARRAY(av) - AvALLOC(av);
                            SvPV_set(av, (char*)ary);
@@ -2459,8 +2455,6 @@ PP(pp_goto)
                     * it's for informational purposes only.
                     */
                    SV * const sv = GvSV(PL_DBsub);
-                   CV *gotocv;
-
                    save_item(sv);
                    if (PERLDB_SUB_NN) {
                        const int type = SvTYPE(sv);
@@ -2471,11 +2465,13 @@ PP(pp_goto)
                    } else {
                        gv_efullname3(sv, CvGV(cv), NULL);
                    }
-                   if (  PERLDB_GOTO
-                         && (gotocv = get_cv("DB::goto", FALSE)) ) {
-                       PUSHMARK( PL_stack_sp );
-                       call_sv((SV*)gotocv, G_SCALAR | G_NODEBUG);
-                       PL_stack_sp--;
+                   if (PERLDB_GOTO) {
+                       CV * const gotocv = get_cv("DB::goto", FALSE);
+                       if (gotocv) {
+                           PUSHMARK( PL_stack_sp );
+                           call_sv((SV*)gotocv, G_SCALAR | G_NODEBUG);
+                           PL_stack_sp--;
+                       }
                    }
                }
                RETURNOP(CvSTART(cv));
@@ -2800,7 +2796,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
     (*startop)->op_ppaddr = PL_ppaddr[OP_NULL];
     lex_end();
     /* XXX DAPM do this properly one year */
-    *padp = (AV*)SvREFCNT_inc(PL_comppad);
+    *padp = (AV*)SvREFCNT_inc_simple(PL_comppad);
     LEAVE;
     if (IN_PERL_COMPILETIME)
        PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
@@ -2882,7 +2878,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
     cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
 
     CvOUTSIDE_SEQ(PL_compcv) = seq;
-    CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outside);
+    CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc_simple(outside);
 
     /* set up a scratch pad */
 
@@ -3189,7 +3185,7 @@ PP(pp_require)
                                       save the gv to manage the lifespan of
                                       the pipe, but this didn't help. XXX */
                                    filter_child_proc = (GV *)arg;
-                                   (void)SvREFCNT_inc(filter_child_proc);
+                                   SvREFCNT_inc_simple_void(filter_child_proc);
                                }
                                else {
                                    if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
@@ -3207,11 +3203,11 @@ PP(pp_require)
 
                        if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) {
                            filter_sub = arg;
-                           (void)SvREFCNT_inc(filter_sub);
+                           SvREFCNT_inc_void_NN(filter_sub);
 
                            if (i < count) {
                                filter_state = SP[i];
-                               (void)SvREFCNT_inc(filter_state);
+                               SvREFCNT_inc_simple_void(filter_state);
                            }
 
                            if (!tryrsfp) {
@@ -3346,7 +3342,7 @@ PP(pp_require)
     } else {
        SV** const svp = hv_fetch(GvHVn(PL_incgv), name, len, 0);
        if (!svp)
-           (void)hv_store(GvHVn(PL_incgv), name, len, SvREFCNT_inc(hook_sv), 0 );
+           (void)hv_store(GvHVn(PL_incgv), name, len, SvREFCNT_inc_simple(hook_sv), 0 );
     }
 
     ENTER;
index d26d8f0..3292332 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -146,7 +146,7 @@ PP(pp_sassign)
                SvUPGRADE((SV *)gv, SVt_RV);
                SvROK_on(gv);
                SvRV_set(gv, value);
-               SvREFCNT_inc(value);
+               SvREFCNT_inc_simple_void(value);
                SETs(right);
                RETURN;
            }
@@ -162,7 +162,7 @@ PP(pp_sassign)
            /* We've been returned a constant rather than a full subroutine,
               but they expect a subroutine reference to apply.  */
            ENTER;
-           SvREFCNT_inc(SvRV(cv));
+           SvREFCNT_inc_void(SvRV(cv));
            /* newCONSTSUB takes a reference count on the passed in SV
               from us.  We set the name to NULL, otherwise we get into
               all sorts of fun as the reference to our new sub is
@@ -1801,7 +1801,7 @@ PP(pp_helem)
            LvTYPE(lv) = 'y';
            sv_magic(lv, key2 = newSVsv(keysv), PERL_MAGIC_defelem, NULL, 0);
            SvREFCNT_dec(key2); /* sv_magic() increments refcount */
-           LvTARG(lv) = SvREFCNT_inc(hv);
+           LvTARG(lv) = SvREFCNT_inc_simple(hv);
            LvTARGLEN(lv) = 1;
            PUSHs(lv);
            RETURN;
@@ -2007,14 +2007,14 @@ PP(pp_iter)
            LvTYPE(lv) = 'y';
            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
        }
-       LvTARG(lv) = SvREFCNT_inc(av);
+       LvTARG(lv) = SvREFCNT_inc_simple(av);
        LvTARGOFF(lv) = cx->blk_loop.iterix;
        LvTARGLEN(lv) = (STRLEN)UV_MAX;
        sv = (SV*)lv;
     }
 
     oldsv = *itersvp;
-    *itersvp = SvREFCNT_inc(sv);
+    *itersvp = SvREFCNT_inc_simple_NN(sv);
     SvREFCNT_dec(oldsv);
 
     RETPUSHYES;
@@ -2025,7 +2025,6 @@ PP(pp_subst)
     dVAR; dSP; dTARG;
     register PMOP *pm = cPMOP;
     PMOP *rpm = pm;
-    register SV *dstr;
     register char *s;
     char *strend;
     register char *m;
@@ -2051,7 +2050,7 @@ PP(pp_subst)
     SV *nsv = NULL;
 
     /* known replacement string? */
-    dstr = (pm->op_pmflags & PMf_CONST) ? POPs : NULL;
+    register SV *dstr = (pm->op_pmflags & PMf_CONST) ? POPs : NULL;
     if (PL_op->op_flags & OPf_STACKED)
        TARG = POPs;
     else if (PL_op->op_private & OPpTARGET_MY)
@@ -2515,7 +2514,7 @@ PP(pp_leavesublv)
                else {
                    /* Can be a localized value subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
        }
@@ -2552,7 +2551,7 @@ PP(pp_leavesublv)
                else {                  /* Can be a localized value
                                         * subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
            else {                      /* Should not happen? */
@@ -2584,7 +2583,7 @@ PP(pp_leavesublv)
                else {
                    /* Can be a localized value subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
        }
@@ -2820,7 +2819,7 @@ try_autoload:
                AvREIFY_on(av);
            }
            cx->blk_sub.savearray = GvAV(PL_defgv);
-           GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+           GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
            CX_CURPAD_SAVE(cx->blk_sub);
            cx->blk_sub.argarray = av;
            ++MARK;
@@ -2955,7 +2954,7 @@ PP(pp_aelem)
            sv_upgrade(lv, SVt_PVLV);
            LvTYPE(lv) = 'y';
            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-           LvTARG(lv) = SvREFCNT_inc(av);
+           LvTARG(lv) = SvREFCNT_inc_simple(av);
            LvTARGOFF(lv) = elem;
            LvTARGLEN(lv) = 1;
            PUSHs(lv);
index 104e8ed..7585b75 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1655,10 +1655,10 @@ PP(pp_sort)
 
                    if (hasargs) {
                        /* This is mostly copied from pp_entersub */
-                       AV *av = (AV*)PAD_SVl(0);
+                       AV * const av = (AV*)PAD_SVl(0);
 
                        cx->blk_sub.savearray = GvAV(PL_defgv);
-                       GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+                       GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
                        CX_CURPAD_SAVE(cx->blk_sub);
                        cx->blk_sub.argarray = av;
                    }
index d6055f2..92c0b08 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1150,8 +1150,7 @@ void
 Perl_setdefout(pTHX_ GV *gv)
 {
     dVAR;
-    if (gv)
-       (void)SvREFCNT_inc(gv);
+    SvREFCNT_inc_simple_void(gv);
     if (PL_defoutgv)
        SvREFCNT_dec(PL_defoutgv);
     PL_defoutgv = gv;
index dba8bfb..b3c31b7 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -6230,14 +6230,15 @@ Perl_save_re_context(pTHX)
        if (rx) {
            U32 i;
            for (i = 1; i <= rx->nparens; i++) {
-               GV *gv;
                char digits[TYPE_CHARS(long)];
                const STRLEN len = my_sprintf(digits, "%lu", (long)i);
                GV *const *const gvp
                    = (GV**)hv_fetch(PL_defstash, digits, len, 0);
 
-               if (gvp && SvTYPE(gv = *gvp) == SVt_PVGV && GvSV(gv)) {
-                   save_scalar(gv);
+               if (gvp) {
+                   GV * const gv = *gvp;
+                   if (SvTYPE(gv) == SVt_PVGV && GvSV(gv))
+                       save_scalar(gv);
                }
            }
        }
diff --git a/scope.c b/scope.c
index ad7f14d..234dd9f 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -186,7 +186,7 @@ Perl_save_scalar(pTHX_ GV *gv)
     SvGETMAGIC(*sptr);
     PL_localizing = 0;
     SSCHECK(3);
-    SSPUSHPTR(SvREFCNT_inc(gv));
+    SSPUSHPTR(SvREFCNT_inc_simple(gv));
     SSPUSHPTR(SvREFCNT_inc(*sptr));
     SSPUSHINT(SAVEt_SV);
     return save_scalar_at(sptr);
@@ -479,7 +479,7 @@ Perl_save_delete(pTHX_ HV *hv, char *key, I32 klen)
     SSCHECK(4);
     SSPUSHINT(klen);
     SSPUSHPTR(key);
-    SSPUSHPTR(SvREFCNT_inc(hv));
+    SSPUSHPTR(SvREFCNT_inc_simple(hv));
     SSPUSHINT(SAVEt_DELETE);
 }
 
@@ -500,13 +500,13 @@ Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr)
     SV *sv;
     SvGETMAGIC(*sptr);
     SSCHECK(4);
-    SSPUSHPTR(SvREFCNT_inc(av));
+    SSPUSHPTR(SvREFCNT_inc_simple(av));
     SSPUSHINT(idx);
     SSPUSHPTR(SvREFCNT_inc(*sptr));
     SSPUSHINT(SAVEt_AELEM);
     /* if it gets reified later, the restore will have the wrong refcnt */
     if (!AvREAL(av) && AvREIFY(av))
-        (void)SvREFCNT_inc(*sptr);
+       SvREFCNT_inc_void(*sptr);
     save_scalar_at(sptr);
     sv = *sptr;
     /* If we're localizing a tied array element, this new sv
@@ -524,8 +524,8 @@ Perl_save_helem(pTHX_ HV *hv, SV *key, SV **sptr)
     SV *sv;
     SvGETMAGIC(*sptr);
     SSCHECK(4);
-    SSPUSHPTR(SvREFCNT_inc(hv));
-    SSPUSHPTR(SvREFCNT_inc(key));
+    SSPUSHPTR(SvREFCNT_inc_simple(hv));
+    SSPUSHPTR(SvREFCNT_inc_simple(key));
     SSPUSHPTR(SvREFCNT_inc(*sptr));
     SSPUSHINT(SAVEt_HELEM);
     save_scalar_at(sptr);
@@ -831,7 +831,7 @@ Perl_leave_scope(pTHX_ I32 base)
                sv = *(SV**)ptr;
                if (sv && sv != &PL_sv_undef) {
                    if (SvTIED_mg((SV*)av, PERL_MAGIC_tied))
-                       (void)SvREFCNT_inc(sv);
+                       SvREFCNT_inc_void_NN(sv);
                    goto restore_sv;
                }
            }
@@ -848,7 +848,7 @@ Perl_leave_scope(pTHX_ I32 base)
                if (oval && oval != &PL_sv_undef) {
                    ptr = &HeVAL((HE*)ptr);
                    if (SvTIED_mg((SV*)hv, PERL_MAGIC_tied))
-                       (void)SvREFCNT_inc(*(SV**)ptr);
+                       SvREFCNT_inc_void(*(SV**)ptr);
                    SvREFCNT_dec(sv);
                    av = (AV*)hv; /* what to refcnt_dec */
                    goto restore_sv;
diff --git a/sv.c b/sv.c
index 7e7d631..66b4d8e 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -3328,8 +3328,7 @@ S_glob_assign_ref(pTHX_ SV *dstr, SV *sstr) {
        }
        break;
     }
-    if (dref)
-       SvREFCNT_dec(dref);
+    SvREFCNT_dec(dref);
     if (SvTAINTED(sstr))
        SvTAINT(dstr);
     return;
@@ -4338,7 +4337,7 @@ Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable,
        mg->mg_obj = obj;
     }
     else {
-       mg->mg_obj = SvREFCNT_inc(obj);
+       mg->mg_obj = SvREFCNT_inc_simple(obj);
        mg->mg_flags |= MGf_REFCOUNTED;
     }
 
@@ -4362,7 +4361,7 @@ Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable,
        if (namlen > 0)
            mg->mg_ptr = savepvn(name, namlen);
        else if (namlen == HEf_SVKEY)
-           mg->mg_ptr = (char*)SvREFCNT_inc((SV*)name);
+           mg->mg_ptr = (char*)SvREFCNT_inc_simple_NN((SV*)name);
        else
            mg->mg_ptr = (char *) name;
     }
@@ -4668,7 +4667,7 @@ Perl_sv_add_backref(pTHX_ SV *tsv, SV *sv)
            } else {
                av = newAV();
                AvREAL_off(av);
-               SvREFCNT_inc(av);
+               SvREFCNT_inc_simple_void(av);
            }
            *avp = av;
        }
@@ -5112,7 +5111,7 @@ Perl_sv_clear(pTHX_ register SV *sv)
     case SVt_PV:
     case SVt_RV:
        if (SvROK(sv)) {
-           SV *target = SvRV(sv);
+           SV * const target = SvRV(sv);
            if (SvWEAKREF(sv))
                sv_del_backref(target, sv);
            else
@@ -5766,9 +5765,7 @@ Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
     if (cur1 == cur2)
        eq = (pv1 == pv2) || memEQ(pv1, pv2, cur1);
        
-    if (svrecode)
-        SvREFCNT_dec(svrecode);
-
+    SvREFCNT_dec(svrecode);
     if (tpv)
        Safefree(tpv);
 
@@ -5851,9 +5848,7 @@ Perl_sv_cmp(pTHX_ register SV *sv1, register SV *sv2)
        }
     }
 
-    if (svrecode)
-        SvREFCNT_dec(svrecode);
-
+    SvREFCNT_dec(svrecode);
     if (tpv)
        Safefree(tpv);
 
@@ -6971,7 +6966,7 @@ SV *
 Perl_newRV(pTHX_ SV *tmpRef)
 {
     dVAR;
-    return newRV_noinc(SvREFCNT_inc(tmpRef));
+    return newRV_noinc(SvREFCNT_inc_simple(tmpRef));
 }
 
 /*
@@ -7665,7 +7660,7 @@ Perl_sv_bless(pTHX_ SV *sv, HV *stash)
     if (SvTYPE(tmpRef) != SVt_PVIO)
        ++PL_sv_objcount;
     SvUPGRADE(tmpRef, SVt_PVMG);
-    SvSTASH_set(tmpRef, (HV*)SvREFCNT_inc(stash));
+    SvSTASH_set(tmpRef, (HV*)SvREFCNT_inc_simple(stash));
 
     if (Gv_AMG(stash))
        SvAMAGIC_on(sv);
@@ -7689,7 +7684,7 @@ S_sv_unglob(pTHX_ SV *sv)
 {
     dVAR;
     void *xpvmg;
-    SV *temp = sv_newmortal();
+    SV * const temp = sv_newmortal();
 
     assert(SvTYPE(sv) == SVt_PVGV);
     SvFAKE_off(sv);
@@ -9373,6 +9368,7 @@ GP *
 Perl_gp_dup(pTHX_ GP *gp, CLONE_PARAMS* param)
 {
     GP *ret;
+
     if (!gp)
        return (GP*)NULL;
     /* look for it in the table first */
@@ -11152,7 +11148,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
                    proto_perl->Ttmps_stack[i]);
            if (nsv && !SvREFCNT(nsv)) {
                EXTEND_MORTAL(1);
-               PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc(nsv);
+               PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple(nsv);
            }
        }
     }
@@ -11300,7 +11296,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     /* orphaned? eg threads->new inside BEGIN or use */
     if (PL_compcv && ! SvREFCNT(PL_compcv)) {
-       (void)SvREFCNT_inc(PL_compcv);
+       SvREFCNT_inc_simple_void(PL_compcv);
        SAVEFREESV(PL_compcv);
     }
 
diff --git a/sv.h b/sv.h
index e5fb2d3..fc49f23 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -150,6 +150,41 @@ Returns the value of the object's reference count.
 =for apidoc Am|SV*|SvREFCNT_inc|SV* sv
 Increments the reference count of the given SV.
 
+All of the following SvREFCNT_inc* macros are optimized versions of
+SvREFCNT_inc, and can be replaced with SvREFCNT_inc.
+
+=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the
+return value.  The macro doesn't need to return a meaningful value.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL.  The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv
+Same as SvREFCNT_inc, but can only be used with simple variables, not
+expressions or pointer dereferences.  Since we don't have to store a
+temporary value, it's faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_void|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you don't need the
+return value.  The macro doesn't need to return a meaningful value.
+
+=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
+Increments the reference count of the given SV.
+
 =for apidoc Am|void|SvREFCNT_dec|SV* sv
 Decrements the reference count of the given SV.
 
@@ -175,11 +210,41 @@ perform the upgrade if necessary.  See C<svtype>.
             (SvREFCNT(_sv))++;         \
        _sv;                            \
     })
+#  define SvREFCNT_inc_simple(sv)      \
+    ({                                 \
+       if (sv)                         \
+            (SvREFCNT(sv))++;          \
+       sv;                             \
+    })
+#  define SvREFCNT_inc_NN(sv)          \
+    ({                                 \
+       SV * const _sv = (SV*)(sv);     \
+       SvREFCNT(_sv)++;                \
+       _sv;                            \
+    })
+#  define SvREFCNT_inc_void(sv)                \
+    ({                                 \
+       SV * const _sv = (SV*)(sv);     \
+       if (_sv)                        \
+           (void)(SvREFCNT(_sv)++);    \
+    })
 #else
 #  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=(SV*)(sv)) ? ((++(SvREFCNT(PL_Sv))),(PL_Sv)) : NULL)
+       ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+#  define SvREFCNT_inc_simple(sv) \
+       ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+#  define SvREFCNT_inc_NN(sv) \
+       (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+#  define SvREFCNT_inc_void(sv) \
+       (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
 #endif
 
+/* These guys don't need the curly blocks */
+#define SvREFCNT_inc_simple_void(sv)   if (sv) (SvREFCNT(sv)++);
+#define SvREFCNT_inc_simple_NN(sv)     (++(SvREFCNT(sv)),(SV*)(sv))
+#define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT((SV*)(sv)))
+#define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT((SV*)(sv)))
+
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
 #  define SvREFCNT_dec(sv)             \
     ({                                 \
diff --git a/toke.c b/toke.c
index 1ef9b18..13582da 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -4443,7 +4443,7 @@ Perl_yylex(pTHX)
                    if ((sv = gv_const_sv(gv))) {
                  its_constant:
                        SvREFCNT_dec(((SVOP*)yylval.opval)->op_sv);
-                       ((SVOP*)yylval.opval)->op_sv = SvREFCNT_inc(sv);
+                       ((SVOP*)yylval.opval)->op_sv = SvREFCNT_inc_simple(sv);
                        yylval.opval->op_private = 0;
                        TOKEN(WORD);
                    }
@@ -9329,11 +9329,11 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, SV *sv, SV *pv,
        sv_catpvs(ERRSV, "Propagated");
        yyerror(SvPV_nolen_const(ERRSV)); /* Duplicates the message inside eval */
        (void)POPs;
-       res = SvREFCNT_inc(sv);
+       res = SvREFCNT_inc_simple(sv);
     }
     else {
        res = POPs;
-       (void)SvREFCNT_inc(res);
+       SvREFCNT_inc_simple_void(res);
     }
 
     PUTBACK ;
@@ -10950,7 +10950,7 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags)
 
     PL_subline = CopLINE(PL_curcop);
     CvPADLIST(PL_compcv) = pad_new(padnew_SAVE|padnew_SAVESUB);
-    CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outsidecv);
+    CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc_simple(outsidecv);
     CvOUTSIDE_SEQ(PL_compcv) = PL_cop_seqmax;
 
     return oldsavestack_ix;