# New Ticket Created by  Jonathan Sillito 
# Please include the string:  [perl #22633]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22633 >


(This conflicts with "[perl #22592] [PATCH] Introduce macros for register
access." because I use the REG_PMC(x) approach. It would be easy to fix I
just don't know when or if #22592 is going to be committed.)

This patch converts parrot to a continuation passing style. This means that
when invoking a sub or a method the "continuation" to return to should be
placed in P1. If the 'cc' ops (invokecc and invokecc_method) are used the
current continuation is captured and placed in P1 automatically.

So for a callee to return:

    invoke P1

for a tail call, just leave P1 (i.e. the continuation) as is and:

    invoke

for returning from a sub that is to be used as a coroutine:

    invokecc P1

nice, eh?

Specifically this patch applies the following changes:

  - adds file completecontext.pmc: should go in classes/
  - changes continuation.pmc - to not restore registers
  - small changes to sub.pmc & coroutine.pmc
  - supporting changes to sub.c, sub.h, register.h
  - add invoke_method & invokecc & invokecc_method ops
  - update tests and added tail call test

I am not satisfied with the time taken to make a call. I did some rough
benchmarking and the parrot implementation makes us slower than python
2.2.1. The most expensive part of our call is the saveall/restoreall that
wraps the invokecc. In some cases the caller can be more selective about
what is saved, if no saveall/restoreall are used parrot calls are faster
than python's. The PASM and python code I used to benchmark along with the
times are below.

#################################
### test.pasm
    new P0, .Sub
    set_addr I3, foo
    set P0, I3
    new P11, .PerlInt
    set P11, 1000000

loop:
    saveall
    invokecc
    restoreall
    sub P11, 1
    if P11, loop
    end

foo:
    invoke P1 # return

#################################
### test.py
def foo():
    pass

p11 = 1000000
while p11:
    foo()
    p11 -= 1

$ time python test.py
real    0m4.401s
user    0m3.990s
sys     0m0.030s

$ perl assemble.pl test.pasm >test.pbc ; time ./parrot  test.pbc
real    0m6.831s
user    0m6.820s
sys     0m0.010s

However if we remove the saveall/restore all we are much faster

$ perl assemble.pl test.pasm >test.pbc ; time ./parrot  test.pbc
real    0m2.382s
user    0m2.380s
sys     0m0.000s

--
Jonathan Sillito


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/59206/43869/1cbffc/cps.patch

-- attachment  2 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/59206/43870/55771c/completecontext.pmc

Attachment: cps.patch
Description: cps.patch

Attachment: completecontext.pmc
Description: completecontext.pmc

Reply via email to