In perl.git, the branch sprout/op_const_sv has been created

<http://perl5.git.perl.org/perl.git/commitdiff/b8e07ef9b5e7a5effbc13ca9e9df9c5ce766d4b4?hp=0000000000000000000000000000000000000000>

        at  b8e07ef9b5e7a5effbc13ca9e9df9c5ce766d4b4 (commit)

- Log -----------------------------------------------------------------
commit b8e07ef9b5e7a5effbc13ca9e9df9c5ce766d4b4
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 22:10:17 2014 -0700

    Notes
    
    Some of these commits were written before I realised what a mess this
    is, and will not likely be merged to blead.  See ticket #123092.
    Also, the last two commits just bloat the code, even though they were
    meant to simplify it, so they are no good.

commit f10f05651c9fa6ed299bfcb9e49603f1c1e039f4
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 17:58:35 2014 -0700

    op.c: Refactor and simply op_has_lone_padsv
    
    This was split out from op_const_sv a few commits ago.  (Actually,
    it’s just a duplicate.)
    
    • It doesn’t need a separate op argument.
    
    • We should be starting at CvSTART, not at the block or lineseq
      op’s second kid.  It was that that resulted in bug #63540,
      because we were starting in the middle of an op chain.
      sub () { if ($outer) {} 0 } becomes:
    
         lineseq
      1    nextstate
           null ->5
      3      and
      2        padsv
               scope
      4          stub
      5    nextstate
      6    const
    
      If we start at the null op and follow op_next pointers, skipping
      null ops, then we miss the fact that we have an if-block here and
      end up treating that as a constant function.  Starting at CvSTART
      solves this properly, hence:
    
    • No need to check whether a null op has kids, which was done solely
      to fix #63540.
    
    • Skip the return check, because we don’t want return $x to be
      inlined.  (See the previous commit’s message.)
    
    • No SV variable is necessary, just a boolean.
    
    • No need to check o->op_next == o, since that only happens before
      op_next pointers are set up (see the previous commit’s message).

M       op.c

commit eb48575ddca1fce06342d31a088922eb00b67326
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 13:10:54 2014 -0700

    op.c: Rewrite op_const_sv
    
    Originally, a compiled CV was checked to see whether it could be
    inlined as a constant.  sub_const, later named, cv_const_sv, followed
    op_next pointers starting at CvSTART to look for a single constant,
    possibly surrounded by multiple nextstate, pushmark or null ops, fol-
    lowed by leavesub or the end of the op chain.  Later this loop was
    put in a separate function, op_const_sv, which is why it is laid out
    like this.
    
    It was 64d1d4c7d or fe5e78ed in 1998, whose purpose was to check the
    values of constants before emitting a redefinition warning, that made
    op_const_sv a separate function and caused it to be called before the
    op_next pointers are set up.  That’s when things stopped making sense.
    
    If you follow op_next pointers when they are not set up yet, you don’t
    get anywhere.  And maybe that’s the point.  op_const_sv starts at the
    second kid of the op passed to it, if the latter is a lineseq op.  So
    a lone constant looks like this:
    
      lineseq
        nextstate
        const <-- op_const_sv starts here and looks no further
    
    It never gets beyond that second kid.  In the case of two constants
    separated by a semicolon, the first one becomes a null op, and the
    surviving constant is never seen:
    
      lineseq
        nextstate
        null <-- op_const_sv starts here and looks no further
        nextstate
        const
    
    It was that change that stopped sub(){return 3} and sub(){die if 0;5}
    from being inlined (and sub(){return $outer_lexical}, for that matter,
    which was inlined in perl 5.004¹), accidentally I presume, but the
    altered behaviour has been documented now for over a decade, so it may
    not be wise to revert it.
    
    This commit just rewrites op_const_sv to work as currently, but with-
    out the useless op_next loop.  In other works, it actually does now
    what it looks as though it is doing, instead of requiring a day of
    detective work to figure out why it works the way it does.
    
    ¹ I was not able to test this; I just surmised it based on the code.

M       op.c

commit 6dc2b169784ebaed50d87a03c3cf64c39859fb7c
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 13:10:12 2014 -0700

    op.c: op_const_sv: Remove null check
    
    op_const_sv is not even called if the argument would be null.

M       op.c

commit 72c6fc237200fb35305e0033c8721ee979f9cdc5
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 13:08:46 2014 -0700

    op.c: Make op_const_sv two functions
    
    It is called two different ways and does two different things.  For
    now, just duplicate the entire thing.  But just watch me collapse the
    code in the next few commits.

M       op.c

commit bffaab0152b55c1053b2ac79fac8bc30d21320ff
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 12:55:21 2014 -0700

    Make op.c:op_const_sv static
    
    Nothing outside of op.c uses it now.

M       embed.fnc
M       embed.h
M       op.c
M       proto.h

commit 4541ae431f8599bd59aec23d3c8233d6e951fcce
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 12:37:50 2014 -0700

    Inline op_const_sv into cv_clone
    
    op_const_sv is actually three functions in one.  (Don’t try to follow
    its logic.  It doesn’t have any!)
    
    This particular calling convention was used only by cv_clone.
    
    Most of the code was not even necessary for cv_clone’s use, so this
    reduces the total number of lines.

M       op.c
M       pad.c

commit 99063ab315c9c4d1c99938630f02afdce89ae81e
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 08:56:44 2014 -0700

    Update comments about sub(){$x} consting
    
    It no longer has anything to do with constant.pm.

M       pad.c

commit 8af5eede2e70a379e3dc46122a5555ca9597f6cb
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 08:52:56 2014 -0700

    Don’t turn sub:CustomAttr(){$outer_lex} into a const
    
    We can’t know what the attributes are for, and turning it into a con-
    stant discards the attributes.

M       ext/XS-APItest/t/call_checker.t
M       op.c

commit 799ada3c590a65c4ec7e8e94329352a31e723410
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 08:46:00 2014 -0700

    Preserve :method in sub:method(){$outer_lex}
    
    When we turn such a sub into a constant, we need to preserve the
    attribute, since it changes behaviour.

M       pad.c
M       t/op/sub.t

commit 10f1ad4e8b5357c4f51a7846780182fd5a34b11b
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 05:08:19 2014 -0700

    Make sub(){$outer_lexical} return a copy each time
    
    We don’t actually stop in from being inlined, but simply mark the
    inlined value as PADTMP, so it gets copied in lvalue context.

M       op.c
M       t/op/sub.t

commit ee2266f43d4431e3197dcbd3509beede105c2d7e
Author: Father Chrysostomos <[email protected]>
Date:   Thu Oct 30 04:32:51 2014 -0700

    Remove dead code from op.c:op_const_sv
    
    We would already have turned CVs that could reach this code into con-
    stant XSUBs in newATTRSUB, before any op_const_sv(..., cv) call.  This
    code only makes sense under ithreads and only if constants are relo-
    cated to the pad before the initial search for a constant in the
    sub body.  But constant relocation happens after the initial
    op_const_sv(block, NULL) call.

M       op.c
-----------------------------------------------------------------------

--
Perl5 Master Repository

Reply via email to