From: Yusuke ENDOH Date: 2009-10-09T01:03:44+09:00 Subject: [ruby-dev:39448] Re: coverage and ensure 遠藤です。 2009年9月11日1:51 Tanaka Akira : > coverage で、ensure 節内の文が数えられない気がします。 > > % cat z.rb > begin > p 1 > ensure > p 2 > end > % ./ruby -rcoverage -ve ' > Coverage.start > load "z.rb" > p Coverage.result > ' > ruby 1.9.2dev (2009-09-10 trunk 24826) [i686-linux] > 1 > 2 > {"z.rb"=>[1, 1, nil, 0, nil]} ものすごく遅くなってすみません。 p "foo"; p "bar" のような複文のある行に対して実行回数を重複して数える のを避けるために、同じ行に対するカバレッジのイベントを 1 回しか挿入 しないようにしていたのですが、ensure の中身は例外が起きた場合と通常 終了した場合にコードがコピーされるため、複数個のカバレッジイベントを 挿入する必要がありました。 どうするか悩んだのですが、同じ行を「連続して」コンパイルする場合に、 1 回だけカバレッジイベントを発生するようにしてみました。 とりあえずこの方法で対処して、問題が見つかったら考えようと思います。 Index: iseq.c =================================================================== --- iseq.c (revision 25260) +++ iseq.c (working copy) @@ -249,6 +249,7 @@ iseq->compile_data->storage_head->buff = (char *)(&iseq->compile_data->storage_head->buff + 1); iseq->compile_data->option = option; + iseq->compile_data->last_coverable_line = -1; set_relation(iseq, parent); Index: iseq.h =================================================================== --- iseq.h (revision 25260) +++ iseq.h (working copy) @@ -82,6 +82,7 @@ struct iseq_compile_data_storage *storage_head; struct iseq_compile_data_storage *storage_current; int last_line; + int last_coverable_line; int flip_cnt; int label_no; int node_level; Index: compile.c =================================================================== --- compile.c (revision 25260) +++ compile.c (working copy) @@ -223,8 +223,9 @@ #define ADD_TRACE(seq, line, event) \ do { \ if ((event) == RUBY_EVENT_LINE && iseq->coverage && \ - RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \ + (line) != iseq->compile_data->last_coverable_line) { \ RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \ + iseq->compile_data->last_coverable_line = (line); \ ADD_INSN1(seq, line, trace, INT2FIX(RUBY_EVENT_COVERAGE)); \ } \ if (iseq->compile_data->option->trace_instruction) { \ -- Yusuke ENDOH