Print JIT cancel when all JIT-ed code is cancelled

This commit is contained in:
Takashi Kokubun 2021-08-12 22:54:40 -07:00
Родитель 1a16940291
Коммит b3f8c491ef
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6FFC433B12EE23DD
5 изменённых файлов: 27 добавлений и 5 удалений

Просмотреть файл

@ -176,6 +176,9 @@ Excluding feature bug fixes.
* The JIT compiler no longer skips compilation of methods longer than
1000 instructions.
* `--jit-verbose` and `--jit-warning` output "JIT cancel" when JIT-ed
code is disabled because TracePoint or GC.compact is used.
* `RubyVM::MJIT` is renamed to `RubyVM::JIT`. [[Feature #17490]]
## Static analysis

12
mjit.c
Просмотреть файл

@ -83,6 +83,16 @@ mjit_gc_exit_hook(void)
CRITICAL_SECTION_FINISH(4, "mjit_gc_exit_hook");
}
// Prohibit calling JIT-ed code and let existing JIT-ed frames exit before the next insn.
void
mjit_cancel_all(const char *reason)
{
mjit_call_p = false;
if (mjit_opts.warnings || mjit_opts.verbose) {
fprintf(stderr, "JIT cancel: Disabled JIT-ed code because %s\n", reason);
}
}
// Deal with ISeq movement from compactor
void
mjit_update_references(const rb_iseq_t *iseq)
@ -96,7 +106,7 @@ mjit_update_references(const rb_iseq_t *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.
// See mjit.h and tool/ruby_vm/views/_mjit_compile_insn.erb for how `mjit_call_p` is used.
mjit_call_p = false; // TODO: instead of cancelling all, invalidate only this one and recompile it with some threshold.
mjit_cancel_all("GC.compact is used"); // 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

2
mjit.h
Просмотреть файл

@ -90,6 +90,7 @@ extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
RUBY_SYMBOL_EXPORT_END
extern void mjit_cancel_all(const char *reason);
extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void mjit_init(const struct mjit_options *opts);
extern void mjit_gc_start_hook(void);
@ -181,6 +182,7 @@ void mjit_finish(bool close_handle_p);
# else // USE_MJIT
static inline void mjit_cancel_all(const char *reason){}
static inline struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec){return NULL;}
static inline void mjit_cont_free(struct mjit_cont *cont){}
static inline void mjit_gc_start_hook(void){}

Просмотреть файл

@ -10,6 +10,7 @@ class TestJIT < Test::Unit::TestCase
IGNORABLE_PATTERNS = [
/\AJIT recompile: .+\n\z/,
/\AJIT inline: .+\n\z/,
/\AJIT cancel: .+\n\z/,
/\ASuccessful MJIT finish\n\z/,
]
MAX_CACHE_PATTERNS = [
@ -1100,6 +1101,14 @@ class TestJIT < Test::Unit::TestCase
end;
end
def test_cancel_by_tracepoint
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 0, min_calls: 2)
begin;
TracePoint.new(:line) {}.enable
2.times {}
end;
end
def test_caller_locations_without_catch_table
out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
begin;

Просмотреть файл

@ -81,10 +81,8 @@ update_global_event_hook(rb_event_flag_t vm_events)
rb_event_flag_t enabled_iseq_events = ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS;
if (new_iseq_events & ~enabled_iseq_events) {
/* Stop calling all JIT-ed code. Compiling trace insns is not supported for now. */
#if USE_MJIT
mjit_call_p = FALSE;
#endif
// Stop calling all JIT-ed code. We can't rewrite existing JIT-ed code to trace_ insns for now.
mjit_cancel_all("TracePoint is enabled");
/* write all ISeqs if and only if new events are added */
rb_iseq_trace_set_all(new_iseq_events | enabled_iseq_events);