Stack Caching $B$rM-8z$K$7$?;~$N%S%k%I$K$D$$$F(B

nagachika e$B$H?=$7$^$9!#e(B

e$BA02s$Ne(BRHGe$B$N5U=1$Ge(B Stack Caching Optimization
e$B$r%M%?$K$9$k$?$a!"e(B
OPT_STACK_CACHING e$B$re(B ON
e$B$K$7$F%S%k%I$7$F$_$k$3$H$KD)@o$7$^$7$?!#e(B
e$B$^$@e(B make e$B$,:G8e$^$GDL$C$F$$$J$$$N$G$9$,!"e(Bminiruby
e$B$GNc30=hM}Ey$,$&$^$/e(B
e$B$$$+$J$$LdBj$K$D$$$FD4::$7$?$N$GJs9p$7$^$9!#e(B

e$B$D$$$G$K?V$$$F$7$^$$$^$9$,e(B STACK_CACHING
e$B$N%%W%7%g%s$N07$$$H$$$&$N$Oe(B
e$B:#8e$I$&$J$C$F$$$/$N$G$7$g$&$+!#:#8eM-8z$K$9$k2DG=@-$O$"$k$G$7$g$&$+!#e(B
e$B$b$&GQ$l$F$$$/%
%W%7%g%s$J$N$N$@$H$7$?$i$"$s$^$j?<DI$$$7$F$b$J$!$He(B
e$B;W$$$^$7$F!#e(B

vm_opt.h e$B$Ne(B OPT_STACK_CACHING e$B$re(B 1 e$B$KJQ99$7$Fe(B
$ make opt_sc.inc
$ make mniruby
e$B$7$F!"0J2<$N%9%/%j%W%H$r<B9T$9$k$He(B[BUG]e$B$,H/@8$7$^$9!#e(B

$ cat test.rb
p :hoge # e$B%l%8%9%?>uBV$re(BAXe$B$K$9$k$?$ae(B

begin
raise “err”
rescue
end
$ ./miniruby test.rb
:hoge
test.rb:4: [BUG] Stack consistency error (sp: 7, bp: 6)
ruby 1.9.2dev (2009-02-16 trunk 22360) [i386-darwin8.11.1]

– control frame ----------
c:0003 p:0026 s:0007 b:0006 l:0012e4 d:002124 EVAL test.rb:4
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0012e4 d:0012e4 TOP

test.rb:4:in `’

Stack Caching e$BMQ$K@8@.$5$l$?L?Na8l$N%9%?%C%/>CHqNL$,%l%8%9%?$K$h$ke(B
e$B%-%c%C%7%e$r9MN8$7$F$$$J$$$?$a$K!"e(B catch_table_entry
e$B$KJ]B8$5$l$ke(B sp e$B$,e(B
e$B0c$&$?$a$N$h$&$G$9!#e(B
e$B$^$?e(B
CATCH_TYPE_RESCUEe$B$N>l9g$K%9%?%C%/%H%C%W$K@Q$^$l$k$Y$-CM$,e(B
e$B%-%c%s%;%k$5$l$k$?$a$Ke(B sp
e$B$r%G%/%j%a%s%H$7$F$$$k=hM}$O!"e(BStack Caching e$BM-8z;~e(B
e$B$K$O7k2L$,%l%8%9%?$K3JG<$5$l$kM=Dj$K$J$k$N$GITMW$K$J$k$H;W$$$^$9!#e(B
(BREAK, NEXTe$B$N$[$&$O$b$7$+$7$?$i0c$&$+$be(B)

tool/instruction.rb
e$B$r=$@5$7$F%9%?%C%/>CHqNL$K%l%8%9%?$N>uBVA+0$r9MN8$9$k$h$&$Ke(B
e$B$7$F$_$^$7$?!#e(B
e$B$?$@$3$l$G$b$^$@e(B make e$B$OESCf$G<:GT$7$F$7$^$$$^$9!#e(B
e$B0J2<0l1~%Q%C%A$O$j$^$9!#e(B trunk e$B$KBP$9$k%Q%C%A$G$9!#e(B
e$B$^$"%G%U%)%k%H$GL58z$J%*%W%7%g%s$J$N$G$9$1$I!#e(B

Index: tool/instruction.rb

— tool/instruction.rb (e$B%j%S%8%g%se(B 22360)
+++ tool/instruction.rb (e$B:n6H%3%T!<e(B)
@@ -8,7 +8,7 @@
class Instruction
def initialize name, opes, pops, rets, comm, body, tvars, sp_inc,
orig = self, defopes = [], type = nil,

  •               nsc = [], psc = [[], []]
    
  •               fsc = [], nsc = [], psc = [[], []]
    
     @name = name
     @opes = opes # [[type, name], ...]
    

@@ -22,6 +22,7 @@
@type = type
@tvars = tvars

  •  @fromsc = fsc
     @nextsc = nsc
     @pushsc = psc
     @sc     = []
    

@@ -38,7 +39,7 @@

 attr_reader :name, :opes, :pops, :rets
 attr_reader :body, :comm
  • attr_reader :nextsc, :pushsc
  • attr_reader :fromsc, :nextsc, :pushsc
    attr_reader :orig, :defopes, :type
    attr_reader :sc
    attr_reader :unifs, :optimized
    @@ -58,12 +59,16 @@
    @optimized << insn
    end

  • def sp_increase_with_sc

  •  @fromsc.size - @nextsc.size
    
  • end

  • def sp_increase_c_expr
    if(pops.any?{|t, v| v == ‘…’} ||
    rets.any?{|t, v| v == ‘…’})
    # user definision
    raise “no sp increase definition” if @sp_inc.nil?

  •    ret = "int inc = 0;\n"
    
  •    ret = "int inc = #{sp_increase_with_sc};\n"
    
       @opes.each_with_index{|(t, v), i|
         if t == 'rb_num_t' && ((re = /\b#{v}\b/n) =~ @sp_inc ||
    

@@ -81,7 +86,7 @@
ret << " return depth + inc;"
ret
else

  •    "return depth + #{rets.size - pops.size};"
    
  •    "return depth + #{rets.size - pops.size + 
    

sp_increase_with_sc};"
end
end

@@ -519,19 +524,19 @@
name, pops, rets, pushs1, pushs2, nextsc =
*calc_stack(insn, from, after, opops, orets)

  •      make_insn_sc(insn, name, oopes, pops, rets, [pushs1, pushs2], 
    

nextsc)

  •      make_insn_sc(insn, name, oopes, pops, rets, [pushs1,
    

pushs2], from, nextsc)
}
}
end

  • def make_insn_sc orig_insn, name, opes, pops, rets, pushs, nextsc
  • def make_insn_sc orig_insn, name, opes, pops, rets, pushs, fromsc,
    nextsc
    comm = orig_insn.comm.dup
    comm[:c] = ‘optimize(sc)’

    scinsn = Instruction.new(
    name, opes, pops, rets, comm,
    orig_insn.body, orig_insn.tvars, orig_insn.sp_inc,

  •    orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
    
  •    orig_insn, orig_insn.defopes, :sc, fromsc, nextsc, pushs)
    
     add_insn scinsn
     orig_insn.add_sc scinsn
    

@@ -611,7 +616,7 @@
exit
end

  •  ret = 
    

["#{insn.name}SC#{InstructionsLoader.complement_name(ofrom)}_#{complement_name(from)}",

  •  ret = 
    

["#{insn.name}SC#{InstructionsLoader.complement_name(ofrom)}_#{InstructionsLoader.complement_name(from)}",
pops, rets, pushs_before, pushs, from]
end
end
@@ -1176,7 +1181,11 @@
else
insns = Array.new(6){‘SC_ERROR’}
end

  •    sc_insn_info << "  {\n#{insns.join(",\n")}}"
    
  •    if verbose?
    
  •      sc_insn_info << "  { /* #{insn.name} 
    

*/\n#{insns.join(",\n")}}"

  •    else
    
  •      sc_insn_info << "  {\n#{insns.join(",\n")}}"
    
  •    end
     }
     sc_insn_info = sc_insn_info.join(",\n")
    

Index: compile.c

— compile.c (e$B%j%S%8%g%se(B 22360)
+++ compile.c (e$B:n6H%3%T!<e(B)
@@ -1535,12 +1535,14 @@
entry->cont = label_get_position(lobj);
entry->sp = label_get_sp(lobj);

+#if !OPT_STACK_CACHING
/* TODO: Dirty Hack! Fix me */
if (entry->type == CATCH_TYPE_RESCUE ||
entry->type == CATCH_TYPE_BREAK ||
entry->type == CATCH_TYPE_NEXT) {
entry->sp–;
}
+#endif
}
else {
entry->cont = 0;

e$B!!$5$5$@$G$9!%e(B

nagachika wrote::

e$B$D$$$G$K?V$$$F$7$^$$$^$9$,e(B STACK_CACHING e$B$N%%W%7%g%s$N07$$$H$$$&$N$Oe(B
e$B:#8e$I$&$J$C$F$$$/$N$G$7$g$&$+!#:#8eM-8z$K$9$k2DG=@-$O$"$k$G$7$g$&$+!#e(B
e$B$b$&GQ$l$F$$$/%
%W%7%g%s$J$N$N$@$H$7$?$i$"$s$^$j?<DI$$$7$F$b$J$!$He(B
e$B;W$$$^$7$F!#e(B

e$B!!:#<BAu$7$F$$$k$N$Oe(B two level five state stack caching
e$B$G$9$,!$e(Bone
level e$B$G$$$$$s$8$c$J$$!$$H$+!$e(Btwo level e$B$K$7$F$be(B three state
e$B$G$$$$$se(B
e$B$8$c$J$$!$$H$+!$?’!9$"$j$=$&$J$s$G!$$^$@<B83$7$J$$$H$$$1$J$$OC$+$H;W$$$^e(B
e$B$9!%$H$j$"$($:!$$b$&$A$g$C$H=@Fp$K$7$F$_$?$$$J$!!$$H;W$$$^$9!%e(B

Stack Caching e$BMQ$K@8@.$5$l$?L?Na8l$N%9%?%C%/>CHqNL$,%l%8%9%?$K$h$ke(B
e$B%-%c%C%7%e$r9MN8$7$F$$$J$$$?$a$K!"e(B catch_table_entry e$B$KJ]B8$5$l$ke(B sp e$B$,e(B
e$B0c$&$?$a$N$h$&$G$9!#e(B
e$B$^$?e(B CATCH_TYPE_RESCUEe$B$N>l9g$K%9%?%C%/%H%C%W$K@Q$^$l$k$Y$-CM$,e(B
e$B%-%c%s%;%k$5$l$k$?$a$Ke(B sp e$B$r%G%/%j%a%s%H$7$F$$$k=hM}$O!"e(BStack Caching e$BM-8z;~e(B
e$B$K$O7k2L$,%l%8%9%?$K3JG<$5$l$kM=Dj$K$J$k$N$GITMW$K$J$k$H;W$$$^$9!#e(B
(BREAK, NEXTe$B$N$[$&$O$b$7$+$7$?$i0c$&$+$be(B)

e$B!!$?$7$+!$e(Bstack caching e$B$r<BAu$7!$<B83$7$F$$$?$H$-$Oe(B sp
e$B$N7W;;$r$^$H$b$Ke(B
e$B$d$C$F$$$J$+$C$?$h$&$J5$$,$7$^$9!%$H$$$&$o$1$G!$%P%0$,=P$?$s$G$7$g$&$M$’!%e(B

tool/instruction.rb e$B$r=$@5$7$F%9%?%C%/>CHqNL$K%l%8%9%?$N>uBVA+0$r9MN8$9$k$h$&$Ke(B
e$B$7$F$_$^$7$?!#e(B
e$B$?$@$3$l$G$b$^$@e(B make e$B$OESCf$G<:GT$7$F$7$^$$$^$9!#e(B

e$B!!D4::$H$+$"$j$,$H$&$4$6$$$^$9!%e(B

e$B!!$H$$$&$o$1$G!$$^$@F;$O1s$=$&$G$9!%$3$NJU$K4X$7$F$b?’!9$HM-MQ$JO@J8$,=Pe(B
e$B$F$$$k$N$G!$C/$+$,$C$D$j<h$jAH$s$G$/$l$k$H$$$$$s$G$9$,!%e(B

nagachika e$B$H?=$7$^$9!#e(B

e$B9bB.%j%W%i%$$"$j$,$H$&$4$6$$$^$9!#e(B

e$B!!:#<BAu$7$F$$$k$N$Oe(B two level five state stack caching e$B$G$9$,!$e(Bone
level e$B$G$$$$$s$8$c$J$$!$$H$+!$e(Btwo level e$B$K$7$F$be(B three state e$B$G$$$$$se(B
e$B$8$c$J$$!$$H$+!$?’!9$"$j$=$&$J$s$G!$$^$@<B83$7$J$$$H$$$1$J$$OC$+$H;W$$$^e(B
e$B$9!%$H$j$"$($:!$$b$&$A$g$C$H=@Fp$K$7$F$_$?$$$J$!!$$H;W$$$^$9!%e(B
e$B$J$k$[$I!":#$N<BAu$O$$$m$s$J$d$j$+$?$N$&$A$N$R$H$D$J$s$G$9$M!#e(B

e$B$^$@<B83$9$k0U5A$O$"$kOC$$?$$$J$N$G0B?4$7$F$b$&>/$7DI$C$+$1$F$$^$9!#e(B

e$B0J>e!#e(B