ruby-changes:47398
From: nagachika <ko1@a...>
Date: Sat, 5 Aug 2017 11:43:17 +0900 (JST)
Subject: [ruby-changes:47398] nagachika:r59514 (ruby_2_4): merge revision(s) 58810, 58894: [Backport #13578]
nagachika 2017-08-05 11:43:08 +0900 (Sat, 05 Aug 2017) New Revision: 59514 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59514 Log: merge revision(s) 58810,58894: [Backport #13578] compile.c: fix catch-table labels optimization * compile.c (remove_unreachable_chunk): do not eliminate chunks followed by labels in catch-table entries. compile.c: fix possible use of uninitialized value LABEL::unremovable added by r58810 is not initialized by new_label_body(), making the optimization unstable. Modified directories: branches/ruby_2_4/ Modified files: branches/ruby_2_4/compile.c branches/ruby_2_4/test/ruby/test_optimization.rb branches/ruby_2_4/version.h Index: ruby_2_4/compile.c =================================================================== --- ruby_2_4/compile.c (revision 59513) +++ ruby_2_4/compile.c (revision 59514) @@ -66,6 +66,7 @@ typedef struct iseq_label_data { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/compile.c#L66 int refcnt; unsigned int set: 1; unsigned int rescued: 2; + unsigned int unremovable: 1; } LABEL; typedef struct iseq_insn_data { @@ -290,13 +291,15 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/compile.c#L291 #define ADD_ADJUST_RESTORE(seq, label) \ ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1)) +#define LABEL_UNREMOVABLE(label) \ + ((label) ? (LABEL_REF(label), (label)->unremovable=1) : 0) #define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) do { \ VALUE _e = rb_ary_new3(5, (type), \ (VALUE)(ls) | 1, (VALUE)(le) | 1, \ (VALUE)(iseqv), (VALUE)(lc) | 1); \ - if (ls) LABEL_REF(ls); \ - if (le) LABEL_REF(le); \ - if (lc) LABEL_REF(lc); \ + LABEL_UNREMOVABLE(ls); \ + LABEL_UNREMOVABLE(le); \ + LABEL_UNREMOVABLE(lc); \ rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \ } while (0) @@ -1034,7 +1037,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL * https://github.com/ruby/ruby/blob/trunk/ruby_2_4/compile.c#L1037 adjust->link.next = 0; adjust->label = label; adjust->line_no = line; - if (label) LABEL_REF(label); + LABEL_UNREMOVABLE(label); return adjust; } @@ -2015,9 +2018,30 @@ replace_destination(INSN *dobj, INSN *no https://github.com/ruby/ruby/blob/trunk/ruby_2_4/compile.c#L2018 static int remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i) { - int removed = 0; + LINK_ELEMENT *first = i, *end; + + if (!i) return 0; while (i) { if (IS_INSN(i)) { + if (IS_INSN_ID(i, jump) || IS_INSN_ID(i, leave)) { + break; + } + } + else if (IS_LABEL(i)) { + if (((LABEL *)i)->unremovable) return 0; + if (((LABEL *)i)->refcnt > 0) { + if (i == first) return 0; + i = i->prev; + break; + } + } + else return 0; + i = i->next; + } + end = i; + i = first; + do { + if (IS_INSN(i)) { struct rb_iseq_constant_body *body = iseq->body; VALUE insn = INSN_OF(i); int pos, len = insn_len(insn); @@ -2035,15 +2059,9 @@ remove_unreachable_chunk(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/ruby_2_4/compile.c#L2059 } } } - else if (IS_LABEL(i)) { - if (((LABEL *)i)->refcnt > 0) break; - } - else break; REMOVE_ELEM(i); - removed = 1; - i = i->next; - } - return removed; + } while ((i != end) && (i = i->next) != 0); + return 1; } static int Index: ruby_2_4/version.h =================================================================== --- ruby_2_4/version.h (revision 59513) +++ ruby_2_4/version.h (revision 59514) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1 #define RUBY_VERSION "2.4.2" #define RUBY_RELEASE_DATE "2017-08-05" -#define RUBY_PATCHLEVEL 177 +#define RUBY_PATCHLEVEL 178 #define RUBY_RELEASE_YEAR 2017 #define RUBY_RELEASE_MONTH 8 Index: ruby_2_4/test/ruby/test_optimization.rb =================================================================== --- ruby_2_4/test/ruby/test_optimization.rb (revision 59513) +++ ruby_2_4/test/ruby/test_optimization.rb (revision 59514) @@ -533,4 +533,12 @@ EOS https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_optimization.rb#L533 assert_equal(:ok, t) end end + + def test_retry_label_in_unreachable_chunk + bug = '[ruby-core:81272] [Bug #13578]' + assert_valid_syntax("#{<<-"begin;"}\n#{<<-"end;"}", bug) + begin; + def t; if false; case 42; when s {}; end; end; end + end; + end end Index: ruby_2_4 =================================================================== --- ruby_2_4 (revision 59513) +++ ruby_2_4 (revision 59514) Property changes on: ruby_2_4 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /trunk:r58810 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/