Skip to content

Commit c77e852

Browse files
committed
de-mathom Perl_sv_taint() part 4 add SvTAINTTC() tailcall API
Perl_newSVnv/Perl_newSViv/Perl_newSVuv, currently have to save the fresh SV *, either on C stack, or in non volatile registers, around the possible Perl_sv_taint() fn call inside SvTAINT(). If Perl_sv_taint() returns its SV * argument, and assigns it back to the same C var, now these 3 performance critical SV allocator functions, after plucking the SV head from the arena, these 3 function never ever have to store the fresh SV * back to C stack for any reason during their execution. This optimization removes pop/push pairs of the C compiler saving non-volatile registers and restoring them at function entry and exit since after SvTAINTTC() change, NO variables AT ALL, have to be saved around any function calls in Perl_newSVnv/Perl_newSViv/Perl_newSVuv. Also the SV head *, after being delinked/removed from an areana, can now be stored through the whole function, in the x86 EAX/x64 RAX register, and pass through to the caller, without a final (non vol) reg to (vol retval reg) mov/copy cpu op. Remember eax/rax/retval registers, are always wiped after each fn call, but the refactoring of SvTAINTTC() conviently returns the SV * back to us, in the ABI return register, and we let the fresh SV * glide through on the "heavy" Perl_sv_taint() branch, from Perl_sv_taint() to Perl_newSViv()'s caller, without touching it, 0 machine code ops. Few code sites were changed from SvTAINT() to SvTAINTTC(), to keep this patch smaller, and the Perl_sv_set*vXXX() category of functions, all have void return types and can't be chained. Also the Perl_sv_taint() branch can be tail called or converted to a JMP insted of CALL, if the CC/OS/ABI wants to now. This is the final part of speeding up Perl_newSVnv/Perl_newSViv/Perl_newSVuv there is nothing else to remove or optimze.
1 parent 7f29878 commit c77e852

File tree

4 files changed

+24
-6
lines changed

4 files changed

+24
-6
lines changed

hv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,12 +1130,12 @@ Perl_hv_scalar(pTHX_ HV *hv)
11301130
if (u <= (UV)IV_MAX) {
11311131
SvIV_set(sv, (IV)u);
11321132
(void)SvIOK_only(sv);
1133-
SvTAINT(sv);
1133+
sv = SvTAINTTC(sv);
11341134
} else {
11351135
SvIV_set(sv, 0);
11361136
SvUV_set(sv, u);
11371137
(void)SvIOK_only_UV(sv);
1138-
SvTAINT(sv);
1138+
sv = SvTAINTTC(sv);
11391139
}
11401140

11411141
return sv;

sv.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10037,7 +10037,7 @@ Perl_newSVnv(pTHX_ const NV n)
1003710037
SvNV_set(sv, n);
1003810038
#endif
1003910039

10040-
SvTAINT(sv);
10040+
sv = SvTAINTTC(sv);
1004110041

1004210042
return sv;
1004310043
}
@@ -10073,7 +10073,7 @@ Perl_newSViv(pTHX_ const IV i)
1007310073
SET_SVANY_FOR_BODYLESS_IV(sv);
1007410074
sv->sv_u.svu_iv = i;
1007510075

10076-
SvTAINT(sv);
10076+
sv = SvTAINTTC(sv);
1007710077

1007810078
return sv;
1007910079
}
@@ -10175,7 +10175,7 @@ Perl_newSVuv(pTHX_ const UV u)
1017510175
SET_SVANY_FOR_BODYLESS_IV(sv);
1017610176
sv->sv_u.svu_uv = u;
1017710177

10178-
SvTAINT(sv);
10178+
sv = SvTAINTTC(sv);
1017910179

1018010180
return sv;
1018110181
}

sv.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,21 @@ inputs such as locale settings. C<SvTAINT> propagates that taintedness to
17211721
the outputs of an expression in a pessimistic fashion; i.e., without paying
17221722
attention to precisely which outputs are influenced by which inputs.
17231723
1724+
=cut
1725+
1726+
=for apidoc Cm|SV* sv|SvTAINTTC|SV* sv
1727+
Identical to C<SvTAINT>, except optimized for for C compilers to do tail calls.
1728+
Incoming arg I<sv> will be returned as the retval of I<SvTAINTTC>.
1729+
The return value I<SV *> pointer will be identical to the incoming
1730+
argument I<SV *> pointer. Ex. I<sv = sv;>). This way if I<TAINT> is on, and
1731+
the slow path branch executes, which has an internal helper function, that
1732+
helper function returns the argument passed in, and C compilers can optimize
1733+
the slowpath branch to a tail call, or use less registers. This macro is mostly
1734+
intended to be used if C<SvTAINTTC> is the last or almost last statement
1735+
in the caller function, and the caller has a I<SV *> return type, and will
1736+
return C<SvTAINTTC>'s arg I<sv>, to its caller as a return value. Similar idea
1737+
to C<sv_2mortal>.
1738+
17241739
=cut
17251740
*/
17261741

@@ -1739,6 +1754,9 @@ attention to precisely which outputs are influenced by which inputs.
17391754
sv_taint(sv); \
17401755
} STMT_END
17411756

1757+
#define SvTAINTTC(sv) ((assert(TAINTING_get || !TAINT_get), \
1758+
TAINT_AND_TAINTING_get) ? sv_taint((sv)) : (sv))
1759+
17421760
/*
17431761
=for apidoc_section $SV
17441762
=for apidoc Am|char*|SvPV_force |SV* sv|STRLEN len

sv_inline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ Perl_sv_setpv_freshbuf(pTHX_ SV *const sv)
985985
(void)SvPOK_only_UTF8(sv); /* UTF-8 flag will be 0; This is used instead
986986
of 'SvPOK_only' because the other sv_setpv
987987
functions use it */
988-
SvTAINT(sv);
988+
SvTAINTTC(sv);
989989
return SvPVX(sv);
990990
}
991991

0 commit comments

Comments
 (0)