This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
SvTRUE(): special-case immortals
authorDavid Mitchell <davem@iabyn.com>
Wed, 12 Jul 2017 13:48:34 +0000 (14:48 +0100)
committerDavid Mitchell <davem@iabyn.com>
Thu, 27 Jul 2017 10:30:22 +0000 (11:30 +0100)
Immortal SVs like PL_sv_no will often be used as an argument to
SvTRUE(); however it turns out that SvTRUE() is very inefficient at
determining the truth value of such SVs. For example, for PL_sv_yes
it does all the following test-and-branches to decide that it is indeed
true:

    SvOK()
    SvPOK()
    SvANY()
    xpv_cur > 1
    xpv_cur
    sv_u.svu_pv != '0'

After the previous commit it is now much cheaper to  test whether an SV is
one of the four "interpreter" immortals PL_sv_yes, PL_sv_undef, PL_sv_no,
PL_sv_zero.

So this commit adds an extra check at the beginning of SvTRUE(): if it's
an immortal, return whether it's a true immortal (i.e. PL_sv_yes).

SvTRUE_nomg_NN(&PL_sv_yes) now only requires one test-and-branch plus an
address comparison. The other immortals are similarly improved.

Non-immortals now require one extra test-and-branch.

sv.h

diff --git a/sv.h b/sv.h
index 15b8547..b80aba1 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1768,7 +1768,9 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 #define SvTRUE_nomg_NN(sv) (SvTRUE_common(sv, sv_2bool_nomg(sv)))
 
 #define SvTRUE_common(sv,fallback) (                   \
-      !SvOK(sv)                                                \
+      SvIMMORTAL_INTERP(sv)                             \
+        ? SvIMMORTAL_TRUE(sv)                           \
+    : !SvOK(sv)                                                \
        ? 0                                             \
     : SvPOK(sv)                                                \
        ? SvPVXtrue(sv)                                 \