mirror of
https://github.com/Perl/perl5.git
synced 2026-01-26 08:38:23 +00:00
Perl_leave_scope - sv_backoff shouldn't do an unnecessay string copy
When a `my` SV goes out of scope, any OOK hack on its string buffer is undone by `Perl_sv_backoff`. If the SV is `SvOK`, a copy of the buffer contents will occur, but since the contents are defunct at this point, the copy is unnecessary. See https://github.com/Perl/perl5/issues/23967 as an example of where this unnecessary copy had a noticeable effect on performance. This commit essentially inlines the necessary parts of `sv_backoff` to avoid the copy, without excessive messing around with `sv`'s flags at the call site in `Perl_leave_scope`.
This commit is contained in:
parent
e3b0f74b83
commit
4342210875
16
scope.c
16
scope.c
@ -1440,8 +1440,20 @@ Perl_leave_scope(pTHX_ I32 base)
|
|||||||
|
|
||||||
if (SvTYPE(sv) == SVt_PVHV && HvHasAUX(sv))
|
if (SvTYPE(sv) == SVt_PVHV && HvHasAUX(sv))
|
||||||
Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
|
Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
|
||||||
else if(SvOOK(sv))
|
else if(SvOOK(sv)) {
|
||||||
sv_backoff(sv);
|
/* Inlined sv_backoff() - the buffer contents are
|
||||||
|
* defunct and there's no need to copy them. All that
|
||||||
|
* is needed is resetting SvLEN and the SvPVX pointer. */
|
||||||
|
assert(SvTYPE(sv) != SVt_PVHV); /* the branch above */
|
||||||
|
assert(SvTYPE(sv) != SVt_PVAV);
|
||||||
|
|
||||||
|
STRLEN delta;
|
||||||
|
SvOOK_offset(sv, delta);
|
||||||
|
|
||||||
|
SvLEN_set(sv, SvLEN(sv) + delta);
|
||||||
|
SvPV_set(sv, SvPVX(sv) - delta);
|
||||||
|
SvFLAGS(sv) &= ~SVf_OOK;
|
||||||
|
}
|
||||||
|
|
||||||
if (SvMAGICAL(sv)) {
|
if (SvMAGICAL(sv)) {
|
||||||
/* note that backrefs (either in HvAUX or magic)
|
/* note that backrefs (either in HvAUX or magic)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user