Maintaining Perl 5 Core (Dave Mitchell): June 2022
Sun, 10-Jul-2022 by
Jason A. Crome
edit post
Dave writes:
This is my monthly report on work done during June covered by my TPF perl
core maintenance grant.
SUMMARY:
```
0:47 improve docs for internal exception handling (JMPENV etc)
1:46 look into disabling smartmatch/switch.
8:02 make stack reference counted
7:58 process p5p mailbox
------
18:33 TOTAL (HH::MM)
```
The most interesting thing I did was that near the end of the month I
started work on "making the stack reference counted"; i.e. that when
things are pushed onto the argument stack, their reference count (RC)
should be incremented and, conversely, decremented when popped.
Currently things on the stack aren't RCed, so there is a danger that such
items could be prematurely freed. For example,
@a = (1,2,3);
f(@a);
sub f {
@a = (); # prematurely frees the elements of @a
print "($_[0])\n"; # prints an undefined value or random garbage
}
This issue has been the basis of countless "unfixable" bug reports over
the years, and in particular most fuzzing crash reports turn out to be
caused by this issue.
There is a particular difficulty in fixing this: specifically how do we
get to there from where we are now, because it's rather an all-or-nothing
scenario. Every single pp function in the 30K lines of code in the various
`pp*.c` files all need to be updated to expect an RCed stack at the same
time. You can't have only half of them updated: the stack is binary, it's
either RCed or it isn't. So having updated only half the pp functions, you
can't compile perl and run the test suite.
My cunning plan for getting round that is to initially redefine all the
`Perl_pp_foo()` functions to be small wrapper functions around the real
functions. The wrappers are responsible for making a non-RCed copy of the
function's args and calling the real (non-RC aware) function; then on
return, shifting down and bumping the RC of any returned arguments. A
similar thing will be done by `pp_entersub()` to call XS functions.
This is crude and slow, but in principle allows the changeover to an RCed
stack in a single go. Then at my leisure, I can go through the pp
functions one by one and modify them to be RC-aware and remove the wrapper
functions. Once all the important functions are done (e.g. all the ones in
`pp_hot.c`) then the new system may be ready for production use. We can
continue using wrapper functions for the slow/rare functions if converting
them would be too much work.
I intend to have a new build define, `PERL_RC_STACK`, which isn't initially
enabled by default. Unless enabled, perl behaves as usual, with the stack
not being reference counted, the wrapper functions not being defined, etc.
So my work can proceed initially without breaking normal perl. Once the
work is stable and we don't think it will break most of CPAN, then
`PERL_RC_STACK` will be enabled by default in builds, but can be disabled at
build time if necessary. Eventually the define will be removed
altogether, meaning that various places in the perl core no longer need to
handle both RC and non-RC cases.
This work if fairly risky, in that I may well find along the way that the
problems are unsurmountable and have to abandon it.
Comments (0)