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

ruby-changes:62124

From: Takashi <ko1@a...>
Date: Sun, 5 Jul 2020 08:07:20 +0900 (JST)
Subject: [ruby-changes:62124] e4f7eee009 (master): Check ROBJECT_EMBED on guards-merged ivar access

https://git.ruby-lang.org/ruby.git/commit/?id=e4f7eee009

From e4f7eee009ebe1f23ee3e5ea69ccd9ea1530bc6f Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sat, 4 Jul 2020 15:37:20 -0700
Subject: Check ROBJECT_EMBED on guards-merged ivar access

Fix CI failure like
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3043247
introduced by a69dd699ee630dd1086627dbca15a218a8538b6f

diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index f929a8c..08093a5 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -921,6 +921,34 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L921
     end;
   end
 
+  def test_heap_promotion_of_ivar_in_the_middle_of_jit
+    assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, min_calls: 2)
+    begin;
+      class A
+        def initialize
+          @iv0 = nil
+          @iv1 = []
+          @iv2 = nil
+        end
+
+        def test(add)
+          @iv0.nil?
+          @iv2.nil?
+          add_ivar if add
+          @iv1.empty?
+        end
+
+        def add_ivar
+          @iv3 = nil
+        end
+      end
+
+      a = A.new
+      p a.test(false)
+      p a.test(true)
+    end;
+  end
+
   def test_jump_to_precompiled_branch
     assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
     begin;
diff --git a/tool/ruby_vm/views/_mjit_compile_ivar.erb b/tool/ruby_vm/views/_mjit_compile_ivar.erb
index 33dc60c..e50f4bf 100644
--- a/tool/ruby_vm/views/_mjit_compile_ivar.erb
+++ b/tool/ruby_vm/views/_mjit_compile_ivar.erb
@@ -24,30 +24,21 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_ivar.erb#L24
         fprintf(f, "{\n");
         fprintf(f, "    VALUE obj = GET_SELF();\n");
         fprintf(f, "    const st_index_t index = %"PRIuSIZE";\n", ic_copy->index);
-        fprintf(f, "    VALUE val;\n");
         if (status->merge_ivar_guards_p) {
 % # JIT: Access ivar without checking these VM_ASSERTed prerequisites as we checked them in the beginning of `mjit_compile_body`
             fprintf(f, "    VM_ASSERT(RB_TYPE_P(obj, T_OBJECT));\n");
             fprintf(f, "    VM_ASSERT((rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(obj)->klass));\n", ic_copy->ic_serial);
             fprintf(f, "    VM_ASSERT(index < ROBJECT_NUMIV(obj));\n");
 % if insn.name == 'setinstancevariable'
-            fprintf(f, "    if (LIKELY(!RB_OBJ_FROZEN(obj))) {\n");
-            fprintf(f, "        val = stack[%d];\n", b->stack_size - 1);
-            if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) {
-                fprintf(f, "        RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.heap.ivptr[index], val);\n");
-            }
-            else {
-                fprintf(f, "        RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.ary[index], val);\n");
-            }
+            fprintf(f, "    if (LIKELY(!RB_OBJ_FROZEN(obj) && %sRB_FL_ANY_RAW(obj, ROBJECT_EMBED))) {\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "!" : "");
+            fprintf(f, "        RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.%s, stack[%d]);\n",
+                    status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]", b->stack_size - 1);
             fprintf(f, "    }\n");
 % else
-            if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) {
-                fprintf(f, "    val = ROBJECT(obj)->as.heap.ivptr[index];\n");
-            }
-            else {
-                fprintf(f, "    val = ROBJECT(obj)->as.ary[index];\n");
-            }
-            fprintf(f, "    if (LIKELY(val != Qundef)) {\n");
+            fprintf(f, "    VALUE val;\n");
+            fprintf(f, "    if (LIKELY(%sRB_FL_ANY_RAW(obj, ROBJECT_EMBED) && (val = ROBJECT(obj)->as.%s) != Qundef)) {\n",
+                    status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "!" : "",
+                    status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]");
             fprintf(f, "        stack[%d] = val;\n", b->stack_size);
             fprintf(f, "    }\n");
 %end
@@ -56,12 +47,12 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_ivar.erb#L47
             fprintf(f, "    const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->ic_serial);
 % # JIT: cache hit path of vm_getivar/vm_setivar, or cancel JIT (recompile it with exivar)
 % if insn.name == 'setinstancevariable'
-            fprintf(f, "    val = stack[%d];\n", b->stack_size - 1);
             fprintf(f, "    if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && !RB_OBJ_FROZEN(obj))) {\n");
             fprintf(f, "        VALUE *ptr = ROBJECT_IVPTR(obj);\n");
-            fprintf(f, "        RB_OBJ_WRITE(obj, &ptr[index], val);\n");
+            fprintf(f, "        RB_OBJ_WRITE(obj, &ptr[index], stack[%d]);\n", b->stack_size - 1);
             fprintf(f, "    }\n");
 % else
+            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");
-- 
cgit v0.10.2


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

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