[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]