sprinkle LIKELY() on pp_hot.c scope.c and some *.h
authorDavid Mitchell <davem@iabyn.com>
Wed, 12 Mar 2014 19:14:13 +0000 (19:14 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 12 Mar 2014 20:19:03 +0000 (20:19 +0000)
I've gone through pp_hot.c and scope.c and added LIKELY() or UNLIKELY()
to all conditionals where I understand the code well enough to know that
a particular branch is or isn't likely to be taken very often.

I also processed some of the .h files which contain commonly used macros.

handy.h
perl.h
pp.h
pp_hot.c
scope.c
scope.h
sv.h

diff --git a/handy.h b/handy.h
index 2f0132f..16264fe 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -1793,9 +1793,9 @@ PoisonWith(0xEF) for catching access to freed memory.
  * (U16)n > (size_t)~0/sizeof(U16) always being false. */
 #ifdef PERL_MALLOC_WRAP
 #define MEM_WRAP_CHECK(n,t) \
-       (void)(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t) && (croak_memory_wrap(),0))
+       (void)(UNLIKELY(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t)) && (croak_memory_wrap(),0))
 #define MEM_WRAP_CHECK_1(n,t,a) \
-       (void)(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t) && (Perl_croak_nocontext("%s",(a)),0))
+       (void)(UNLIKELY(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t)) && (Perl_croak_nocontext("%s",(a)),0))
 #define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
 
 #define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (croak_memory_wrap(),0):0),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
diff --git a/perl.h b/perl.h
index d3e2675..574a8a3 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -3485,11 +3485,11 @@ my_swap16(const U16 x) {
 #define U_32(n) ((n) < 0.0 ? ((n) < I32_MIN ? (UV) I32_MIN : (U32)(I32) (n)) \
                   : ((n) < U32_MAX_P1 ? (U32) (n) \
                      : ((n) > 0 ? U32_MAX : 0 /* NaN */)))
-#define I_V(n) ((n) < IV_MAX_P1 ? ((n) < IV_MIN ? IV_MIN : (IV) (n)) \
-                  : ((n) < UV_MAX_P1 ? (IV)(UV) (n) \
+#define I_V(n) (LIKELY((n) < IV_MAX_P1) ? (UNLIKELY((n) < IV_MIN) ? IV_MIN : (IV) (n)) \
+                  : (LIKELY((n) < UV_MAX_P1) ? (IV)(UV) (n) \
                      : ((n) > 0 ? (IV)UV_MAX : 0 /* NaN */)))
-#define U_V(n) ((n) < 0.0 ? ((n) < IV_MIN ? (UV) IV_MIN : (UV)(IV) (n)) \
-                  : ((n) < UV_MAX_P1 ? (UV) (n) \
+#define U_V(n) ((n) < 0.0 ? (UNLIKELY((n) < IV_MIN) ? (UV) IV_MIN : (UV)(IV) (n)) \
+                  : (LIKELY((n) < UV_MAX_P1) ? (UV) (n) \
                      : ((n) > 0 ? UV_MAX : 0 /* NaN */)))
 #endif
 
@@ -5459,7 +5459,7 @@ typedef struct am_table_short AMTS;
 
 #ifndef PERL_MICRO
 #      ifndef PERL_ASYNC_CHECK
-#              define PERL_ASYNC_CHECK() if (PL_sig_pending) PL_signalhook(aTHX)
+#              define PERL_ASYNC_CHECK() if (UNLIKELY(PL_sig_pending)) PL_signalhook(aTHX)
 #      endif
 #endif
 
diff --git a/pp.h b/pp.h
index d0a62fb..97738c2 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -57,7 +57,7 @@ Refetch the stack pointer.  Used after a callback.  See L<perlcall>.
 
 #define PUSHMARK(p)    \
        STMT_START {                                    \
-           if (++PL_markstack_ptr == PL_markstack_max) \
+           if (UNLIKELY(++PL_markstack_ptr == PL_markstack_max))       \
            markstack_grow();                           \
            *PL_markstack_ptr = (I32)((p) - PL_stack_base);\
        } STMT_END
@@ -400,12 +400,12 @@ Does not use C<TARG>.  See also C<XPUSHu>, C<mPUSHu> and C<PUSHu>.
 /* do SvGETMAGIC on the stack args before checking for overload */
 
 #define tryAMAGICun_MG(method, flags) STMT_START { \
-       if ( (SvFLAGS(TOPs) & (SVf_ROK|SVs_GMG)) \
+       if ( UNLIKELY((SvFLAGS(TOPs) & (SVf_ROK|SVs_GMG))) \
                && Perl_try_amagic_un(aTHX_ method, flags)) \
            return NORMAL; \
     } STMT_END
 #define tryAMAGICbin_MG(method, flags) STMT_START { \
-       if ( ((SvFLAGS(TOPm1s)|SvFLAGS(TOPs)) & (SVf_ROK|SVs_GMG)) \
+       if ( UNLIKELY(((SvFLAGS(TOPm1s)|SvFLAGS(TOPs)) & (SVf_ROK|SVs_GMG))) \
                && Perl_try_amagic_bin(aTHX_ method, flags)) \
            return NORMAL; \
     } STMT_END
@@ -422,10 +422,11 @@ Does not use C<TARG>.  See also C<XPUSHu>, C<mPUSHu> and C<PUSHu>.
        SV *tmpsv;                                              \
        SV *arg= *sp;                                           \
         int gimme = GIMME_V;                                    \
-       if (SvAMAGIC(arg) &&                                    \
+       if (UNLIKELY(SvAMAGIC(arg) &&                           \
            (tmpsv = amagic_call(arg, &PL_sv_undef, meth,       \
                                 AMGf_want_list | AMGf_noright  \
-                               |AMGf_unary))) {                \
+                               |AMGf_unary))))                 \
+        {                                                      \
            SPAGAIN;                                            \
             if (gimme == G_VOID) {                              \
                 (void)POPs; /* XXX ??? */                       \
index 36eac2b..3a19f52 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -61,7 +61,7 @@ PP(pp_gvsv)
     dVAR;
     dSP;
     EXTEND(SP,1);
-    if (PL_op->op_private & OPpLVAL_INTRO)
+    if (UNLIKELY(PL_op->op_private & OPpLVAL_INTRO))
        PUSHs(save_scalar(cGVOP_gv));
     else
        PUSHs(GvSVn(cGVOP_gv));
@@ -133,9 +133,10 @@ PP(pp_sassign)
        SV * const temp = left;
        left = right; right = temp;
     }
-    if (TAINTING_get && TAINT_get && !SvTAINTED(right))
+    if (TAINTING_get && UNLIKELY(TAINT_get) && !SvTAINTED(right))
        TAINT_NOT;
-    if (PL_op->op_private & OPpASSIGN_CV_TO_GV) {
+    if (UNLIKELY(PL_op->op_private & OPpASSIGN_CV_TO_GV)) {
+        /* *foo =\&bar */
        SV * const cv = SvRV(right);
        const U32 cv_type = SvTYPE(cv);
        const bool is_gv = isGV_with_GP(left);
@@ -214,7 +215,7 @@ PP(pp_sassign)
 
     }
     if (
-      SvTEMP(left) && !SvSMAGICAL(left) && SvREFCNT(left) == 1 &&
+      UNLIKELY(SvTEMP(left)) && !SvSMAGICAL(left) && SvREFCNT(left) == 1 &&
       (!isGV_with_GP(left) || SvFAKE(left)) && ckWARN(WARN_MISC)
     )
        Perl_warner(aTHX_
@@ -330,7 +331,7 @@ S_pushav(pTHX_ AV* const av)
     dSP;
     const SSize_t maxarg = AvFILL(av) + 1;
     EXTEND(SP, maxarg);
-    if (SvRMAGICAL(av)) {
+    if (UNLIKELY(SvRMAGICAL(av))) {
         PADOFFSET i;
         for (i=0; i < (PADOFFSET)maxarg; i++) {
             SV ** const svp = av_fetch(av, i, FALSE);
@@ -344,7 +345,7 @@ S_pushav(pTHX_ AV* const av)
         PADOFFSET i;
         for (i=0; i < (PADOFFSET)maxarg; i++) {
             SV * const sv = AvARRAY(av)[i];
-            SP[i+1] = sv ? sv : &PL_sv_undef;
+            SP[i+1] = LIKELY(sv) ? sv : &PL_sv_undef;
         }
     }
     SP += maxarg;
@@ -470,9 +471,9 @@ PP(pp_preinc)
     dVAR; dSP;
     const bool inc =
        PL_op->op_type == OP_PREINC || PL_op->op_type == OP_I_PREINC;
-    if (SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs)))
+    if (UNLIKELY(SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs))))
        Perl_croak_no_modify();
-    if (!SvREADONLY(TOPs) && !SvGMAGICAL(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
+    if (LIKELY(!SvREADONLY(TOPs) && !SvGMAGICAL(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs))
         && SvIVX(TOPs) != (inc ? IV_MAX : IV_MIN))
     {
        SvIV_set(TOPs, SvIVX(TOPs) + (inc ? 1 : -1));
@@ -509,7 +510,7 @@ PP(pp_defined)
     if (is_dor) {
        PERL_ASYNC_CHECK();
         sv = TOPs;
-        if (!sv || !SvANY(sv)) {
+        if (UNLIKELY(!sv || !SvANY(sv))) {
            if (op_type == OP_DOR)
                --SP;
             RETURNOP(cLOGOP->op_other);
@@ -518,7 +519,7 @@ PP(pp_defined)
     else {
        /* OP_DEFINED */
         sv = POPs;
-        if (!sv || !SvANY(sv))
+        if (UNLIKELY(!sv || !SvANY(sv)))
             RETPUSHNO;
     }
 
@@ -876,18 +877,18 @@ PP(pp_rv2av)
 
     SvGETMAGIC(sv);
     if (SvROK(sv)) {
-       if (SvAMAGIC(sv)) {
+       if (UNLIKELY(SvAMAGIC(sv))) {
            sv = amagic_deref_call(sv, is_pp_rv2av ? to_av_amg : to_hv_amg);
        }
        sv = SvRV(sv);
-       if (SvTYPE(sv) != type)
+       if (UNLIKELY(SvTYPE(sv) != type))
            /* diag_listed_as: Not an ARRAY reference */
            DIE(aTHX_ "Not %s reference", is_pp_rv2av ? an_array : a_hash);
-       else if (PL_op->op_flags & OPf_MOD
-               && PL_op->op_private & OPpLVAL_INTRO)
+       else if (UNLIKELY(PL_op->op_flags & OPf_MOD
+               && PL_op->op_private & OPpLVAL_INTRO))
            Perl_croak(aTHX_ "%s", PL_no_localize_ref);
     }
-    else if (SvTYPE(sv) != type) {
+    else if (UNLIKELY(SvTYPE(sv) != type)) {
            GV *gv;
        
            if (!isGV_with_GP(sv)) {
@@ -907,7 +908,7 @@ PP(pp_rv2av)
                SETs(sv);
                RETURN;
     }
-    else if (PL_op->op_private & OPpMAYBE_LVSUB) {
+    else if (UNLIKELY(PL_op->op_private & OPpMAYBE_LVSUB)) {
              const I32 flags = is_lvalue_sub();
              if (flags && !(flags & OPpENTERSUB_INARGS)) {
                if (gimme != G_ARRAY)
@@ -1026,13 +1027,13 @@ PP(pp_aassign)
     ) {
        EXTEND_MORTAL(lastrelem - firstrelem + 1);
        for (relem = firstrelem; relem <= lastrelem; relem++) {
-           if ((sv = *relem)) {
+           if (LIKELY((sv = *relem))) {
                TAINT_NOT;      /* Each item is independent */
 
                /* Dear TODO test in t/op/sort.t, I love you.
                   (It's relying on a panic, not a "semi-panic" from newSVsv()
                   and then an assertion failure below.)  */
-               if (SvIS_FREED(sv)) {
+               if (UNLIKELY(SvIS_FREED(sv))) {
                    Perl_croak(aTHX_ "panic: attempt to copy freed scalar %p",
                               (void*)sv);
                }
@@ -1050,7 +1051,7 @@ PP(pp_aassign)
     ary = NULL;
     hash = NULL;
 
-    while (lelem <= lastlelem) {
+    while (LIKELY(lelem <= lastlelem)) {
        TAINT_NOT;              /* Each item stands on its own, taintwise. */
        sv = *lelem++;
        switch (SvTYPE(sv)) {
@@ -1064,7 +1065,7 @@ PP(pp_aassign)
            i = 0;
            while (relem <= lastrelem) {        /* gobble up all the rest */
                SV **didstore;
-               if (*relem)
+               if (LIKELY(*relem))
                    SvGETMAGIC(*relem); /* before newSV, in case it dies */
                sv = newSV(0);
                sv_setsv_nomg(sv, *relem);
@@ -1078,7 +1079,7 @@ PP(pp_aassign)
                }
                TAINT_NOT;
            }
-           if (PL_delaymagic & DM_ARRAY_ISA)
+           if (UNLIKELY(PL_delaymagic & DM_ARRAY_ISA))
                SvSETMAGIC(MUTABLE_SV(ary));
            LEAVE;
            break;
@@ -1093,7 +1094,7 @@ PP(pp_aassign)
                magic = SvMAGICAL(hash) != 0;
 
                 odd = ((lastrelem - firsthashrelem)&1)? 0 : 1;
-                if ( odd ) {
+                if (UNLIKELY(odd)) {
                     do_oddball(lastrelem, firsthashrelem);
                     /* we have firstlelem to reuse, it's not needed anymore
                     */
@@ -1103,7 +1104,7 @@ PP(pp_aassign)
                ENTER;
                SAVEFREESV(SvREFCNT_inc_simple_NN(sv));
                hv_clear(hash);
-               while (relem < lastrelem+odd) { /* gobble up all the rest */
+               while (LIKELY(relem < lastrelem+odd)) { /* gobble up all the rest */
                    HE *didstore;
                     assert(*relem);
                    /* Copy the key if aassign is called in lvalue context,
@@ -1163,10 +1164,10 @@ PP(pp_aassign)
                break;
            }
            if (relem <= lastrelem) {
-               if (
+               if (UNLIKELY(
                  SvTEMP(sv) && !SvSMAGICAL(sv) && SvREFCNT(sv) == 1 &&
                  (!isGV_with_GP(sv) || SvFAKE(sv)) && ckWARN(WARN_MISC)
-               )
+               ))
                    Perl_warner(aTHX_
                       packWARN(WARN_MISC),
                      "Useless assignment to a temporary"
@@ -1180,7 +1181,7 @@ PP(pp_aassign)
            break;
        }
     }
-    if (PL_delaymagic & ~DM_DELAY) {
+    if (UNLIKELY(PL_delaymagic & ~DM_DELAY)) {
         int rc = 0;
        /* Will be used to set PL_tainting below */
        Uid_t tmp_uid  = PerlProc_getuid();
@@ -1314,7 +1315,7 @@ PP(pp_qr)
     SvROK_on(rv);
 
     cvp = &( ReANY((REGEXP *)SvRV(rv))->qr_anoncv);
-    if ((cv = *cvp) && CvCLONE(*cvp)) {
+    if (UNLIKELY((cv = *cvp) && CvCLONE(*cvp))) {
        *cvp = cv_clone(cv);
        SvREFCNT_dec_NN(cv);
     }
@@ -1325,7 +1326,7 @@ PP(pp_qr)
        (void)sv_bless(rv, stash);
     }
 
-    if (RX_ISTAINTED(rx)) {
+    if (UNLIKELY(RX_ISTAINTED(rx))) {
         SvTAINTED_on(rv);
         SvTAINTED_on(SvRV(rv));
     }
@@ -1487,11 +1488,13 @@ PP(pp_match)
        EXTEND_MORTAL(nparens + i);
        for (i = !i; i <= nparens; i++) {
            PUSHs(sv_newmortal());
-           if ((RX_OFFS(rx)[i].start != -1) && RX_OFFS(rx)[i].end != -1 ) {
+           if (LIKELY((RX_OFFS(rx)[i].start != -1)
+                     && RX_OFFS(rx)[i].end   != -1 ))
+            {
                const I32 len = RX_OFFS(rx)[i].end - RX_OFFS(rx)[i].start;
                const char * const s = RX_OFFS(rx)[i].start + truebase;
-               if (RX_OFFS(rx)[i].end < 0 || RX_OFFS(rx)[i].start < 0 ||
-                   len < 0 || len > strend - s)
+               if (UNLIKELY(RX_OFFS(rx)[i].end < 0 || RX_OFFS(rx)[i].start < 0
+                        || len < 0 || len > strend - s))
                    DIE(aTHX_ "panic: pp_match start/end pointers, i=%ld, "
                        "start=%ld, end=%ld, s=%p, strend=%p, len=%"UVuf,
                        (long) i, (long) RX_OFFS(rx)[i].start,
@@ -1832,11 +1835,11 @@ PP(pp_iter)
            It has SvPVX of "" and SvCUR of 0, which is what we want.  */
         STRLEN maxlen = 0;
         const char *max = SvPV_const(end, maxlen);
-        if (SvNIOK(cur) || SvCUR(cur) > maxlen)
+        if (UNLIKELY(SvNIOK(cur) || SvCUR(cur) > maxlen))
             RETPUSHNO;
 
         oldsv = *itersvp;
-        if (SvREFCNT(oldsv) == 1 && !SvMAGICAL(oldsv)) {
+        if (LIKELY(SvREFCNT(oldsv) == 1 && !SvMAGICAL(oldsv))) {
             /* safe to reuse old SV */
             sv_setsv(oldsv, cur);
         }
@@ -1858,12 +1861,12 @@ PP(pp_iter)
     case CXt_LOOP_LAZYIV: /* integer increment */
     {
         IV cur = cx->blk_loop.state_u.lazyiv.cur;
-       if (cur > cx->blk_loop.state_u.lazyiv.end)
+       if (UNLIKELY(cur > cx->blk_loop.state_u.lazyiv.end))
            RETPUSHNO;
 
         oldsv = *itersvp;
        /* don't risk potential race */
-       if (SvREFCNT(oldsv) == 1 && !SvMAGICAL(oldsv)) {
+       if (LIKELY(SvREFCNT(oldsv) == 1 && !SvMAGICAL(oldsv))) {
            /* safe to reuse old SV */
            sv_setiv(oldsv, cur);
        }
@@ -1876,7 +1879,7 @@ PP(pp_iter)
            SvREFCNT_dec_NN(oldsv);
        }
 
-       if (cur == IV_MAX) {
+       if (UNLIKELY(cur == IV_MAX)) {
            /* Handle end of range at IV_MAX */
            cx->blk_loop.state_u.lazyiv.end = IV_MIN;
        } else
@@ -1898,16 +1901,16 @@ PP(pp_iter)
         }
         if (PL_op->op_private & OPpITER_REVERSED) {
             ix = --cx->blk_loop.state_u.ary.ix;
-            if (ix <= (av_is_stack ? cx->blk_loop.resetsp : -1))
+            if (UNLIKELY(ix <= (av_is_stack ? cx->blk_loop.resetsp : -1)))
                 RETPUSHNO;
         }
         else {
             ix = ++cx->blk_loop.state_u.ary.ix;
-            if (ix > (av_is_stack ? cx->blk_oldsp : AvFILL(av)))
+            if (UNLIKELY(ix > (av_is_stack ? cx->blk_oldsp : AvFILL(av))))
                 RETPUSHNO;
         }
 
-        if (SvMAGICAL(av) || AvREIFY(av)) {
+        if (UNLIKELY(SvMAGICAL(av) || AvREIFY(av))) {
             SV * const * const svp = av_fetch(av, ix, FALSE);
             sv = svp ? *svp : NULL;
         }
@@ -1915,8 +1918,8 @@ PP(pp_iter)
             sv = AvARRAY(av)[ix];
         }
 
-        if (sv) {
-            if (SvIS_FREED(sv)) {
+        if (LIKELY(sv)) {
+            if (UNLIKELY(SvIS_FREED(sv))) {
                 *itersvp = NULL;
                 Perl_croak(aTHX_ "Use of freed value in iteration");
             }
@@ -2224,9 +2227,9 @@ PP(pp_subst)
             d = s = RX_OFFS(rx)[0].start + orig;
            do {
                 I32 i;
-               if (iters++ > maxiters)
+               if (UNLIKELY(iters++ > maxiters))
                    DIE(aTHX_ "Substitution loop");
-               if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
+               if (UNLIKELY(RX_MATCH_TAINTED(rx))) /* run time pattern taint, eg locale */
                    rxtainted |= SUBST_TAINT_PAT;
                m = RX_OFFS(rx)[0].start + orig;
                if ((i = m - s)) {
@@ -2294,9 +2297,9 @@ PP(pp_subst)
        }
        first = TRUE;
        do {
-           if (iters++ > maxiters)
+           if (UNLIKELY(iters++ > maxiters))
                DIE(aTHX_ "Substitution loop");
-           if (RX_MATCH_TAINTED(rx))
+           if (UNLIKELY(RX_MATCH_TAINTED(rx)))
                rxtainted |= SUBST_TAINT_PAT;
            if (RX_MATCH_COPIED(rx) && RX_SUBBEG(rx) != orig) {
                char *old_s    = s;
@@ -2324,7 +2327,7 @@ PP(pp_subst)
                    sv_catsv(dstr, nsv);
                }
                else sv_catsv(dstr, repl);
-               if (SvTAINTED(repl))
+               if (UNLIKELY(SvTAINTED(repl)))
                    rxtainted |= SUBST_TAINT_REPL;
            }
            if (once)
@@ -2407,7 +2410,7 @@ PP(pp_grepwhile)
     LEAVE_with_name("grep_item");                                      /* exit inner scope */
 
     /* All done yet? */
-    if (PL_stack_base + *PL_markstack_ptr > SP) {
+    if (UNLIKELY(PL_stack_base + *PL_markstack_ptr > SP)) {
        I32 items;
        const I32 gimme = GIMME_V;
 
@@ -2472,7 +2475,7 @@ PP(pp_leavesub)
     TAINT_NOT;
     if (gimme == G_SCALAR) {
        MARK = newsp + 1;
-       if (MARK <= SP) {
+       if (LIKELY(MARK <= SP)) {
            if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
                if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1
                     && !SvMAGICAL(TOPs)) {
@@ -2835,14 +2838,14 @@ PP(pp_aelem)
     bool preeminent = TRUE;
     SV *sv;
 
-    if (SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC))
+    if (UNLIKELY(SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC)))
        Perl_warner(aTHX_ packWARN(WARN_MISC),
                    "Use of reference \"%"SVf"\" as array index",
                    SVfARG(elemsv));
-    if (SvTYPE(av) != SVt_PVAV)
+    if (UNLIKELY(SvTYPE(av) != SVt_PVAV))
        RETPUSHUNDEF;
 
-    if (localizing) {
+    if (UNLIKELY(localizing)) {
        MAGIC *mg;
        HV *stash;
 
@@ -2882,7 +2885,7 @@ PP(pp_aelem)
                1));
            RETURN;
        }
-       if (localizing) {
+       if (UNLIKELY(localizing)) {
            if (preeminent)
                save_aelem(av, elem, svp);
            else
@@ -2978,7 +2981,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
 
     PERL_ARGS_ASSERT_METHOD_COMMON;
 
-    if (!sv)
+    if (UNLIKELY(!sv))
        undefined:
        Perl_croak(aTHX_ "Can't call method \"%"SVf"\" on an undefined value",
                   SVfARG(meth));
diff --git a/scope.c b/scope.c
index de90b1d..07f24b7 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -88,7 +88,7 @@ void
 Perl_push_scope(pTHX)
 {
     dVAR;
-    if (PL_scopestack_ix == PL_scopestack_max) {
+    if (UNLIKELY(PL_scopestack_ix == PL_scopestack_max)) {
        PL_scopestack_max = GROW(PL_scopestack_max);
        Renew(PL_scopestack, PL_scopestack_max, I32);
 #ifdef DEBUGGING
@@ -164,7 +164,7 @@ Perl_free_tmps(pTHX)
 #ifdef PERL_POISON
        PoisonWith(PL_tmps_stack + PL_tmps_ix + 1, 1, SV *, 0xAB);
 #endif
-       if (sv && sv != &PL_sv_undef) {
+       if (LIKELY(sv && sv != &PL_sv_undef)) {
            SvTEMP_off(sv);
            SvREFCNT_dec_NN(sv);                /* note, can modify tmps_ix!!! */
        }
@@ -214,7 +214,7 @@ Perl_save_scalar(pTHX_ GV *gv)
 
     PERL_ARGS_ASSERT_SAVE_SCALAR;
 
-    if (SvGMAGICAL(*sptr)) {
+    if (UNLIKELY(SvGMAGICAL(*sptr))) {
         PL_localizing = 1;
         (void)mg_get(*sptr);
         PL_localizing = 0;
@@ -321,13 +321,13 @@ Perl_save_ary(pTHX_ GV *gv)
 
     PERL_ARGS_ASSERT_SAVE_ARY;
 
-    if (!AvREAL(oav) && AvREIFY(oav))
+    if (UNLIKELY(!AvREAL(oav) && AvREIFY(oav)))
        av_reify(oav);
     save_pushptrptr(SvREFCNT_inc_simple_NN(gv), oav, SAVEt_AV);
 
     GvAV(gv) = NULL;
     av = GvAVn(gv);
-    if (SvMAGIC(oav))
+    if (UNLIKELY(SvMAGIC(oav)))
        mg_localize(MUTABLE_SV(oav), MUTABLE_SV(av), TRUE);
     return av;
 }
@@ -346,7 +346,7 @@ Perl_save_hash(pTHX_ GV *gv)
 
     GvHV(gv) = NULL;
     hv = GvHVn(gv);
-    if (SvMAGIC(ohv))
+    if (UNLIKELY(SvMAGIC(ohv)))
        mg_localize(MUTABLE_SV(ohv), MUTABLE_SV(hv), TRUE);
     return hv;
 }
@@ -400,7 +400,7 @@ Perl_save_int(pTHX_ int *intp)
 
     PERL_ARGS_ASSERT_SAVE_INT;
 
-    if ((int)(type >> SAVE_TIGHT_SHIFT) != i) {
+    if (UNLIKELY((int)(type >> SAVE_TIGHT_SHIFT) != i)) {
         SS_ADD_INT(i);
         type = SAVEt_INT;
         size++;
@@ -447,7 +447,7 @@ Perl_save_I32(pTHX_ I32 *intp)
 
     PERL_ARGS_ASSERT_SAVE_I32;
 
-    if ((I32)(type >> SAVE_TIGHT_SHIFT) != i) {
+    if (UNLIKELY((I32)(type >> SAVE_TIGHT_SHIFT) != i)) {
         SS_ADD_INT(i);
         type = SAVEt_I32;
         size++;
@@ -559,7 +559,7 @@ Perl_save_clearsv(pTHX_ SV **svp)
 
     ASSERT_CURPAD_ACTIVE("save_clearsv");
     SvPADSTALE_off(*svp); /* mark lexical as active */
-    if ((offset_shifted >> SAVE_TIGHT_SHIFT) != offset) {
+    if (UNLIKELY((offset_shifted >> SAVE_TIGHT_SHIFT) != offset)) {
        Perl_croak(aTHX_ "panic: pad offset %"UVuf" out of range (%p-%p)",
                   offset, svp, PL_curpad);
     }
@@ -681,7 +681,7 @@ Perl_save_aelem_flags(pTHX_ AV *av, SSize_t idx, SV **sptr,
     SS_ADD_END(4);
     /* The array needs to hold a reference count on its new element, so it
        must be AvREAL. */
-    if (!AvREAL(av) && AvREIFY(av))
+    if (UNLIKELY(!AvREAL(av) && AvREIFY(av)))
        av_reify(av);
     save_scalar_at(sptr, flags); /* XXX - FIXME - see #60360 */
     if (flags & SAVEf_KEEPOLDELEM)
@@ -691,7 +691,7 @@ Perl_save_aelem_flags(pTHX_ AV *av, SSize_t idx, SV **sptr,
      * won't actually be stored in the array - so it won't get
      * reaped when the localize ends. Ensure it gets reaped by
      * mortifying it instead. DAPM */
-    if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied))
+    if (UNLIKELY(SvTIED_mg((const SV *)av, PERL_MAGIC_tied)))
        sv_2mortal(sv);
 }
 
@@ -720,7 +720,7 @@ Perl_save_helem_flags(pTHX_ HV *hv, SV *key, SV **sptr, const U32 flags)
      * won't actually be stored in the hash - so it won't get
      * reaped when the localize ends. Ensure it gets reaped by
      * mortifying it instead. DAPM */
-    if (SvTIED_mg((const SV *)hv, PERL_MAGIC_tied))
+    if (UNLIKELY(SvTIED_mg((const SV *)hv, PERL_MAGIC_tied)))
        sv_2mortal(sv);
 }
 
@@ -745,7 +745,7 @@ Perl_save_alloc(pTHX_ I32 size, I32 pad)
     const UV elems = 1 + ((size + pad - 1) / sizeof(*PL_savestack));
     const UV elems_shifted = elems << SAVE_TIGHT_SHIFT;
 
-    if ((elems_shifted >> SAVE_TIGHT_SHIFT) != elems)
+    if (UNLIKELY((elems_shifted >> SAVE_TIGHT_SHIFT) != elems))
        Perl_croak(aTHX_
             "panic: save_alloc elems %"UVuf" out of range (%"IVdf"-%"IVdf")",
                   elems, (IV)size, (IV)pad);
@@ -798,7 +798,7 @@ Perl_leave_scope(pTHX_ I32 base)
     arg1.any_ptr = NULL;
     arg2.any_ptr = NULL;
 
-    if (base < -1)
+    if (UNLIKELY(base < -1))
        Perl_croak(aTHX_ "panic: corrupt saved stack index %ld", (long) base);
     DEBUG_l(Perl_deb(aTHX_ "savestack: releasing items %ld -> %ld\n",
                        (long)PL_savestack_ix, (long)base));
@@ -833,7 +833,7 @@ Perl_leave_scope(pTHX_ I32 base)
        switch (type) {
        case SAVEt_ITEM:                        /* normal string */
            sv_replace(ARG1_SV, ARG0_SV);
-            if (SvSMAGICAL(ARG1_SV)) {
+            if (UNLIKELY(SvSMAGICAL(ARG1_SV))) {
                 PL_localizing = 2;
                 mg_set(ARG1_SV);
                 PL_localizing = 0;
@@ -855,7 +855,7 @@ Perl_leave_scope(pTHX_ I32 base)
            SV * const sv = *svp;
            *svp = ARG0_SV;
            SvREFCNT_dec(sv);
-            if (SvSMAGICAL(ARG0_SV)) {
+            if (UNLIKELY(SvSMAGICAL(ARG0_SV))) {
                 PL_localizing = 2;
                 mg_set(ARG0_SV);
                 PL_localizing = 0;
@@ -913,7 +913,7 @@ Perl_leave_scope(pTHX_ I32 base)
        case SAVEt_AV:                          /* array reference */
            SvREFCNT_dec(GvAV(ARG1_GV));
            GvAV(ARG1_GV) = ARG0_AV;
-            if (SvSMAGICAL(ARG0_SV)) {
+            if (UNLIKELY(SvSMAGICAL(ARG0_SV))) {
                 PL_localizing = 2;
                 mg_set(ARG0_SV);
                 PL_localizing = 0;
@@ -923,7 +923,7 @@ Perl_leave_scope(pTHX_ I32 base)
        case SAVEt_HV:                          /* hash reference */
            SvREFCNT_dec(GvHV(ARG1_GV));
            GvHV(ARG1_GV) = ARG0_HV;
-            if (SvSMAGICAL(ARG0_SV)) {
+            if (UNLIKELY(SvSMAGICAL(ARG0_SV))) {
                 PL_localizing = 2;
                 mg_set(ARG0_SV);
                 PL_localizing = 0;
@@ -944,7 +944,7 @@ Perl_leave_scope(pTHX_ I32 base)
 #ifdef NO_TAINT_SUPPORT
             PERL_UNUSED_VAR(was);
 #else
-           if (ARG0_PTR == &(TAINT_get)) {
+           if (UNLIKELY(ARG0_PTR == &(TAINT_get))) {
                /* If we don't update <was>, to reflect what was saved on the
                 * stack for PL_tainted, then we will overwrite this attempt to
                 * restore it when we exit this routine.  Note that this won't
@@ -1154,12 +1154,12 @@ Perl_leave_scope(pTHX_ I32 base)
            break;
        case SAVEt_AELEM:               /* array element */
            svp = av_fetch(ARG2_AV, arg1.any_iv, 1);
-           if (!AvREAL(ARG2_AV) && AvREIFY(ARG2_AV)) /* undo reify guard */
+           if (UNLIKELY(!AvREAL(ARG2_AV) && AvREIFY(ARG2_AV))) /* undo reify guard */
                SvREFCNT_dec(ARG0_SV);
-           if (svp) {
+           if (LIKELY(svp)) {
                SV * const sv = *svp;
-               if (sv && sv != &PL_sv_undef) {
-                   if (SvTIED_mg((const SV *)ARG2_AV, PERL_MAGIC_tied))
+               if (LIKELY(sv && sv != &PL_sv_undef)) {
+                   if (UNLIKELY(SvTIED_mg((const SV *)ARG2_AV, PERL_MAGIC_tied)))
                        SvREFCNT_inc_void_NN(sv);
                     refsv = ARG2_SV;
                    goto restore_sv;
@@ -1172,11 +1172,11 @@ Perl_leave_scope(pTHX_ I32 base)
         {
            HE * const he = hv_fetch_ent(ARG2_HV, ARG1_SV, 1, 0);
            SvREFCNT_dec(ARG1_SV);
-           if (he) {
+           if (LIKELY(he)) {
                const SV * const oval = HeVAL(he);
-               if (oval && oval != &PL_sv_undef) {
+               if (LIKELY(oval && oval != &PL_sv_undef)) {
                    svp = &HeVAL(he);
-                   if (SvTIED_mg((const SV *)ARG2_HV, PERL_MAGIC_tied))
+                   if (UNLIKELY(SvTIED_mg((const SV *)ARG2_HV, PERL_MAGIC_tied)))
                        SvREFCNT_inc_void(*svp);
                    refsv = ARG2_SV; /* what to refcnt_dec */
                    goto restore_sv;
@@ -1215,7 +1215,7 @@ Perl_leave_scope(pTHX_ I32 base)
            break;
        case SAVEt_COMPPAD:
            PL_comppad = (PAD*)ARG0_PTR;
-           if (PL_comppad)
+           if (LIKELY(PL_comppad))
                PL_curpad = AvARRAY(PL_comppad);
            else
                PL_curpad = NULL;
diff --git a/scope.h b/scope.h
index 996230c..0dce9d6 100644 (file)
--- a/scope.h
+++ b/scope.h
@@ -98,8 +98,8 @@
  * macros */
 #define SS_MAXPUSH 4
 
-#define SSCHECK(need) if (PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max) savestack_grow()
-#define SSGROW(need) if (PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max) savestack_grow_cnt(need + SS_MAXPUSH)
+#define SSCHECK(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max)) savestack_grow()
+#define SSGROW(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max)) savestack_grow_cnt(need + SS_MAXPUSH)
 #define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i))
 #define SSPUSHLONG(i) (PL_savestack[PL_savestack_ix++].any_long = (long)(i))
 #define SSPUSHBOOL(p) (PL_savestack[PL_savestack_ix++].any_bool = (p))
     ix += (need);                                               \
     PL_savestack_ix = ix;                                       \
     assert(ix <= PL_savestack_max);                             \
-    if ((ix + SS_MAXPUSH) > PL_savestack_max) savestack_grow(); \
+    if (UNLIKELY((ix + SS_MAXPUSH) > PL_savestack_max)) savestack_grow(); \
     assert(PL_savestack_ix + SS_MAXPUSH <= PL_savestack_max);
 
 #define SS_ADD_INT(i)   ((ssp++)->any_i32 = (I32)(i))
diff --git a/sv.h b/sv.h
index 396a36b..8760ec4 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1362,7 +1362,7 @@ sv_force_normal does nothing.
                     assert(SvTYPE(sv) >= SVt_PV);                      \
                     if (SvLEN(sv)) {                                   \
                         assert(!SvROK(sv));                            \
-                        if(SvOOK(sv)) {                                \
+                        if(UNLIKELY(SvOOK(sv))) {                      \
                             STRLEN zok;                                \
                             SvOOK_offset(sv, zok);                     \
                             SvPV_set(sv, SvPVX_mutable(sv) - zok);     \
@@ -1480,13 +1480,13 @@ attention to precisely which outputs are influenced by which inputs.
 #else
 #   define SvTAINTED(sv)         (SvMAGICAL(sv) && sv_tainted(sv))
 #endif
-#define SvTAINTED_on(sv)  STMT_START{ if(TAINTING_get){sv_taint(sv);}   }STMT_END
-#define SvTAINTED_off(sv) STMT_START{ if(TAINTING_get){sv_untaint(sv);} }STMT_END
+#define SvTAINTED_on(sv)  STMT_START{ if(UNLIKELY(TAINTING_get)){sv_taint(sv);}   }STMT_END
+#define SvTAINTED_off(sv) STMT_START{ if(UNLIKELY(TAINTING_get)){sv_untaint(sv);} }STMT_END
 
 #define SvTAINT(sv)                    \
     STMT_START {                       \
-       if (TAINTING_get) {             \
-           if (TAINT_get)              \
+       if (UNLIKELY(TAINTING_get)) {   \
+           if (UNLIKELY(TAINT_get))    \
                SvTAINTED_on(sv);       \
        }                               \
     } STMT_END
@@ -1756,9 +1756,9 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>.
 #define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
 #define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
 
-#define SvTRUE(sv)        ((sv) && (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv))))
-#define SvTRUE_nomg(sv)   ((sv) && (                                SvTRUE_common(sv, sv_2bool_nomg(sv))))
-#define SvTRUE_NN(sv)              (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv)))
+#define SvTRUE(sv)        (LIKELY(sv) && (UNLIKELY(SvGMAGICAL(sv)) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_nomg(sv)   (LIKELY(sv) && (                                SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_NN(sv)              (UNLIKELY(SvGMAGICAL(sv)) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv)))
 #define SvTRUE_nomg_NN(sv) (                                        SvTRUE_common(sv, sv_2bool_nomg(sv)))
 #define SvTRUE_common(sv,fallback) (                   \
       !SvOK(sv)                                                \
@@ -2061,19 +2061,19 @@ alternative is to call C<sv_grow> if you are not sure of the type of SV.
 #define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv)
 #define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv)
 
-#define SvGETMAGIC(x) ((void)(SvGMAGICAL(x) && mg_get(x)))
-#define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
+#define SvGETMAGIC(x) ((void)(UNLIKELY(SvGMAGICAL(x)) && mg_get(x)))
+#define SvSETMAGIC(x) STMT_START { if (UNLIKELY(SvSMAGICAL(x))) mg_set(x); } STMT_END
 
 #define SvSetSV_and(dst,src,finally) \
        STMT_START {                                    \
-           if ((dst) != (src)) {                       \
+           if (LIKELY((dst) != (src))) {               \
                sv_setsv(dst, src);                     \
                finally;                                \
            }                                           \
        } STMT_END
 #define SvSetSV_nosteal_and(dst,src,finally) \
        STMT_START {                                    \
-           if ((dst) != (src)) {                       \
+           if (LIKELY((dst) != (src))) {                       \
                sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV);   \
                finally;                                \
            }                                           \