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$^[email protected](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$&$+!#:#[email protected]$O$"$k$G$7$g$&$+!#e(B
e$B$b$&GQ$l$F$$$/%%W%7%g%[email protected]$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 [email protected]@.$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%[email protected]$^$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
[email protected]$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
[email protected]$3$l$G$b$^[email protected](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;