diff --git a/iseq.c b/iseq.c index 971f1c54c7..6b8f3d0e2c 100644 --- a/iseq.c +++ b/iseq.c @@ -3232,6 +3232,25 @@ rb_vm_insn_addr2insn(const void *addr) rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr); } +// Unlike rb_vm_insn_addr2insn, this function can return trace opcode variants. +int +rb_vm_insn_addr2opcode(const void *addr) +{ + st_data_t key = (st_data_t)addr; + st_data_t val; + + if (st_lookup(rb_encoded_insn_data, key, &val)) { + insn_data_t *e = (insn_data_t *)val; + int opcode = e->insn; + if (addr == e->trace_encoded_insn) { + opcode += VM_INSTRUCTION_SIZE/2; + } + return opcode; + } + + rb_bug("rb_vm_insn_addr2opcode: invalid insn address: %p", addr); +} + // Decode `iseq->body->iseq_encoded[i]` to an insn. int rb_vm_insn_decode(const VALUE encoded) diff --git a/iseq.h b/iseq.h index ace5a45ba3..9b5eb138ad 100644 --- a/iseq.h +++ b/iseq.h @@ -167,6 +167,8 @@ const rb_iseq_t *rb_iseq_load_iseq(VALUE fname); unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body); #endif +int rb_vm_insn_addr2opcode(const void *addr); + RUBY_SYMBOL_EXPORT_BEGIN /* compile.c */ diff --git a/ujit_compile.c b/ujit_compile.c index 1d349b5664..f922088bcc 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -74,7 +74,7 @@ opcode_at_pc(const rb_iseq_t *iseq, const VALUE *pc) { const VALUE at_pc = *pc; if (FL_TEST_RAW((VALUE)iseq, ISEQ_TRANSLATED)) { - return rb_vm_insn_addr2insn((const void *)at_pc); + return rb_vm_insn_addr2opcode((const void *)at_pc); } else { return (int)at_pc;