Skip to content

Commit 789b63c

Browse files
committed
Perl_sv_backoff - only copy the buffer contents if SvOK(sv)
When undoing an OOK, `Perl_sv_backoff` will always copy the shifted buffer contents down to the start of the buffer. That's required when the contents are live, unfortunate when the contents are defunct but tiny, and can have a noticeably bad effect on performance when the contents are defunct but large. See #23967 for an example of the latter. With this commit the copy will only occur if `SvOK(sv)`. This test is expected to indicate whether the buffer contents are active or defunct.
1 parent 23a787a commit 789b63c

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

sv.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,8 @@ wrapper instead.
13361336

13371337
/* prior to 5.000 stable, this function returned the new OOK-less SvFLAGS
13381338
prior to 5.23.4 this function always returned 0
1339+
prior to 5.43.x, the contents of the string buffer were always copied
1340+
down to the start of the buffer. Now, this only happens if SvOK(sv)
13391341
*/
13401342

13411343
void
@@ -1355,7 +1357,11 @@ Perl_sv_backoff(SV *const sv)
13551357
SvLEN_set(sv, SvLEN(sv) + delta);
13561358
SvPV_set(sv, SvPVX(sv) - delta);
13571359
SvFLAGS(sv) &= ~SVf_OOK;
1358-
Move(s, SvPVX(sv), SvCUR(sv)+1, char);
1360+
1361+
/* Don't copy a buffer if the contents are already defunct. */
1362+
if (SvOK(sv))
1363+
Move(s, SvPVX(sv), SvCUR(sv)+1, char);
1364+
13591365
return;
13601366
}
13611367

0 commit comments

Comments
 (0)