develooper Front page | perl.perl5.porters | Postings from November 2021

"no snails"; or having signatured subs complain about @_

Thread Next
From:
Paul "LeoNerd" Evans
Date:
November 29, 2021 16:09
Subject:
"no snails"; or having signatured subs complain about @_
Message ID:
20211129160854.16f6fcce@shy.leonerd.org.uk
The final part of the "signatures" feature still to be implemented, is
getting rid of the @_ setup as part of OP_ENTERSUB when entering a
signature'd sub, for the speed benefit it gives. I've been thinking
about how to implement this.

It seems to me we need four pieces. The first two of these should be
quite simple:

   1. Add a flag (maybe CvSIGNATURE(cv)) on CVs that is present when
      the sub has a signature. The parser can easily turn this one on
      at the time it creates the CV.

   2. Get pp_entersub to check that flag, and skip setting up the
      callee's @_ array if set. -- this is the core of the speedup.

   3. {handwavy something} to ensure that OP_ARGCHECK and OP_ARGELEM
      can look somewhere else to find the arguments, now they can no
      longer use GvAV(PL_defgv).

   4. {handwavy something else} to make accesses of @_ throw an error
      at runtime.

Part 2 is the main reason *why* to do this. Part 1 is the logic to make
it apply at the right time. Those are the easy bits.

Far less clear is how to do parts 3 and 4. In particular, for part 3 I
have the following thoughts on possible ways to implement it:

   3a. Don't set up @_ but instead move the stack values over to some
       other temporary place for the OP_ARG* ops to read from. Since
       that has to be local'ised in case of recursion into another
       signatured sub during argument unpack in practice this is going
       to perform about the same amount of work as the current
       GvAV(PL_defgv) implementation anyway, and thus be about the same
       speed. We gain nothing.

   3b. Don't have pp_entersub reset the stack pointers before jumping
       into the optree. A CV with CvSIGNATURE() set would be promising
       that it will inspect the TOPMARK and use that to pull its
       arguments off the stack into whatever setup it wants, via those
       OP_ARG* operations. Thus where OP_ARGCHECK currently does

         argc = (UV)(AvFILLp(defav) + 1);

       It could instead compare TOPMARK with SP, in something like
       ((I may have an off-by-one here but you get the idea))

         argc = SP - TOPMARK + 1;

       This does seem notably more fragile than the current setup,
       because now we can't have any OP_NEXTSTATEs in the middle of
       signature unpacking, or else they'll reset the stack pointers.
       The whole setup relies on the state of the stack being rather
       fragile during the first phase of the callee's optree - at least
       until the OP_ARG* ops are finished.

   3c. A variant of 3b, which involves adding a new interpreter pointer
       like SP, which points at the start of the stack arguments. Lets
       steal x86's naming and call it the "frame pointer". When
       entering a CV with CvSIGNATURE(), pp_entersub would set
       FP = TOPMARK and jump into the optree. Thereafter, the OP_ARG*
       ops can use the frame pointer to work:

       In OP_ARGCHECK:
         argc = SP - FP + 1;

       In OP_ARGELEM:
         SV *arg = FP[argi];

       This would be somewhat less fragile than 3b because it doesn't
       rely on the TOPMARK being preserved. It lets us set aside a
       storage area for passed arguments that should be much more
       robust than in 3b, without needing to copy them aside as we do
       now, or with 3a.

       It is still one more pointer value that has to be saved/restored
       around every function invocation (and likely stored on the
       context stack), but it's nowhere near as much work to do that as
       the current work around @_.

And finally I don't really have much thought on how to go about part 4,
other than the vague thinking that adding a new AV flag just to put one
on @_ in a signature'd sub, and then have every AV access check it, is
probably going to be a bit slow as it makes every AV access slow.


I'd welcome any thoughts anyone else has around this subject...

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About