зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
b79899b56a
Коммит
b2ffafd238
|
@ -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)
|
||||
|
|
4
mjit.c
4
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче