diff --git a/vm_exec.c b/vm_exec.c index 0adaa7b721..2c7e22228a 100644 --- a/vm_exec.c +++ b/vm_exec.c @@ -15,6 +15,36 @@ static void vm_analysis_insn(int insn); #endif +#if USE_INSNS_COUNTER +static size_t rb_insns_counter[VM_INSTRUCTION_SIZE]; + +static void +vm_insns_counter_count_insn(int insn) +{ + rb_insns_counter[insn]++; +} + +__attribute__((destructor)) +static void +vm_insns_counter_show_results_at_exit(void) +{ + int insn_end = (ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS) + ? VM_INSTRUCTION_SIZE : VM_INSTRUCTION_SIZE / 2; + + size_t total = 0; + for (int insn = 0; insn < insn_end; insn++) + total += rb_insns_counter[insn]; + + for (int insn = 0; insn < insn_end; insn++) { + fprintf(stderr, "[RUBY_INSNS_COUNTER]\t%-32s%'12"PRIuSIZE" (%4.1f%%)\n", + insn_name(insn), rb_insns_counter[insn], + 100.0 * rb_insns_counter[insn] / total); + } +} +#else +static void vm_insns_counter_count_insn(int insn) {} +#endif + #if VMDEBUG > 0 #define DECL_SC_REG(type, r, reg) register type reg_##r diff --git a/vm_exec.h b/vm_exec.h index 9c8b42371d..86a70fe8ad 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -41,6 +41,10 @@ typedef rb_iseq_t *ISEQ; #define throwdebug if(0)printf /* #define throwdebug printf */ +#ifndef USE_INSNS_COUNTER +#define USE_INSNS_COUNTER 0 +#endif + /************************************************/ #if defined(DISPATCH_XXX) error ! @@ -75,7 +79,8 @@ error ! (reg_pc - reg_cfp->iseq->body->iseq_encoded), \ (reg_cfp->pc - reg_cfp->iseq->body->iseq_encoded), \ RSTRING_PTR(rb_iseq_path(reg_cfp->iseq)), \ - rb_iseq_line_no(reg_cfp->iseq, reg_pc - reg_cfp->iseq->body->iseq_encoded)); + rb_iseq_line_no(reg_cfp->iseq, reg_pc - reg_cfp->iseq->body->iseq_encoded)); \ + if (USE_INSNS_COUNTER) vm_insns_counter_count_insn(BIN(insn)); #define INSN_DISPATCH_SIG(insn)