This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
More branch prediction hints for sv_setsv_flags
authorSteffen Mueller <smueller@cpan.org>
Sun, 30 Nov 2014 16:26:38 +0000 (17:26 +0100)
committerSteffen Mueller <smueller@cpan.org>
Mon, 1 Dec 2014 07:36:36 +0000 (08:36 +0100)
Dave's cachegrind benchmark says "small win":

          REF   THIS
       ------ ------
    Ir 105.35 105.91
    Dr 104.45 105.42
    Dw 105.42 105.17
  COND 104.33 104.58
   IND 107.04 106.76

COND_m 98.55  110.11
 IND_m 110.09 111.08

sv.c
sv.h

diff --git a/sv.c b/sv.c
index d98e55c..7384221 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -4270,7 +4270,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
 
     PERL_ARGS_ASSERT_SV_SETSV_FLAGS;
 
-    if (sstr == dstr)
+    if (UNLIKELY( sstr == dstr ))
        return;
 
     if (SvIS_FREED(dstr)) {
@@ -4278,7 +4278,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
                   " to a freed scalar %p", SVfARG(sstr), (void *)dstr);
     }
     SV_CHECK_THINKFIRST_COW_DROP(dstr);
-    if (!sstr)
+    if (UNLIKELY( !sstr ))
        sstr = &PL_sv_undef;
     if (SvIS_FREED(sstr)) {
        Perl_croak(aTHX_ "panic: attempt to copy freed scalar %p to %p",
@@ -4292,7 +4292,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
     switch (stype) {
     case SVt_NULL:
       undef_sstr:
-       if (dtype != SVt_PVGV && dtype != SVt_PVLV) {
+       if (LIKELY( dtype != SVt_PVGV && dtype != SVt_PVLV )) {
            (void)SvOK_off(dstr);
            return;
        }
@@ -4335,7 +4335,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
        break;
 
     case SVt_NV:
-       if (SvNOK(sstr)) {
+       if (LIKELY( SvNOK(sstr) )) {
            switch (dtype) {
            case SVt_NULL:
            case SVt_IV:
@@ -4424,7 +4424,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
     dtype = SvTYPE(dstr);
     sflags = SvFLAGS(sstr);
 
-    if (dtype == SVt_PVCV) {
+    if (UNLIKELY( dtype == SVt_PVCV )) {
        /* Assigning to a subroutine sets the prototype.  */
        if (SvOK(sstr)) {
            STRLEN len;
@@ -10039,7 +10039,7 @@ Perl_newSVrv(pTHX_ SV *const rv, const char *const classname)
 
     SV_CHECK_THINKFIRST_COW_DROP(rv);
 
-    if (SvTYPE(rv) >= SVt_PVMG) {
+    if (UNLIKELY( SvTYPE(rv) >= SVt_PVMG )) {
        const U32 refcnt = SvREFCNT(rv);
        SvREFCNT(rv) = 0;
        sv_clear(rv);
diff --git a/sv.h b/sv.h
index ec5726d..303bbfa 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -349,7 +349,7 @@ perform the upgrade if necessary.  See C<svtype>.
 /* Sadly there are some parts of the core that have pointers to already-freed
    SV heads, and rely on being able to tell that they are now free. So mark
    them all by using a consistent macro.  */
-#define SvIS_FREED(sv) ((sv)->sv_flags == SVTYPEMASK)
+#define SvIS_FREED(sv) UNLIKELY(((sv)->sv_flags == SVTYPEMASK))
 
 /* this is defined in this peculiar way to avoid compiler warnings.
  * See the <20121213131428.GD1842@iabyn.com> thread in p5p */