From: Yusuke ENDOH Date: 2007-08-08T23:32:47+09:00 Subject: [ruby-dev:31360] infinite loop at peephole optimization 遠藤と申します。 while true; redo; end で YARV のコンパイルが止まらなくなります。 $ ./ruby -ve 'VM::InstructionSequence.compile("while true; redo; end")' ruby 1.9.0 (2007-08-08 patchlevel 0) [i686-linux] (固まる) peephole optimization を止めるとちゃんとコンパイルできます。 $ ./ruby -ve ' VM::InstructionSequence.compile_option = { :peephole_optimization => false } puts VM::InstructionSequence.compile("while true; redo; end").disasm ' ruby 1.9.0 (2007-08-08 patchlevel 0) [i686-linux] == disasm: @>================================= == catch table | catch type: break st: 0002 ed: 0007 sp: 0000 cont: 0007 | catch type: next st: 0002 ed: 0007 sp: 0000 cont: 0004 | catch type: redo st: 0002 ed: 0007 sp: 0000 cont: 0002 |------------------------------------------------------------------------ 0000 jump 4 ( 1) 0002 jump 2 0004 jump 2 0006 putnil 0007 leave 見た感じ iseq_peephole_optimize の goto again; で無限ループしているようです。 正しい修正かわかりませんが、とりあえず以下で動くようになりました。 Index: compile.c =================================================================== --- compile.c (revision 12903) +++ compile.c (working copy) @@ -1318,8 +1318,10 @@ REMOVE_ELEM(&iobj->link); } else if (iobj != diobj && diobj->insn_id == BIN(jump)) { - OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0); - goto again; + if (OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) { + OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0); + goto again; + } } else if (diobj->insn_id == BIN(leave)) { /* -- Yusuke ENDOH