ruby-changes:50059
From: normal <ko1@a...>
Date: Sat, 3 Feb 2018 16:25:26 +0900 (JST)
Subject: [ruby-changes:50059] normal:r62177 (trunk): compile.c: fix string Range optimization with FSL
normal 2018-02-03 16:25:21 +0900 (Sat, 03 Feb 2018) New Revision: 62177 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62177 Log: compile.c: fix string Range optimization with FSL The optimization in [Feature #13355] needs to be detected differently to work with "frozen_string_literal: true" Modified files: trunk/compile.c trunk/test/ruby/test_optimization.rb Index: test/ruby/test_optimization.rb =================================================================== --- test/ruby/test_optimization.rb (revision 62176) +++ test/ruby/test_optimization.rb (revision 62177) @@ -557,12 +557,14 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L557 when "1.8.0"..."1.8.8" then :bar end end; - iseq = RubyVM::InstructionSequence.compile(code) - insn = iseq.disasm - assert_match %r{putobject\s+#{Regexp.quote('"1.8.0"..."1.8.8"')}}, insn - assert_match %r{putobject\s+#{Regexp.quote('"2.0.0".."2.3.2"')}}, insn - assert_no_match(/putstring/, insn) - assert_no_match(/newrange/, insn) + [ nil, { frozen_string_literal: true } ].each do |opt| + iseq = RubyVM::InstructionSequence.compile(code, nil, nil, opt) + insn = iseq.disasm + assert_match %r{putobject\s+#{Regexp.quote('"1.8.0"..."1.8.8"')}}, insn + assert_match %r{putobject\s+#{Regexp.quote('"2.0.0".."2.3.2"')}}, insn + assert_no_match(/putstring/, insn) + assert_no_match(/newrange/, insn) + end end def test_branch_condition_backquote Index: compile.c =================================================================== --- compile.c (revision 62176) +++ compile.c (revision 62177) @@ -2455,6 +2455,20 @@ same_debug_pos_p(LINK_ELEMENT *iobj1, LI https://github.com/ruby/ruby/blob/trunk/compile.c#L2455 } static int +is_frozen_putstring(INSN *insn, VALUE *op) +{ + if (IS_INSN_ID(insn, putstring)) { + *op = OPERAND_AT(insn, 0); + return 1; + } + else if (IS_INSN_ID(insn, putobject)) { /* frozen_string_literal */ + *op = OPERAND_AT(insn, 0); + return RB_TYPE_P(*op, T_STRING); + } + return 0; +} + +static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) { INSN *const iobj = (INSN *)list; @@ -2574,16 +2588,15 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2588 * putobject "beg".."end" */ if (IS_INSN_ID(iobj, checkmatch)) { - INSN *range = (INSN *)get_prev_insn(iobj); - INSN *beg, *end; + INSN *range = (INSN *)get_prev_insn(iobj); + INSN *beg, *end; + VALUE str_beg, str_end; if (range && IS_INSN_ID(range, newrange) && - (end = (INSN *)get_prev_insn(range)) != 0 && - IS_INSN_ID(end, putstring) && - (beg = (INSN *)get_prev_insn(end)) != 0 && - IS_INSN_ID(beg, putstring)) { - VALUE str_beg = OPERAND_AT(beg, 0); - VALUE str_end = OPERAND_AT(end, 0); + (end = (INSN *)get_prev_insn(range)) != 0 && + is_frozen_putstring(end, &str_end) && + (beg = (INSN *)get_prev_insn(end)) != 0 && + is_frozen_putstring(beg, &str_beg)) { int excl = FIX2INT(OPERAND_AT(range, 0)); VALUE lit_range = rb_range_new(str_beg, str_end, excl); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/