aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-20 05:48:22 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-20 05:48:22 +0000
commitb2ffafd2383fef50933a725797b1ea7ae4fbdaea (patch)
treeaafd3533552ba67ce0f750d9f58829bbf990598f
parentb79899b56a9ebadf5c493c4df2419ebf63934381 (diff)
downloadruby-b2ffafd2383fef50933a725797b1ea7ae4fbdaea.tar.gz
Invalidate JIT-ed code if ISeq is moved by GC.compact
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--debug_counter.h2
-rw-r--r--mjit.c4
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb4
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb4
4 files changed, 9 insertions, 5 deletions
diff --git a/debug_counter.h b/debug_counter.h
index fbfe67e467..faf876a8c4 100644
--- a/debug_counter.h
+++ b/debug_counter.h
@@ -274,7 +274,7 @@ RB_DEBUG_COUNTER(mjit_cancel)
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)
diff --git a/mjit.c b/mjit.c
index 0cedd55e57..186702270d 100644
--- a/mjit.c
+++ b/mjit.c
@@ -120,6 +120,9 @@ mjit_update_references(const rb_iseq_t *iseq)
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)
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
diff --git a/tool/ruby_vm/views/_mjit_compile_insn.erb b/tool/ruby_vm/views/_mjit_compile_insn.erb
index f9acd81ed5..4488876da3 100644
--- a/tool/ruby_vm/views/_mjit_compile_insn.erb
+++ b/tool/ruby_vm/views/_mjit_compile_insn.erb
@@ -61,12 +61,12 @@
%
% # 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
diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb
index 31b1126a9d..da7e96581b 100644
--- a/tool/ruby_vm/views/_mjit_compile_send.erb
+++ b/tool/ruby_vm/views/_mjit_compile_send.erb
@@ -86,12 +86,12 @@
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");
}