[Feature:1.9] speed up continuation in 1.9

e$B1sF#$G$9!#e(B

1.9 e$B$N7QB3$Oe(B 1.8 e$B$KHf$Y$F6KC<$KCY$$$h$&$G$9!#e(B

$ time ruby18 -e ‘i = 0; callcc {|c| $c = c }; i += 1; $c.call if i <
1000000’
real 0m1.060s
user 0m1.050s
sys 0m0.010s

$ time ruby19 -rcontinuation -e ‘i = 0; callcc {|c| $c = c }; i += 1;
$c.call if i < 1000000’
real 1m57.022s
user 1m56.780s
sys 0m0.180s

capture e$B$de(B call e$B$N:]!"e(BVM
e$B$N%9%?%C%/$r>o$K4]$4$H%3%T!<$7$F$$$k$N$,e(B
e$B860x$G!"I,MW$J$H$3$me(B (e$B@hF,$Ne(B sp e$BItJ,$H=*C<$Ne(B cfp
e$BItJ,e(B) e$B$@$1%3%T!<e(B
e$B$9$k$h$&$K$7$?$i!"e(B1.8 e$BJB$KB.$/$J$j$^$7$?!#e(B

$ time ./ruby.fast-cont -rcontinuation -e ‘i = 0; callcc {|c| $c = c
}; i += 1; $c.call if i < 1000000’

real 0m0.660s
user 0m0.660s
sys 0m0.000s

e$B;d$N4D6-$Ge(B test-all e$B$,DL$k$3$H$O3NG’$7$F$$$^$9!#e(B
e$B$H$/$K0[O@$,$J$1$l$P%3%_%C%H$7$h$&$H;W$$$^$9!#e(B

Index: cont.c

— cont.c (revision 20241)
+++ cont.c (working copy)
@@ -14,6 +14,8 @@
#include “gc.h”
#include “eval_intern.h”

+#define CAPTURE_JUST_VALID_VM_STACK 1
+
enum context_type {
CONTINUATION_CONTEXT = 0,
FIBER_CONTEXT = 1,
@@ -25,6 +27,10 @@
VALUE self;
VALUE value;
VALUE *vm_stack;
+#ifdef CAPTURE_JUST_VALID_VM_STACK

  • int vm_stack_slen; /* length of stack (head of th->stack) */
  • int vm_stack_clen; /* length of control frames (tail of th->stack)
    */
    +#endif
    VALUE *machine_stack;
    VALUE *machine_stack_src;
    #ifdef __ia64
    @@ -75,8 +81,13 @@
    rb_thread_mark(&cont->saved_thread);

if (cont->vm_stack) {
+#ifdef CAPTURE_JUST_VALID_VM_STACK
rb_gc_mark_locations(cont->vm_stack,

  •     cont->vm_stack + cont->saved_thread.stack_size);
    
  •     cont->vm_stack + cont->vm_stack_slen + cont->vm_stack_clen);
    

+#elif

  •  rb_gc_mark_localtion(cont->vm_stack,
    
  •     cont->vm_stack, cont->saved_thread.stack_size);
    

+#endif
}

if (cont->machine_stack) {
@@ -247,8 +258,16 @@
contval = cont->self;
sth = &cont->saved_thread;

+#ifdef CAPTURE_JUST_VALID_VM_STACK

  • cont->vm_stack_slen = th->cfp->sp + th->mark_stack_len - th->stack;

  • cont->vm_stack_clen = th->stack + th->stack_size - (VALUE*)th->cfp;

  • cont->vm_stack = ALLOC_N(VALUE, cont->vm_stack_slen +
    cont->vm_stack_clen);

  • MEMCPY(cont->vm_stack, th->stack, VALUE, cont->vm_stack_slen);

  • MEMCPY(cont->vm_stack + cont->vm_stack_slen, (VALUE*)th->cfp,
    VALUE, cont->vm_stack_clen);
    +#elif
    cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
    MEMCPY(cont->vm_stack, th->stack, VALUE, th->stack_size);
    +#endif
    sth->stack = 0;

    cont_save_machine_stack(th, cont);
    @@ -288,7 +307,13 @@
    th->stack_size = fcont->saved_thread.stack_size;
    th->stack = fcont->saved_thread.stack;
    }
    +#ifdef CAPTURE_JUST_VALID_VM_STACK

  • MEMCPY(th->stack, cont->vm_stack, VALUE, cont->vm_stack_slen);

  • MEMCPY(th->stack + sth->stack_size - cont->vm_stack_clen,

  •     cont->vm_stack + cont->vm_stack_slen, VALUE, 
    

cont->vm_stack_clen);
+#elif
MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
+#endif
}
else {
/* fiber */

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:37106] [Feature:1.9] speed up continuation in
1.9”
on Tue, 18 Nov 2008 00:44:53 +0900, “Yusuke ENDOH” [email protected]
writes:

|1.9 e$B$N7QB3$Oe(B 1.8 e$B$KHf$Y$F6KC<$KCY$$$h$&$G$9!#e(B

|capture e$B$de(B call e$B$N:]!"e(BVM e$B$N%9%?%C%/$r>o$K4]$4$H%3%T!<$7$F$$$k$N$,e(B
|e$B860x$G!"I,MW$J$H$3$me(B (e$B@hF,$Ne(B sp e$BItJ,$H=*C<$Ne(B cfp e$BItJ,e(B) e$B$@$1%3%T!<e(B
|e$B$9$k$h$&$K$7$?$i!"e(B1.8 e$BJB$KB.$/$J$j$^$7$?!#e(B

|e$B;d$N4D6-$Ge(B test-all e$B$,DL$k$3$H$O3NG’$7$F$$$^$9!#e(B
|e$B$H$/$K0[O@$,$J$1$l$P%3%_%C%H$7$h$&$H;W$$$^$9!#e(B

e$B$$$$$s$8$c$J$$$G$7$g$&$+!#e(B

e$B%A%1%C%He(B #758 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r20256.

http://redmine.ruby-lang.org/issues/show/758