YJIT: Fix `Struct` accessors not firing tracing events (#10690)

* YJIT: Fix `Struct` accessors not firing tracing events

Reading and writing to structs should fire `c_call` and `c_return`, but
YJIT wasn't correctly dropping those calls when tracing.
This has been missing since this functionality was added in 3081c83169,
but the added test only fails when ran in isolation with
`--yjit-call-threshold=1`. The test sometimes failed on CI.

* RJIT: YJIT: Fix `Struct` readers not firing tracing events

Same issue as YJIT, but it looks like RJIT doesn't support writing to
structs, so only reading needs changing.
This commit is contained in:
Alan Wu 2024-05-01 10:22:41 -04:00 коммит произвёл GitHub
Родитель f4c6479eea
Коммит 2a978ee047
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 38 добавлений и 4 удалений

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

@ -4964,3 +4964,19 @@ assert_equal '[[true, false, false], [true, false, true], [true, :error, :error]
results << test
} unless rjit_enabled? # Not yet working on RJIT
# test struct accessors fire c_call events
assert_equal '[[:c_call, :x=], [:c_call, :x]]', %q{
c = Struct.new(:x)
obj = c.new
events = []
TracePoint.new(:c_call) do
events << [_1.event, _1.method_id]
end.enable do
obj.x = 100
obj.x
end
events
}

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

@ -5461,6 +5461,12 @@ module RubyVM::RJIT
return CantCompile
end
if c_method_tracing_currently_enabled?
# Don't JIT if tracing c_call or c_return
asm.incr_counter(:send_cfunc_tracing)
return CantCompile
end
off = cme.def.body.optimized.index
recv_idx = argc # blockarg is not supported

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

@ -8309,6 +8309,13 @@ fn gen_struct_aref(
}
}
if c_method_tracing_currently_enabled(jit) {
// Struct accesses need fire c_call and c_return events, which we can't support
// See :attr-tracing:
gen_counter_incr(asm, Counter::send_cfunc_tracing);
return None;
}
// This is a .send call and we need to adjust the stack
if flags & VM_CALL_OPT_SEND != 0 {
handle_opt_send_shift_stack(asm, argc);
@ -8353,6 +8360,13 @@ fn gen_struct_aset(
return None;
}
if c_method_tracing_currently_enabled(jit) {
// Struct accesses need fire c_call and c_return events, which we can't support
// See :attr-tracing:
gen_counter_incr(asm, Counter::send_cfunc_tracing);
return None;
}
// This is a .send call and we need to adjust the stack
if flags & VM_CALL_OPT_SEND != 0 {
handle_opt_send_shift_stack(asm, argc);
@ -8619,10 +8633,8 @@ fn gen_send_general(
// Handling the C method tracing events for attr_accessor
// methods is easier than regular C methods as we know the
// "method" we are calling into never enables those tracing
// events. Once global invalidation runs, the code for the
// attr_accessor is invalidated and we exit at the closest
// instruction boundary which is always outside of the body of
// the attr_accessor code.
// events. We are never inside the code that needs to be
// invalidated when invalidation happens.
gen_counter_incr(asm, Counter::send_cfunc_tracing);
return None;
}