diff options
author | Jeremy Evans <[email protected]> | 2023-10-26 17:03:17 -0700 |
---|---|---|
committer | Jeremy Evans <[email protected]> | 2023-12-07 10:29:33 -0800 |
commit | 3081c83169c55ef7eead6222e49248e09232c22c (patch) | |
tree | 6825cd4cd747f053b4d085801a888d9217ee1726 /vm_insnhelper.c | |
parent | 1721bb9dc6dcc3ecec05e9d6f72654099460ef50 (diff) |
Support tracing of struct member accessor methods
This follows the same approach used for attr_reader/attr_writer in
2d98593bf54a37397c6e4886ccc7e3654c2eaf85, skipping the checking for
tracing after the first call using the call cache, and clearing the
call cache when tracing is turned on/off.
Fixes [Bug #18886]
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 50ca9902fd..b72167f75d 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -4342,6 +4342,19 @@ vm_call_opt_struct_aset(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, NOINLINE(static VALUE vm_call_optimized(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci, const struct rb_callcache *cc)); +#define VM_CALL_METHOD_ATTR(var, func, nohook) \ + if (UNLIKELY(ruby_vm_event_flags & (RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN))) { \ + EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, calling->recv, vm_cc_cme(cc)->def->original_id, \ + vm_ci_mid(ci), vm_cc_cme(cc)->owner, Qundef); \ + var = func; \ + EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, calling->recv, vm_cc_cme(cc)->def->original_id, \ + vm_ci_mid(ci), vm_cc_cme(cc)->owner, (var)); \ + } \ + else { \ + nohook; \ + var = func; \ + } + static VALUE vm_call_optimized(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci, const struct rb_callcache *cc) @@ -4356,35 +4369,33 @@ vm_call_optimized(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb case OPTIMIZED_METHOD_TYPE_BLOCK_CALL: CC_SET_FASTPATH(cc, vm_call_opt_block_call, TRUE); return vm_call_opt_block_call(ec, cfp, calling); - case OPTIMIZED_METHOD_TYPE_STRUCT_AREF: + case OPTIMIZED_METHOD_TYPE_STRUCT_AREF: { CALLER_SETUP_ARG(cfp, calling, ci, 0); rb_check_arity(calling->argc, 0, 0); - CC_SET_FASTPATH(cc, vm_call_opt_struct_aref, (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)); - return vm_call_opt_struct_aref(ec, cfp, calling); - case OPTIMIZED_METHOD_TYPE_STRUCT_ASET: + VALUE v; + VM_CALL_METHOD_ATTR(v, + vm_call_opt_struct_aref(ec, cfp, calling), + set_vm_cc_ivar(cc); \ + CC_SET_FASTPATH(cc, vm_call_opt_struct_aref, (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE))) + return v; + } + case OPTIMIZED_METHOD_TYPE_STRUCT_ASET: { CALLER_SETUP_ARG(cfp, calling, ci, 1); rb_check_arity(calling->argc, 1, 1); - CC_SET_FASTPATH(cc, vm_call_opt_struct_aset, (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)); - return vm_call_opt_struct_aset(ec, cfp, calling); + + VALUE v; + VM_CALL_METHOD_ATTR(v, + vm_call_opt_struct_aset(ec, cfp, calling), + set_vm_cc_ivar(cc); \ + CC_SET_FASTPATH(cc, vm_call_opt_struct_aset, (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE))) + return v; + } default: rb_bug("vm_call_method: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type); } } -#define VM_CALL_METHOD_ATTR(var, func, nohook) \ - if (UNLIKELY(ruby_vm_event_flags & (RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN))) { \ - EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, calling->recv, vm_cc_cme(cc)->def->original_id, \ - vm_ci_mid(ci), vm_cc_cme(cc)->owner, Qundef); \ - var = func; \ - EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, calling->recv, vm_cc_cme(cc)->def->original_id, \ - vm_ci_mid(ci), vm_cc_cme(cc)->owner, (var)); \ - } \ - else { \ - nohook; \ - var = func; \ - } - static VALUE vm_call_method_each_type(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling) { |