summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2005-04-28 11:22:15 +0000
committerNicholas Clark <nick@ccl4.org>2005-04-28 11:22:15 +0000
commit8bd4d4c5ee440ccae167e2a7f5bf6f74ff02916b (patch)
treea0c18027ed2df90e52cd3274c69bcff795b71d6f
parent9dcb96024af7087d05f03617e991e04fef9ff716 (diff)
downloadperl-8bd4d4c5ee440ccae167e2a7f5bf6f74ff02916b.tar.gz
Add a new macro SvPV_free() which undoes OOK and free()s the PVX(),
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
-rw-r--r--perl.c3
-rw-r--r--pp.c7
-rw-r--r--pp_ctl.c4
-rw-r--r--pp_hot.c7
-rw-r--r--sv.c32
-rw-r--r--sv.h12
6 files changed, 29 insertions, 36 deletions
diff --git a/perl.c b/perl.c
index dfd5f83355..96f5b2dba2 100644
--- 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 ca4f61d4cb..4500c575de 100644
--- 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);
}
diff --git a/pp_ctl.c b/pp_ctl.c
index 2db8d7e051..783a59a7b5 100644
--- 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));
diff --git a/pp_hot.c b/pp_hot.c
index 767188be9a..97d7e28868 100644
--- 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 5353df2ac2..f2e6206729 100644
--- 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 cf71f03430..869cd422b5 100644
--- 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