This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
make sv_backoff tailcall friendly
authorDaniel Dragan <bulk88@hotmail.com>
Fri, 25 Sep 2015 04:40:43 +0000 (00:40 -0400)
committerDavid Mitchell <davem@iabyn.com>
Thu, 8 Oct 2015 15:21:17 +0000 (16:21 +0100)
commitfa7a1e491ab222c171fed6ca536cf7483a165414
treea4ed042ef2ee84136008dd4381e829b80d29180f
parent6fc2106e6704b632dc6ea04410ea89e1fa4ca43c
make sv_backoff tailcall friendly

Reorder the body of Perl_sv_backoff slightly to make it more tail-call
friendly, and change its signature from returning an int (always 0) to
void.

sv_backoff has only 1.5 function calls in it, there is a memcpy of a U32 *
for alignment reasons (I wont discuss U32_ALIGNMENT_REQUIRED) inside of
SvOOK_offset, and the explicit Move()/memmove. GCC and clang often inline
memcpy/memmove when the length is a constant and is small. Sometimes
a CC might also do unaligned memory reads if OS/CPU allows it
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130513/174807.html
so I'll assume memcpy by short constant isn't a func call for discussion.
By moving SvFLAGS modification before the one and only func call, and
changing the return type to void, there is no code to execute after the
Move func call so the CC, if it wants (OS/ABI/CPU, specifically I am
thinking about x86-64) can tailcall jump to memmove. Also var sv can be
stored in a cheaper vol reg since it is not saved around any func calls
(SvFLAGS set was moved) assuming the memcpy by short constant was inlined.

The before machine code size of Perl_sv_backoff with VC 2003 -O1 was
0x6d bytes. After size is 0x61. .text section size of perl523.dll was
after was 0xD2733 bytes long, before was 0xD2743 bytes long. VC perl does
not inline memcpys by default.

In commit a0d0e21ea6 "perl 5.000" the return 0 was added. The int ret type
is from day 1 of sv_backoff function existing/day 1 of SV *s
from commit 79072805bf "perl 5.0 alpha 2". str_backoff didn't exist AFAIK,
only str_grow would retake the memory at the start of the block. Since
sv_backoff is usually used in a "&& func()" macro (SvOOK_off), it needed a
non void ret type, a simple ", 0" in the macro fixes that. All CCs optimize
and remove "if(0)" machine instructions so the ", 0" is optimized away in
the perl binary.
embed.fnc
pod/perldelta.pod
proto.h
sv.c
sv.h