Do not compile C calls when C tracing is enabled

This commit is contained in:
Takashi Kokubun 2023-02-10 21:06:02 -08:00
Родитель 20e55be47c
Коммит 9e42f31574
5 изменённых файлов: 36 добавлений и 8 удалений

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

@ -1185,6 +1185,12 @@ module RubyVM::MJIT
frame_type |= C.VM_FRAME_FLAG_CFRAME_KW
end
# EXEC_EVENT_HOOK: RUBY_EVENT_C_CALL and RUBY_EVENT_C_RETURN
if C.rb_mjit_global_events & (C.RUBY_EVENT_C_CALL | C.RUBY_EVENT_C_RETURN) != 0
asm.incr_counter(:send_c_tracing)
return CantCompile
end
# rb_check_arity
if argc != cfunc.argc
asm.incr_counter(:send_arity)

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

@ -300,6 +300,9 @@ mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
// JIT buffer
uint8_t *rb_mjit_mem_block = NULL;
// `rb_ec_ractor_hooks(ec)->events` is moved to this variable during compilation.
rb_event_flag_t rb_mjit_global_events = 0;
// Basically mjit_opts.stats, but this becomes false during MJIT compilation.
static bool mjit_stats_p = false;
@ -316,17 +319,17 @@ rb_mjit_collect_vm_usage_insn(int insn)
#endif // YJIT_STATS
#define WITH_MJIT_DISABLED(stmt) do { \
#define WITH_MJIT_ISOLATED(stmt) do { \
rb_hook_list_t *global_hooks = rb_ec_ractor_hooks(GET_EC()); \
rb_event_flag_t original_events = global_hooks->events; \
bool original_call_p = mjit_call_p; \
rb_mjit_global_events = global_hooks->events; \
global_hooks->events = 0; \
bool original_call_p = mjit_call_p; \
mjit_stats_p = false; \
mjit_call_p = false; \
stmt; \
mjit_call_p = (mjit_cancel_p ? false : original_call_p); \
mjit_stats_p = mjit_opts.stats; \
global_hooks->events = original_events; \
global_hooks->events = rb_mjit_global_events; \
} while (0);
void
@ -341,7 +344,7 @@ mjit_cme_invalidate(void *data)
{
if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)data;
WITH_MJIT_DISABLED({
WITH_MJIT_ISOLATED({
VALUE cme_klass = rb_funcall(rb_mMJITC, rb_intern("rb_callable_method_entry_struct"), 0);
VALUE cme_ptr = rb_funcall(cme_klass, rb_intern("new"), 1, SIZET2NUM((size_t)cme));
rb_funcall(rb_mMJITHooks, rb_intern("on_cme_invalidate"), 1, cme_ptr);
@ -368,7 +371,7 @@ void
rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
{
if (!mjit_call_p) return;
WITH_MJIT_DISABLED({
WITH_MJIT_ISOLATED({
rb_funcall(rb_mMJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events));
});
}
@ -386,7 +389,7 @@ rb_mjit_compile(const rb_iseq_t *iseq)
RB_VM_LOCK_ENTER();
rb_vm_barrier();
WITH_MJIT_DISABLED({
WITH_MJIT_ISOLATED({
VALUE iseq_ptr = rb_funcall(rb_cMJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
VALUE cfp_ptr = rb_funcall(rb_cMJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)GET_EC()->cfp));
rb_funcall(rb_MJITCompiler, rb_intern("compile"), 2, iseq_ptr, cfp_ptr);
@ -406,7 +409,7 @@ rb_mjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p)
rb_control_frame_t *cfp = GET_EC()->cfp;
cfp->sp += sp_offset; // preserve stack values, also using the actual sp_offset to make jit.peek_at_stack work
WITH_MJIT_DISABLED({
WITH_MJIT_ISOLATED({
VALUE cfp_ptr = rb_funcall(rb_cMJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)cfp));
result = rb_funcall(rb_MJITCompiler, rb_intern("branch_stub_hit"), 3, branch_stub, cfp_ptr, RBOOL(target0_p));
});

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

@ -127,6 +127,7 @@ MJIT_RUNTIME_COUNTERS(
send_refined,
send_stackoverflow,
send_arity,
send_c_tracing,
send_iseq_not_simple,
send_iseq_kw_splat,

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

@ -149,6 +149,13 @@ module RubyVM::MJIT # :nodoc: all
Primitive.mjit_for_each_iseq(block)
end
def rb_mjit_global_events
Primitive.cstmt! %{
extern rb_event_flag_t rb_mjit_global_events;
return SIZET2NUM((size_t)rb_mjit_global_events);
}
end
#========================================================================================
#
# Old stuff
@ -354,6 +361,14 @@ module RubyVM::MJIT # :nodoc: all
Primitive.cexpr! %q{ UINT2NUM(RUBY_EVENT_CLASS) }
end
def C.RUBY_EVENT_C_CALL
Primitive.cexpr! %q{ UINT2NUM(RUBY_EVENT_C_CALL) }
end
def C.RUBY_EVENT_C_RETURN
Primitive.cexpr! %q{ UINT2NUM(RUBY_EVENT_C_RETURN) }
end
def C.SHAPE_CAPACITY_CHANGE
Primitive.cexpr! %q{ UINT2NUM(SHAPE_CAPACITY_CHANGE) }
end
@ -981,6 +996,7 @@ module RubyVM::MJIT # :nodoc: all
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_refined)")],
send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_stackoverflow)")],
send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_arity)")],
send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_c_tracing)")],
send_iseq_not_simple: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_iseq_not_simple)")],
send_iseq_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_iseq_kw_splat)")],
send_cfunc_variadic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc_variadic)")],

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

@ -359,6 +359,8 @@ generator = BindingGenerator.new(
METHOD_VISI_PUBLIC
ROBJECT_EMBED
RUBY_EVENT_CLASS
RUBY_EVENT_C_CALL
RUBY_EVENT_C_RETURN
SHAPE_CAPACITY_CHANGE
SHAPE_FLAG_SHIFT
SHAPE_FROZEN