Add a new macro SvPV_free() which undoes OOK and free()s the PVX(),
Nicholas Clark [Thu, 28 Apr 2005 11:22:15 +0000 (11:22 +0000)]
becase there's a lot of code around that calls SvOOK_off(), memmov()s
the buffer, then promptly free()s it. So avoid the needless memmov().

p4raw-id: //depot/perl@24348

perl.c
pp.c
pp_ctl.c
pp_hot.c
sv.c
sv.h

diff --git a/perl.c b/perl.c
index dfd5f83..96f5b2d 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -957,8 +957,7 @@ perl_destruct(pTHXx)
            }
        }
        /* we know that type >= SVt_PV */
-       SvOOK_off(PL_mess_sv);
-       Safefree(SvPVX(PL_mess_sv));
+       SvPV_free(PL_mess_sv);
        Safefree(SvANY(PL_mess_sv));
        Safefree(PL_mess_sv);
        PL_mess_sv = Nullsv;
diff --git a/pp.c b/pp.c
index ca4f61d..4500c57 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -175,9 +175,7 @@ PP(pp_rv2gv)
                    if (SvTYPE(sv) < SVt_RV)
                        sv_upgrade(sv, SVt_RV);
                    if (SvPVX(sv)) {
-                       SvOOK_off(sv);          /* backoff */
-                       if (SvLEN(sv))
-                           Safefree(SvPVX(sv));
+                       SvPV_free(sv);
                        SvLEN_set(sv, 0);
                         SvCUR_set(sv, 0);
                    }
@@ -825,8 +823,7 @@ PP(pp_undef)
        break;
     default:
        if (SvTYPE(sv) >= SVt_PV && SvPVX(sv) && SvLEN(sv)) {
-           SvOOK_off(sv);
-           Safefree(SvPVX(sv));
+           SvPV_free(sv);
            SvPV_set(sv, Nullch);
            SvLEN_set(sv, 0);
        }
index 2db8d7e..783a59a 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -240,9 +240,7 @@ PP(pp_substcont)
            } else
 #endif
            {
-               SvOOK_off(targ);
-               if (SvLEN(targ))
-                   Safefree(SvPVX(targ));
+               SvPV_free(targ);
            }
            SvPV_set(targ, SvPVX(dstr));
            SvCUR_set(targ, SvCUR(dstr));
index 767188b..97d7e28 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2251,9 +2251,7 @@ PP(pp_subst)
        } else
 #endif
        {
-           SvOOK_off(TARG);
-           if (SvLEN(TARG))
-               Safefree(SvPVX(TARG));
+           SvPV_free(TARG);
        }
        SvPV_set(TARG, SvPVX(dstr));
        SvCUR_set(TARG, SvCUR(dstr));
@@ -2934,8 +2932,7 @@ Perl_vivify_ref(pTHX_ SV *sv, U32 to_what)
        if (SvTYPE(sv) < SVt_RV)
            sv_upgrade(sv, SVt_RV);
        else if (SvTYPE(sv) >= SVt_PV) {
-           SvOOK_off(sv);
-           Safefree(SvPVX(sv));
+           SvPV_free(sv);
             SvLEN_set(sv, 0);
            SvCUR_set(sv, 0);
        }
diff --git a/sv.c b/sv.c
index 5353df2..f2e6206 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1906,11 +1906,13 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
        /* to here.  */
        /* XXX? Only SVt_NULL is ever upgraded to AV or HV?  */
        assert(!pv);
-       /* FIXME. Should be able to remove this if the above assertion is
-          genuinely always true.  */
-       (void)SvOOK_off(sv);
-       if (pv)
-           Safefree(pv);
+       /* FIXME. Should be able to remove all this if()... if the above
+          assertion is genuinely always true.  */
+       if(SvOOK(sv)) {
+           pv -= iv;
+           SvFLAGS(sv) &= ~SVf_OOK;
+       }
+       Safefree(pv);
        SvPV_set(sv, (char*)0);
        SvMAGIC_set(sv, magic);
        SvSTASH_set(sv, stash);
@@ -4416,16 +4418,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                return;
            }
            if (SvPVX(dstr)) {
-               if (SvLEN(dstr)) {
-                   /* Unwrap the OOK offset by hand, to save a needless
-                      memmove on memory that's about to be free()d.  */
-                   char *pv = SvPVX(dstr);
-                   if (SvOOK(dstr)) {
-                       pv -= SvIVX(dstr);
-                       SvFLAGS(dstr) &= ~SVf_OOK;
-                   }
-                   Safefree(pv);
-               }
+               SvPV_free(dstr);
                SvLEN_set(dstr, 0);
                 SvCUR_set(dstr, 0);
            }
@@ -4843,9 +4836,8 @@ Perl_sv_usepvn(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
        (void)SvOK_off(sv);
        return;
     }
-    (void)SvOOK_off(sv);
-    if (SvPVX(sv) && SvLEN(sv))
-       Safefree(SvPVX(sv));
+    if (SvPVX(sv))
+       SvPV_free(sv);
     Renew(ptr, len+1, char);
     SvPV_set(sv, ptr);
     SvCUR_set(sv, len);
@@ -8493,9 +8485,7 @@ Perl_newSVrv(pTHX_ SV *rv, const char *classname)
     if (SvTYPE(rv) < SVt_RV)
        sv_upgrade(rv, SVt_RV);
     else if (SvTYPE(rv) > SVt_RV) {
-       SvOOK_off(rv);
-       if (SvPVX(rv) && SvLEN(rv))
-           Safefree(SvPVX(rv));
+       SvPV_free(rv);
        SvCUR_set(rv, 0);
        SvLEN_set(rv, 0);
     }
diff --git a/sv.h b/sv.h
index cf71f03..869cd42 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -842,6 +842,18 @@ in gv.h: */
                   SvPV_renew(sv, _lEnGtH); \
                 } STMT_END
 
+#define SvPV_free(sv) \
+       STMT_START { assert(SvTYPE(sv) >= SVt_PV);      \
+               if (SvLEN(sv)) {                        \
+                   if(SvOOK(sv)) {                     \
+                     Safefree(SvPVX(sv) - SvIVX(sv));  \
+                     SvFLAGS(sv) &= ~SVf_OOK;          \
+                   } else {                            \
+                     Safefree(SvPVX(sv));              \
+                   }                                   \
+               }                                       \
+       } STMT_END
+
 #define BmRARE(sv)     ((XPVBM*)  SvANY(sv))->xbm_rare
 #define BmUSEFUL(sv)   ((XPVBM*)  SvANY(sv))->xbm_useful
 #define BmPREVIOUS(sv) ((XPVBM*)  SvANY(sv))->xbm_previous