Trace :return of builtin methods
using opt_invokebuiltin_delegate_leave insn. Since Ruby 2.7, :return of methods using builtin have not been traced properly.
This commit is contained in:
parent
fbb32b1f48
commit
3e02cd518f
@ -1509,7 +1509,7 @@ opt_invokebuiltin_delegate_leave
|
|||||||
val = vm_invoke_builtin_delegate(ec, reg_cfp, bf, (unsigned int)index);
|
val = vm_invoke_builtin_delegate(ec, reg_cfp, bf, (unsigned int)index);
|
||||||
|
|
||||||
/* leave fastpath */
|
/* leave fastpath */
|
||||||
/* TracePoint/return should fallback this insn to opt_invokebuiltin_delegate */
|
/* TracePoint/return fallbacks this insn to opt_invokebuiltin_delegate */
|
||||||
if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
|
if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
|
||||||
#if OPT_CALL_THREADED_CODE
|
#if OPT_CALL_THREADED_CODE
|
||||||
rb_ec_thread_ptr(ec)->retval = val;
|
rb_ec_thread_ptr(ec)->retval = val;
|
||||||
|
6
iseq.c
6
iseq.c
@ -3125,8 +3125,12 @@ rb_vm_encoded_insn_data_table_init(void)
|
|||||||
encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2);
|
encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2);
|
||||||
|
|
||||||
for (insn = 0; insn < VM_INSTRUCTION_SIZE/2; insn++) {
|
for (insn = 0; insn < VM_INSTRUCTION_SIZE/2; insn++) {
|
||||||
|
int traced_insn = insn;
|
||||||
|
if (traced_insn == BIN(opt_invokebuiltin_delegate_leave)) {
|
||||||
|
traced_insn = BIN(opt_invokebuiltin_delegate); // to dispatch :return from leave
|
||||||
|
}
|
||||||
st_data_t key1 = (st_data_t)INSN_CODE(insn);
|
st_data_t key1 = (st_data_t)INSN_CODE(insn);
|
||||||
st_data_t key2 = (st_data_t)INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
|
st_data_t key2 = (st_data_t)INSN_CODE(traced_insn + VM_INSTRUCTION_SIZE/2);
|
||||||
|
|
||||||
insn_data[insn].insn = (int)insn;
|
insn_data[insn].insn = (int)insn;
|
||||||
insn_data[insn].insn_len = insn_len(insn);
|
insn_data[insn].insn_len = insn_len(insn);
|
||||||
|
@ -2292,4 +2292,18 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||||||
def test_stat_exists
|
def test_stat_exists
|
||||||
assert_instance_of Hash, TracePoint.stat
|
assert_instance_of Hash, TracePoint.stat
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_tracepoint_opt_invokebuiltin_delegate_leave
|
||||||
|
code = 'puts RubyVM::InstructionSequence.of("\x00".method(:unpack)).disasm'
|
||||||
|
out, _err, _status = EnvUtil.invoke_ruby(['-e', code], '', true)
|
||||||
|
assert_match /^0000 opt_invokebuiltin_delegate_leave /, out
|
||||||
|
|
||||||
|
events = []
|
||||||
|
TracePoint.new(:return) do |tp|
|
||||||
|
events << [tp.event, tp.method_id]
|
||||||
|
end.enable do
|
||||||
|
"\x00".unpack("c")
|
||||||
|
end
|
||||||
|
assert_equal [[:return, :unpack]], events
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user