This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
reduce cost of SvVALID()
authorDavid Mitchell <davem@iabyn.com>
Sun, 13 Nov 2016 14:59:32 +0000 (14:59 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sun, 13 Nov 2016 15:27:34 +0000 (15:27 +0000)
Now that SvVALID() no longer just checks an SV flag, but instead checks
for the existence of a certain type of magic, avoid using this more
expensive macro when its not really needed.

Also, and an extra flag test to SvVALID() to make it fail quicker.

gv.h
sv.c
sv.h
util.c

diff --git a/gv.h b/gv.h
index 0b08b68..488f2cc 100644 (file)
--- a/gv.h
+++ b/gv.h
@@ -52,7 +52,6 @@ struct gp {
     (*({ GV * const _gvname_hek = (GV *) (gv);                         \
           assert(isGV_with_GP(_gvname_hek));                           \
           assert(SvTYPE(_gvname_hek) == SVt_PVGV || SvTYPE(_gvname_hek) >= SVt_PVLV); \
-          assert(!SvVALID((SV*)_gvname_hek));                          \
           &(GvXPVGV(_gvname_hek)->xiv_u.xivu_namehek);                 \
         }))
 #  define GvNAME_get(gv)       ({ assert(GvNAME_HEK(gv)); (char *)HEK_KEY(GvNAME_HEK(gv)); })
diff --git a/sv.c b/sv.c
index 2257708..7bc97f3 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2449,8 +2449,8 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags)
     }
 
     if (SvVALID(sv) || isREGEXP(sv)) {
-       /* FBMs use the space for SvIVX and SvNVX for other purposes, and use
-          the same flag bit as SVf_IVisUV, so must not let them cache IVs.
+        /* FBMs use the space for SvIVX and SvNVX for other purposes, so
+           must not let them cache IVs.
           In practice they are extremely unlikely to actually get anywhere
           accessible by user Perl code - the only way that I'm aware of is when
           a constant subroutine which is used as the second argument to index.
@@ -6626,7 +6626,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                /* If we're in a stash, we don't own a reference to it.
                 * However it does have a back reference to us, which
                 * needs to be cleared.  */
-               if (!SvVALID(sv) && (stash = GvSTASH(sv)))
+               if ((stash = GvSTASH(sv)))
                        sv_del_backref(MUTABLE_SV(stash), sv);
            }
            /* FIXME. There are probably more unreferenced pointers to SVs
diff --git a/sv.h b/sv.h
index b97c175..a9aca37 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1118,7 +1118,8 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 /* Does the SV have a Boyer-Moore table attached as magic?
  * 'VALID' is a poor name, but is kept for historical reasons.  */
 #define SvVALID(_svvalid) (                                  \
-               SvSMAGICAL(_svvalid)                          \
+               SvPOKp(_svvalid)                              \
+            && SvSMAGICAL(_svvalid)                          \
             && SvMAGIC(_svvalid)                             \
             && (SvMAGIC(_svvalid)->mg_type == PERL_MAGIC_bm  \
                 || mg_find(_svvalid, PERL_MAGIC_bm))         \
diff --git a/util.c b/util.c
index fb2ddec..88f1700 100644 (file)
--- a/util.c
+++ b/util.c
@@ -811,7 +811,8 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
     const unsigned char *little = (const unsigned char *)SvPV_const(littlestr,l);
     STRLEN littlelen = l;
     const I32 multiline = flags & FBMrf_MULTILINE;
-    bool tail = SvVALID(littlestr) ? cBOOL(SvTAIL(littlestr)) : FALSE;
+    bool valid = SvVALID(littlestr);
+    bool tail = valid ? cBOOL(SvTAIL(littlestr)) : FALSE;
 
     PERL_ARGS_ASSERT_FBM_INSTR;
 
@@ -945,7 +946,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
        return NULL;
     }
 
-    if (!SvVALID(littlestr)) {
+    if (!valid) {
         /* not compiled; use Perl_ninstr() instead */
        char * const b = ninstr((char*)big,(char*)bigend,
                         (char*)little, (char*)little + littlelen);