[my last 2 f'ups didn't arrive at perl.perl6.internals, so I try again]

The patch is fine with two exceptions:
1) still breaks existing P6C tests WRT exceptions & rules
2) performance of CPS sucks

ad 1) I'd like to preserve the old style invoke/ret scheme too. incokecc
and friends could call a new ContSub[1] class, which is the same as
sub.pmc but doesn't put the return address on the control stack during
invoke.

ad 2) CPS subroutines are 3 times slower for calling the sub. There are
2 problems here:

2a) The main is: the continuation object is generated for each[2]
subroutine call. Replacing the invokecc with an explicit sequence of
constructing the return Continuation object once outside the loop brings
again the same speed as invoke/ret.

2b) There is still too much context copying going on AFAIK. The register
top and base pointers are copied too in {save,restore}context worth of 8
words, while just copying the 3 stacks (pad, control, user) should more
then be enough. The coroutine code only swaps these - BTW and doesn't
set them COW.

So we have currently:

sub.pmc (+ contsub.pmc), continuation.pmc, and coroutine.pmc do very
similar things. The only major difference is, where they branch on invoke.
The differences are:
- sub.pmc doesn't have an own context, it pushes the current lex_pad on
the interpreters pad_stack on invoke
- continuation.pmc saves/restores the whole context structure and marks
the 3 stacks COW
- coroutine.pmc swaps the 3 stacks and doesn't mark them COW

This leads to some questions:
- shouldn't these all preserve the same stack(s)?
- which stack(s): pad_stack only or control/user/intstack too?
- can we pull out the construction of the return continuation of the
loop like done below?
- what parts of current context structure should then be preserved
(registers are already out, why then deal with register backing store)?

Comments welcome
leo


[1] we could AFAIK reuse CSub, which is obsoleted by NCI. (also most routines in method_utils.c seems to be obsolete)

[2]
         new P10, .PerlUndef
        set P10, 1000000
        new P11, .PerlUndef
        set P11, 0
        new P0, .Sub
        set_addr I12, func
        set P0, I12
        set I0, 0       # no prototype
        set I2, 0       # no PMC params
        set I3, 0       # void context
        new P1, .Continuation   ##
        set_addr I12, ret       ##
        set P1, I12     ##
lp:
        pushbottomp
        invoke  ## invokecc
ret:
        popbottomp
        inc P11
        lt P11, P10, lp
        end

func:
        invoke P1




Reply via email to