Fixed 5.22 problems during my compiler port
===========================================

I uncovered and fixed many 5.22 problems with
[cperl](http://perl11.org/cperl/) already, but in the last months I
was busy to port the 3 compilers B::C, B::CC and B::Bytecode to 5.22.

As I said in my [interview](http://perlhist.com/perl30/reini-urban)
it's my belief that if all current p5p core committers would stop
committing their bad code it would be actually be the best for the
perl5 project.  They weren't able to implemented any of the already
properly designed features from perl6 in the last 12 years, and every
feature they did implement is just so horrifibly bad, making our
already bad code base, which led to reimplementation efforts of
perl6/parrot with a better core, even worse. With cperl I can only
undo a little, but when they start breaking the API and planned
features in an incompatible way they should just stop.

Nevertheless, 5.22 added a significant improvement from outside,
syber's monomorphic inline caching for method calls besides the
internal improvement of multideref by Dave Mitchell.

Now to the problems I had to fix in the last months with that 5.22.0 release:

1. Father broke ByteLoader
===========================

[cperl #75](https://github.com/perl11/cperl/issues/75)
[perl-compiler](https://github.com/rurban/perl-compiler/commit/3582cffaa26060b5763ae9c840736195bd10e694)

This is something I cannot fix in the compiler. I updated my perl patcher
`App::perlall` with new --patches=Compiler patches to fix this, and cperl of course
also has this fix.

I had to write a complicated
[probe mechanism](https://github.com/rurban/perl-compiler/commit/6dab39642f6444b8fde4cb3e66b7a7d81745babb)
for ByteLoader to check if the used perl5.22 version is already
patched or not. Probing a to-be-built XS submodule is not that easy. A
typical chicken and egg problem. I could use my already existing
B::C::Flags helper config, which allows custom compiler settings.
There I initialize the variable `$B::C::Flags::have_byteloader` with
undef, and when the XS modules are all built I call a helper script to
probe for a working ByteLoader, and patch
`$B::C::Flags::have_byteloader` to 0 or 1.  I can use this then in the
tests to skip or run the bytecode tests.  And I had to put this helper
script into the hints directory to skip it from being
installed. Messing with EUMM libscan() was too dirty for me.

The internal compiler op.c creates a new main or eval environment with
`newPROG()`, setting the entry points `PL_main_start` and `PL_main_root`
from the intermediate parsed `PL_compcv`. In the case of en empty source
the parser always adds a final `;` semicolon, which leads to an empty optree
starting with `OP_STUB`.

But with commit
[34b5495](http://perl5.git.perl.org/perl.git/commitdiff/34b54951568575920f2307bea918f5549bd5a82f)
for [perl #77452] the compiler now always adds a LINESEQ in front of
the STUB, but the logic in newPROG for source filters which already
setup `PL_main_start` and `PL_main_root` wasnot changed, which led to
a broken ByteLoader.

This is an interesting commit as it added a lot of wrong comments
about the inner working of this, but didn't update the logic.

The fix in cperl is
[here](https://github.com/perl11/cperl/commit/309dc8e9649acda055a86514ca334bdfea31c0f8)
and for perlall
[here](https://github.com/rurban/App-perlall/commit/4907abb6dfa86bc5d2572d523e75462a18705aec),
and my perlbug report did not get through.

I can only guess that p5p blocked me again, because they didn't like
me to call them incompetent.  Blocking bug reports and fixes is worse
than just incompetence, but I got used to that recently. They blocked
my simple fix for the horrific double-readonly system, and they
proudly announced last week some
[new optimization](http://perl5.git.perl.org/perl.git/commitdiff/230ee21f3e366901ce5769d324124c522df7ce8a)
regarding faster arithmetic, but didn't have a look into
[my fast arithmetic optimizations](https://github.com/perl11/cperl/commit/8b6139a5cbb3307067daf51503fdee2771595afb)
which I wrote half a year ago, and which makes them look very bad in
the end.  Everybody applauded poor Dave for this "fantastic
breakthrough". The guys are really that simple. Looking through my
improvements would have wasted less time and would have improved it
upstream by 30% not just 10%.


2. Dave couldn't implemented multideref access for the compiler
===============================================================

[cperl #76](https://github.com/perl11/cperl/issues/76)
[perl-compiler #341](https://github.com/rurban/perl-compiler/issues/341)

Multideref merges sequential hash or array access into one compressed op.
This is a pretty good compiler optimization, if the B design would not be so bad.

The upstream design of the new 5.22 `B::UNOP_AUX::aux_list` method
deviates significantly from proper B design.  aux_list requires the
curcv to be provided, which is not trivial to do for a B module, and
it needs this to resolve shared SVs beforehand.  Requiring the curcv
to resolve the padoffset is unneeded and does not help B and any of
its clients.  Clients need the padoffset and resolving it e.g. in
B::Deparse is to be done in B as with all other threaded and shared SV
accessing methods.

Thanksfully I can patch most of **B** bugs by myself, and don't have to
fork it publicly into a worse name. B is already a good enough name,
and I don't want to deviate from that, even if p5p consistently
refused to maintain B properly in the last years. There was some short
time a few years ago where I could work without a patched B, but this
period only lasted very shortly, and none of my fixes were applied,
while other new horrific mistakes made it in.


3. Missing HV::ENAMES api
=========================

[perl-compiler commit](https://github.com/rurban/perl-compiler/commit/e62a5b02b5003e5ad5a371e00ed330d98f4d5980) ++

Stashes can be aliased to seperate namespaces, and the ENAMES API to
access this names never made it into B, and thus never into a
compiler.  Namespaces aliases are rather seldom, so it caused not too much
trouble, but now I added ENAMES and could hereby fix most of the
remaining compiler limitations, even for 5.14.


4. Missing PADNAME B api
========================

I explained that technically in my
[interview](http://perlhist.com/perl30/reini-urban).  Currently we
limit the max name length of lexical variables to 60, because we
statically allocate the buffers for them. It is not a practical
problem, and I'll optimize that sooner or later to smaller static structs.

5. Fixed HEK assertions
=======================

HEK's (shared hash keys) are still dynamic, not [static](https://github.com/perl11/cperl/issues/73), but I could
[fix](https://github.com/rurban/perl-compiler/issues/236) the
remaining refcount issues at least.

The cperl code to support static HEKs is already there, but I still need to add compiler code and probes to support that.


--------------------

Overall we are very happy with the new 5.22 compiler, though we are
not yet using the much more advanced cperl optimizations.  The B::C
optimizations alone lead to ~20% less memory, with cperl and its
compiled readonly hashes for Config and warnings and its upcoming
support for
[static GV/AV/CV/PAD/HEK layout](https://github.com/perl11/cperl/issues/62)
it's much more dramatic.  This will be a real COW (copy-on-write)
mechanism then, being able to statically allocate readonly buffers,
and copy it to the heap, when it's being changed.  For the compiler we
only need to ensure that static buffers are not freed, which is
trivial with the added flag.

**-m support** for perlcc, compiling to modules, not single binaries
is also improving. This can split various optimizations per module/.pm
file, so we can use B::CC compiled modules or even rperl compiled
modules, compile-times should go down from 20min to ~5min, with much
faster smoker feedbacks, and pushing updates live is much faster,
because they will be much smaller. The old compile times were 2 hours.

But since fixing B::C for 5.22 needed so much more time than
expected I couldn't add most of the planned cperl optimizations for
the upcoming cperl-5.22.2 release and B-C-1.53 release.
