summaryrefslogtreecommitdiff
path: root/yjit_iface.c
diff options
context:
space:
mode:
authorNoah Gibbs <noah.gibbs@shopify.com>2021-06-29 16:36:05 +0100
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:36 -0400
commitd2e9932908cf1a1075d07157bfa520a1714d43b0 (patch)
tree272c21b261b45cf0b41bb0274c26a94638bcfb06 /yjit_iface.c
parent33227b1094d349bd64a2a588825cdf530ea5c459 (diff)
Convert YJIT stats reporting on exit from C to Ruby.
Diffstat (limited to 'yjit_iface.c')
-rw-r--r--yjit_iface.c125
1 files changed, 0 insertions, 125 deletions
diff --git a/yjit_iface.c b/yjit_iface.c
index e8a6dde969..a019458074 100644
--- a/yjit_iface.c
+++ b/yjit_iface.c
@@ -796,9 +796,6 @@ reset_stats_bang(rb_execution_context_t *ec, VALUE self)
#include "yjit.rbinc"
-#if RUBY_DEBUG
-// implementation for --yjit-stats
-
void
rb_yjit_collect_vm_usage_insn(int insn)
{
@@ -825,128 +822,6 @@ rb_yjit_count_side_exit_op(const VALUE *exit_pc)
return exit_pc; // This function must return exit_pc!
}
-struct insn_count {
- int64_t insn;
- int64_t count;
-};
-
-static int
-insn_count_sort_comp(const void *a, const void *b)
-{
- const struct insn_count *count_a = a;
- const struct insn_count *count_b = b;
- if (count_a->count > count_b->count) {
- return -1;
- }
- else if (count_a->count < count_b->count) {
- return 1;
- }
- return 0;
-}
-
-static struct insn_count insn_sorting_buffer[VM_INSTRUCTION_SIZE];
-static const struct insn_count *
-sort_insn_count_array(int64_t *array)
-{
- for (int i = 0; i < VM_INSTRUCTION_SIZE; i++) {
- insn_sorting_buffer[i] = (struct insn_count) { i, array[i] };
- }
- qsort(insn_sorting_buffer, VM_INSTRUCTION_SIZE, sizeof(insn_sorting_buffer[0]), &insn_count_sort_comp);
- return insn_sorting_buffer;
-}
-
-// Compute the total interpreter exit count
-static int64_t
-calc_total_exit_count()
-{
- size_t total_exit_count = 0;
- for (int i = 0; i < VM_INSTRUCTION_SIZE; i++) {
- total_exit_count += exit_op_count[i];
- }
-
- return total_exit_count;
-}
-
-static void
-print_insn_count_buffer(int how_many, int left_pad)
-{
- size_t total_exit_count = calc_total_exit_count();
-
- // Sort the exit ops by decreasing frequency
- const struct insn_count *sorted_exit_ops = sort_insn_count_array(exit_op_count);
-
- // Compute the longest instruction name and top10_exit_count
- size_t longest_insn_len = 0;
- size_t top10_exit_count = 0;
- for (int i = 0; i < how_many; i++) {
- const char *instruction_name = insn_name(sorted_exit_ops[i].insn);
- size_t len = strlen(instruction_name);
- if (len > longest_insn_len) {
- longest_insn_len = len;
- }
- top10_exit_count += sorted_exit_ops[i].count;
- }
-
- double top10_exit_percent = 100.0 * top10_exit_count / total_exit_count;
-
- fprintf(stderr, "top-%d most frequent exit ops (%.1f%% of exits):\n", how_many, top10_exit_percent);
-
- // Print the top-N most frequent exit counts
- for (int i = 0; i < how_many; i++) {
- const char *instruction_name = insn_name(sorted_exit_ops[i].insn);
- size_t padding = left_pad + longest_insn_len - strlen(instruction_name);
- for (size_t j = 0; j < padding; j++) {
- fputc(' ', stderr);
- }
- double percent = 100 * sorted_exit_ops[i].count / (double)total_exit_count;
- fprintf(stderr, "%s: %10" PRId64 " (%.1f%%)\n", instruction_name, sorted_exit_ops[i].count, percent);
- }
-}
-
-__attribute__((destructor))
-static void
-print_yjit_stats(void)
-{
- if (!rb_yjit_opts.gen_stats) {
- return;
- }
-
- // Warn if the executable code block is out of the relative
- // 32-bit jump range away from compiled C code
- ptrdiff_t start_diff = (cb->mem_block + cb->mem_size) - (uint8_t*)&print_yjit_stats;
- if (start_diff < INT32_MIN || start_diff > INT32_MAX) {
- fprintf(stderr, "WARNING: end of code block past rel32 offset range from C code\n");
- }
-
- // Compute the total exit count
- int64_t total_exit_count = calc_total_exit_count();
-
- // Number of instructions that finish executing in YJIT. See :count-placement:.
- int64_t retired_in_yjit = yjit_runtime_counters.exec_instruction - total_exit_count;
-
- // Average length of instruction sequences executed by YJIT
- double avg_len_in_yjit = (double)retired_in_yjit / total_exit_count;
-
- // Proportion of instructions that retire in YJIT
- int64_t total_insns_count = retired_in_yjit + yjit_runtime_counters.vm_insns_count;
- double ratio = retired_in_yjit / (double)total_insns_count;
-
- fprintf(stderr, "compiled_iseq_count: %10" PRId64 "\n", yjit_runtime_counters.compiled_iseq_count);
- fprintf(stderr, "inline_code_size: %10d\n", cb->write_pos);
- fprintf(stderr, "outlined_code_size: %10d\n", ocb->write_pos);
-
- fprintf(stderr, "total_exit_count: %10" PRId64 "\n", total_exit_count);
- fprintf(stderr, "total_insns_count: %10" PRId64 "\n", total_insns_count);
- fprintf(stderr, "vm_insns_count: %10" PRId64 "\n", yjit_runtime_counters.vm_insns_count);
- fprintf(stderr, "yjit_insns_count: %10" PRId64 "\n", yjit_runtime_counters.exec_instruction);
- fprintf(stderr, "ratio_in_yjit: %9.1f%%\n", ratio * 100);
- fprintf(stderr, "avg_len_in_yjit: %10.1f\n", avg_len_in_yjit);
-
- // Print the top-N most frequent exit ops
- print_insn_count_buffer(20, 4);
-}
-#endif // if RUBY_DEBUG
-
void
rb_yjit_iseq_mark(const struct rb_iseq_constant_body *body)
{