зеркало из https://github.com/github/ruby.git
Print JIT cancel when all JIT-ed code is cancelled
This commit is contained in:
Родитель
1a16940291
Коммит
b3f8c491ef
3
NEWS.md
3
NEWS.md
|
@ -176,6 +176,9 @@ Excluding feature bug fixes.
|
||||||
* The JIT compiler no longer skips compilation of methods longer than
|
* The JIT compiler no longer skips compilation of methods longer than
|
||||||
1000 instructions.
|
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]]
|
* `RubyVM::MJIT` is renamed to `RubyVM::JIT`. [[Feature #17490]]
|
||||||
|
|
||||||
## Static analysis
|
## Static analysis
|
||||||
|
|
12
mjit.c
12
mjit.c
|
@ -83,6 +83,16 @@ mjit_gc_exit_hook(void)
|
||||||
CRITICAL_SECTION_FINISH(4, "mjit_gc_exit_hook");
|
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
|
// Deal with ISeq movement from compactor
|
||||||
void
|
void
|
||||||
mjit_update_references(const rb_iseq_t *iseq)
|
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.
|
// 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.
|
// 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.
|
// 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
|
// Units in stale_units (list of over-speculated and invalidated code) are not referenced from
|
||||||
|
|
2
mjit.h
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);
|
extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
|
||||||
RUBY_SYMBOL_EXPORT_END
|
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 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_init(const struct mjit_options *opts);
|
||||||
extern void mjit_gc_start_hook(void);
|
extern void mjit_gc_start_hook(void);
|
||||||
|
@ -181,6 +182,7 @@ void mjit_finish(bool close_handle_p);
|
||||||
|
|
||||||
# else // USE_MJIT
|
# 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 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_cont_free(struct mjit_cont *cont){}
|
||||||
static inline void mjit_gc_start_hook(void){}
|
static inline void mjit_gc_start_hook(void){}
|
||||||
|
|
|
@ -10,6 +10,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
IGNORABLE_PATTERNS = [
|
IGNORABLE_PATTERNS = [
|
||||||
/\AJIT recompile: .+\n\z/,
|
/\AJIT recompile: .+\n\z/,
|
||||||
/\AJIT inline: .+\n\z/,
|
/\AJIT inline: .+\n\z/,
|
||||||
|
/\AJIT cancel: .+\n\z/,
|
||||||
/\ASuccessful MJIT finish\n\z/,
|
/\ASuccessful MJIT finish\n\z/,
|
||||||
]
|
]
|
||||||
MAX_CACHE_PATTERNS = [
|
MAX_CACHE_PATTERNS = [
|
||||||
|
@ -1100,6 +1101,14 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
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
|
def test_caller_locations_without_catch_table
|
||||||
out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
|
out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
|
||||||
begin;
|
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;
|
rb_event_flag_t enabled_iseq_events = ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS;
|
||||||
|
|
||||||
if (new_iseq_events & ~enabled_iseq_events) {
|
if (new_iseq_events & ~enabled_iseq_events) {
|
||||||
/* Stop calling all JIT-ed code. Compiling trace insns is not supported for now. */
|
// Stop calling all JIT-ed code. We can't rewrite existing JIT-ed code to trace_ insns for now.
|
||||||
#if USE_MJIT
|
mjit_cancel_all("TracePoint is enabled");
|
||||||
mjit_call_p = FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* write all ISeqs if and only if new events are added */
|
/* write all ISeqs if and only if new events are added */
|
||||||
rb_iseq_trace_set_all(new_iseq_events | enabled_iseq_events);
|
rb_iseq_trace_set_all(new_iseq_events | enabled_iseq_events);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче