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

ruby-changes:53142

From: k0kubun <ko1@a...>
Date: Thu, 25 Oct 2018 00:41:20 +0900 (JST)
Subject: [ruby-changes:53142] k0kubun:r65356 (trunk): _mjit_compile_ivar.erb: cancel on undefined ivar

k0kubun	2018-10-25 00:41:14 +0900 (Thu, 25 Oct 2018)

  New Revision: 65356

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65356

  Log:
    _mjit_compile_ivar.erb: cancel on undefined ivar
    
    I assumed somehow this check was not needed, but it did need.
    By canceling this instead of just warning here, we didn't lose the
    current performance so much.
    
    test_jit.rb: test the case that reproduces SEGV by that.
    
    TestGemStreamUI.rb: delete. This test on --jit-wait is fixed.
    
    === Optcarrot Benchmark ===
    
    $ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems --jit;after::after --disable-gems --jit' -v --repeat-count 24
    before: ruby 2.6.0dev (2018-10-24 trunk 65355) +JIT [x86_64-linux]
    after: ruby 2.6.0dev (2018-10-24 trunk 65355) +JIT [x86_64-linux]
    last_commit=_mjit_compile_ivar.erb: cancel on undefined ivar
    Calculating -------------------------------------
                                 before       after
    Optcarrot Lan_Master.nes     85.344      84.849 fps
    
    Comparison:
                 Optcarrot Lan_Master.nes
                      before:        85.3 fps
                       after:        84.8 fps - 1.01x  slower

  Removed files:
    trunk/test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb
  Modified files:
    trunk/test/ruby/test_jit.rb
    trunk/tool/ruby_vm/views/_mjit_compile_ivar.erb
Index: test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb
===================================================================
--- test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb	(revision 65355)
+++ test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb	(nonexistent)
@@ -1,2 +0,0 @@ https://github.com/ruby/ruby/blob/trunk/test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb#L0
-# debugging this right now
-exclude(/.*/, 'this fails with --jit-wait')

Property changes on: test/excludes/_wercker/test-mjit-wait/TestGemStreamUI.rb
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-LF
\ No newline at end of property
Index: tool/ruby_vm/views/_mjit_compile_ivar.erb
===================================================================
--- tool/ruby_vm/views/_mjit_compile_ivar.erb	(revision 65355)
+++ tool/ruby_vm/views/_mjit_compile_ivar.erb	(revision 65356)
@@ -26,19 +26,19 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_ivar.erb#L26
         fprintf(f, "    VALUE obj = GET_SELF();\n");
         fprintf(f, "    const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->ic_serial);
         fprintf(f, "    const st_index_t index = %"PRIuSIZE";\n", ic_copy->ic_value.index);
+% # JIT: cache hit path of vm_getivar, or cancel JIT.
 % if insn.name == 'setinstancevariable'
         fprintf(f, "    VALUE val = stack[%d];\n", b->stack_size - 1);
-% end
-%
-% # JIT: cache hit path of vm_getivar, or cancel JIT.
         fprintf(f, "    if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj))) {\n");
-% if insn.name == 'setinstancevariable'
         fprintf(f, "        VALUE *ptr = ROBJECT_IVPTR(obj);\n");
         fprintf(f, "        RB_OBJ_WRITE(obj, &ptr[index], val);\n");
+        fprintf(f, "    }\n");
 % else
-        fprintf(f, "        stack[%d] = ROBJECT_IVPTR(obj)[index];\n", b->stack_size);
-% end
+        fprintf(f, "    VALUE val;\n");
+        fprintf(f, "    if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n");
+        fprintf(f, "        stack[%d] = val;\n", b->stack_size);
         fprintf(f, "    }\n");
+% end
         fprintf(f, "    else {\n");
         fprintf(f, "        reg_cfp->pc = original_body_iseq + %d;\n", pos);
         fprintf(f, "        reg_cfp->sp = (VALUE *)reg_cfp->bp + %d;\n", b->stack_size + 1);
Index: test/ruby/test_jit.rb
===================================================================
--- test/ruby/test_jit.rb	(revision 65355)
+++ test/ruby/test_jit.rb	(revision 65356)
@@ -669,6 +669,27 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L669
     end;
   end
 
+  def test_inlined_undefined_ivar
+    assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "bbb", success_count: 2, min_calls: 3)
+    begin;
+      class Foo
+        def initialize
+          @a = :a
+        end
+
+        def bar
+          if @b.nil?
+            @b = :b
+          end
+        end
+      end
+
+      print(Foo.new.bar)
+      print(Foo.new.bar)
+      print(Foo.new.bar)
+    end;
+  end
+
   def test_attr_reader
     assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "4nil\nnil\n6", success_count: 2, min_calls: 2)
     begin;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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