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

ruby-changes:55429

From: k0kubun <ko1@a...>
Date: Sat, 20 Apr 2019 14:48:27 +0900 (JST)
Subject: [ruby-changes:55429] k0kubun:r67638 (trunk): Invalidate JIT-ed code if ISeq is moved by GC.compact

k0kubun	2019-04-20 14:48:22 +0900 (Sat, 20 Apr 2019)

  New Revision: 67638

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

  Log:
    Invalidate JIT-ed code if ISeq is moved by GC.compact

  Modified files:
    trunk/debug_counter.h
    trunk/mjit.c
    trunk/tool/ruby_vm/views/_mjit_compile_insn.erb
    trunk/tool/ruby_vm/views/_mjit_compile_send.erb
Index: mjit.c
===================================================================
--- mjit.c	(revision 67637)
+++ mjit.c	(revision 67638)
@@ -120,6 +120,9 @@ mjit_update_references(const rb_iseq_t * https://github.com/ruby/ruby/blob/trunk/mjit.c#L120
     CRITICAL_SECTION_START(4, "mjit_free_iseq");
     if (iseq->body->jit_unit) {
         iseq->body->jit_unit->iseq = (rb_iseq_t *)rb_gc_new_location((VALUE)iseq->body->jit_unit->iseq);
+        // We need to invalidate JIT-ed code for the ISeq because it embeds pointer addresses.
+        // To efficiently do that, we use the same thing as TracePoint and thus everything is cancelled for now.
+        mjit_call_p = false; // TODO: instead of cancelling all, invalidate only this one and recompile it with some threshold.
     }
 
     // Units in stale_units (list of over-speculated and invalidated code) are not referenced from
@@ -313,6 +316,7 @@ unload_units(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L316
     for (cont = first_cont; cont != NULL; cont = cont->next) {
         mark_ec_units(cont->ec);
     }
+    // TODO: check slale_units and unload unused ones! (note that the unit is not associated to ISeq anymore)
 
     // Remove 1/10 units more to decrease unloading calls.
     // TODO: Calculate max total_calls in unit_queue and don't unload units
Index: debug_counter.h
===================================================================
--- debug_counter.h	(revision 67637)
+++ debug_counter.h	(revision 67638)
@@ -274,7 +274,7 @@ RB_DEBUG_COUNTER(mjit_cancel) https://github.com/ruby/ruby/blob/trunk/debug_counter.h#L274
 RB_DEBUG_COUNTER(mjit_cancel_ivar_inline)
 RB_DEBUG_COUNTER(mjit_cancel_send_inline)
 RB_DEBUG_COUNTER(mjit_cancel_opt_insn) /* CALL_SIMPLE_METHOD */
-RB_DEBUG_COUNTER(mjit_cancel_trace)
+RB_DEBUG_COUNTER(mjit_cancel_invalidate_all)
 
 /* rb_mjit_unit_list length */
 RB_DEBUG_COUNTER(mjit_length_unit_queue)
Index: tool/ruby_vm/views/_mjit_compile_insn.erb
===================================================================
--- tool/ruby_vm/views/_mjit_compile_insn.erb	(revision 67637)
+++ tool/ruby_vm/views/_mjit_compile_insn.erb	(revision 67638)
@@ -61,12 +61,12 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_insn.erb#L61
 %
 % # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow.
 % unless insn.always_leaf?
-        fprintf(f, "    if (UNLIKELY(ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS)) {\n");
+        fprintf(f, "    if (UNLIKELY(!mjit_call_p)) {\n");
         fprintf(f, "        reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %>);
         if (!pc_moved_p) {
             fprintf(f, "        reg_cfp->pc = original_body_iseq + %d;\n", next_pos);
         }
-        fprintf(f, "        RB_DEBUG_COUNTER_INC(mjit_cancel_trace);\n");
+        fprintf(f, "        RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n");
         fprintf(f, "        goto cancel;\n");
         fprintf(f, "    }\n");
 % end
Index: tool/ruby_vm/views/_mjit_compile_send.erb
===================================================================
--- tool/ruby_vm/views/_mjit_compile_send.erb	(revision 67637)
+++ tool/ruby_vm/views/_mjit_compile_send.erb	(revision 67638)
@@ -86,12 +86,12 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_send.erb#L86
                 fprintf(f, "    }\n");
 
 % # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow.
-                fprintf(f, "    if (UNLIKELY(ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS)) {\n");
+                fprintf(f, "    if (UNLIKELY(!mjit_call_p)) {\n");
                 fprintf(f, "        reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %>);
                 if (!pc_moved_p) {
                     fprintf(f, "        reg_cfp->pc = original_body_iseq + %d;\n", next_pos);
                 }
-                fprintf(f, "        RB_DEBUG_COUNTER_INC(mjit_cancel_trace);\n");
+                fprintf(f, "        RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n");
                 fprintf(f, "        goto cancel;\n");
                 fprintf(f, "    }\n");
             }

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

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