Skip to content

Commit d002fa4

Browse files
committed
Perl_sv_can_can_swipe_pv_buf - extracts swipe test from Perl_sv_setsv_flags
Perl_sv_setsv_flags contains the canonical logic for determining the best method for assigning the string value from a source SV to a destination SV: * "Swipe" the string buffer from the source SV * COW the source SV's string buffer * Do a full copy This commit extracts the "can the swipe the buffer" tests out into a new macro (`S_SvPV_can_swipe_buf`) within sv.c. It has two users: * Perl_sv_setsv_flags - so that the logic remains inline in this hot code * Perl_sv_can_can_swipe_pv_buf - a new function `pp_reverse` will shortly make use of the new function to avoid unnecessary string copies when doing a reversal in scalar context.
1 parent 9c5f1c4 commit d002fa4

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

embed.fnc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,6 +3114,8 @@ Adp |SV * |sv_bless |NN SV * const sv \
31143114
Cdmp |bool |sv_2bool |NN SV * const sv
31153115
Cdp |bool |sv_2bool_flags |NN SV *sv \
31163116
|I32 flags
3117+
Cp |bool |sv_can_swipe_pv_buf \
3118+
|NN SV *sv
31173119
Adp |bool |sv_cat_decode |NN SV *dsv \
31183120
|NN SV *encoding \
31193121
|NN SV *ssv \

embed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@
707707
# define sv_2uv_flags(a,b) Perl_sv_2uv_flags(aTHX_ a,b)
708708
# define sv_backoff Perl_sv_backoff
709709
# define sv_bless(a,b) Perl_sv_bless(aTHX_ a,b)
710+
# define sv_can_swipe_pv_buf(a) Perl_sv_can_swipe_pv_buf(aTHX_ a)
710711
# define sv_cat_decode(a,b,c,d,e,f) Perl_sv_cat_decode(aTHX_ a,b,c,d,e,f)
711712
# define sv_catpv(a,b) Perl_sv_catpv(aTHX_ a,b)
712713
# define sv_catpv_flags(a,b,c) Perl_sv_catpv_flags(aTHX_ a,b,c)

proto.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sv.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4187,6 +4187,33 @@ S_sv_buf_to_rw(pTHX_ SV *sv)
41874187
# define sv_buf_to_rw(sv) NOOP
41884188
#endif
41894189

4190+
4191+
/* The test in this macro was extracted from Perl_sv_setsv_flags so that it
4192+
* could be used elsewhere. */
4193+
#define S_SvPV_can_swipe_buf(ssv, sflags, cur, len) \
4194+
(( /* Either ... */ \
4195+
/* slated for free anyway (and not COW)? */ \
4196+
((sflags & (SVs_TEMP|SVf_IsCOW)) == SVs_TEMP) \
4197+
/* or a swipable TARG */ \
4198+
|| ((sflags & \
4199+
(SVs_PADTMP|SVf_READONLY|SVf_PROTECT|SVf_IsCOW))== SVs_PADTMP \
4200+
/* whose buffer is worth stealing */ \
4201+
&& CHECK_COWBUF_THRESHOLD(cur,len) \
4202+
) \
4203+
) && !(sflags & SVf_OOK) /* and not involved in OOK hack? */ \
4204+
&& (SvREFCNT(ssv) == 1) /* and no other references to it? */ \
4205+
&& len /* and really is a string */ \
4206+
)
4207+
4208+
/* Perl_sv_can_swipe_pv_buf was originally created for pp_reverse. */
4209+
bool
4210+
Perl_sv_can_swipe_pv_buf(pTHX_ SV *sv)
4211+
{
4212+
PERL_ARGS_ASSERT_SV_CAN_SWIPE_PV_BUF;
4213+
assert(sv);
4214+
return S_SvPV_can_swipe_buf(sv, SvFLAGS(sv), SvCUR(sv), SvLEN(sv)) ? true : false;
4215+
}
4216+
41904217
void
41914218
Perl_sv_setsv_flags(pTHX_ SV *dsv, SV* ssv, const I32 flags)
41924219
{
@@ -4593,23 +4620,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dsv, SV* ssv, const I32 flags)
45934620
and doing it now facilitates the COW check. */
45944621
(void)SvPOK_only(dsv);
45954622

4596-
if (
4597-
( /* Either ... */
4598-
/* slated for free anyway (and not COW)? */
4599-
(sflags & (SVs_TEMP|SVf_IsCOW)) == SVs_TEMP
4600-
/* or a swipable TARG */
4601-
|| ((sflags &
4602-
(SVs_PADTMP|SVf_READONLY|SVf_PROTECT|SVf_IsCOW))
4603-
== SVs_PADTMP
4604-
/* whose buffer is worth stealing */
4605-
&& CHECK_COWBUF_THRESHOLD(cur,len)
4606-
)
4607-
) &&
4608-
!(sflags & SVf_OOK) && /* and not involved in OOK hack? */
4609-
(!(flags & SV_NOSTEAL)) &&
4610-
/* and we're allowed to steal temps */
4611-
SvREFCNT(ssv) == 1 && /* and no other references to it? */
4612-
len) /* and really is a string */
4623+
if ( !(flags & SV_NOSTEAL) && S_SvPV_can_swipe_buf(ssv, sflags, cur, len) )
46134624
{ /* Passes the swipe test. */
46144625
if (SvPVX_const(dsv)) /* we know that dtype >= SVt_PV */
46154626
SvPV_free(dsv);

0 commit comments

Comments
 (0)