mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

This commit collects statistics about how many binding objects are allocated as well as the number of local variables set on bindings. Statistics are output along with other YJIT stats. Here is an example of the output: ``` ***YJIT: Printing runtime counters from yjit.rb*** Number of Bindings Allocated: 195 Number of locals modified through binding: 0 opt_send_without_block exit reasons: ivar_get_method 7515891 (40.4%) se_cc_klass_differ 3081330 (16.6%) iseq_argc_mismatch 1564578 ( 8.4%) se_receiver_not_heap 1557663 ( 8.4%) ic_empty 1407064 ( 7.6%) optimized_method 995823 ( 5.4%) iseq_not_simple 819413 ( 4.4%) alias_method 706972 ( 3.8%) bmethod 685253 ( 3.7%) callsite_not_simple 225983 ( 1.2%) kw_splat 25999 ( 0.1%) ivar_set_method 902 ( 0.0%) cfunc_toomany_args 394 ( 0.0%) refined_method 42 ( 0.0%) cfunc_ruby_array_varg 29 ( 0.0%) invalid_cme 4 ( 0.0%) leave exit reasons: se_finish_frame 4067107 (100.0%) se_interrupt 24 ( 0.0%) getinstancevariable exit reasons: undef 121177 (100.0%) idx_out_of_range 5 ( 0.0%) opt_aref exit reasons: (all relevant counters are zero) compiled_iseq_count: 3944 main_block_code_size: 1.1 MiB side_block_code_size: 0.6 MiB vm_insns_count: 1137268516 yjit_exec_insns_count: 414015644 ratio_in_yjit: 26.7% avg_len_in_yjit: 7.5 total_exit_count: 55491789 most frequent exit op: opt_send_without_block: 18587628 (33.5%) opt_getinlinecache: 11075822 (20.0%) send: 4949300 (8.9%) leave: 4067131 (7.3%) defined: 3975196 (7.2%) setinstancevariable: 3567315 (6.4%) invokesuper: 2982163 (5.4%) getblockparamproxy: 2168852 (3.9%) opt_nil_p: 2104524 (3.8%) opt_aref: 2013858 (3.6%) ``` Running RailsBench allocates 195 binding objects but doesn't set any local variables.
97 lines
2.7 KiB
C
97 lines
2.7 KiB
C
//
|
|
// These are definitions YJIT uses to interface with the CRuby codebase,
|
|
// but which are only used internally by YJIT.
|
|
//
|
|
|
|
#ifndef YJIT_IFACE_H
|
|
#define YJIT_IFACE_H 1
|
|
|
|
#include "ruby/ruby.h"
|
|
#include "ruby/assert.h" // for RUBY_DEBUG
|
|
#include "vm_core.h"
|
|
#include "yjit_core.h"
|
|
|
|
#if RUBY_DEBUG
|
|
|
|
#define YJIT_DECLARE_COUNTERS(...) struct rb_yjit_runtime_counters { \
|
|
int64_t __VA_ARGS__; \
|
|
}; \
|
|
static char yjit_counter_names[] = #__VA_ARGS__;
|
|
|
|
YJIT_DECLARE_COUNTERS(
|
|
exec_instruction,
|
|
|
|
oswb_callsite_not_simple,
|
|
oswb_kw_splat,
|
|
oswb_ic_empty,
|
|
oswb_invalid_cme,
|
|
oswb_ivar_set_method,
|
|
oswb_ivar_get_method,
|
|
oswb_zsuper_method,
|
|
oswb_alias_method,
|
|
oswb_undef_method,
|
|
oswb_optimized_method,
|
|
oswb_missing_method,
|
|
oswb_bmethod,
|
|
oswb_refined_method,
|
|
oswb_unknown_method_type,
|
|
oswb_cfunc_ruby_array_varg,
|
|
oswb_cfunc_argc_mismatch,
|
|
oswb_cfunc_toomany_args,
|
|
oswb_iseq_tailcall,
|
|
oswb_iseq_argc_mismatch,
|
|
oswb_iseq_not_simple,
|
|
oswb_not_implemented_method,
|
|
oswb_se_receiver_not_heap,
|
|
oswb_se_cf_overflow,
|
|
oswb_se_cc_klass_differ,
|
|
oswb_se_protected_check_failed,
|
|
|
|
leave_se_finish_frame,
|
|
leave_se_interrupt,
|
|
leave_interp_return,
|
|
|
|
getivar_se_self_not_heap,
|
|
getivar_idx_out_of_range,
|
|
getivar_undef,
|
|
|
|
oaref_argc_not_one,
|
|
oaref_arg_not_fixnum,
|
|
|
|
binding_allocations,
|
|
binding_set,
|
|
|
|
// Member with known name for iterating over counters
|
|
last_member
|
|
)
|
|
|
|
#undef YJIT_DECLARE_COUNTERS
|
|
|
|
#endif // if RUBY_DEBUG
|
|
|
|
RUBY_EXTERN struct rb_yjit_options rb_yjit_opts;
|
|
RUBY_EXTERN int64_t rb_compiled_iseq_count;
|
|
RUBY_EXTERN struct rb_yjit_runtime_counters yjit_runtime_counters;
|
|
|
|
void cb_write_pre_call_bytes(codeblock_t* cb);
|
|
void cb_write_post_call_bytes(codeblock_t* cb);
|
|
|
|
VALUE *iseq_pc_at_idx(const rb_iseq_t *iseq, uint32_t insn_idx);
|
|
void map_addr2insn(void *code_ptr, int insn);
|
|
int opcode_at_pc(const rb_iseq_t *iseq, const VALUE *pc);
|
|
|
|
void check_cfunc_dispatch(VALUE receiver, struct rb_callinfo *ci, void *callee, rb_callable_method_entry_t *compile_time_cme);
|
|
bool cfunc_needs_frame(const rb_method_cfunc_t *cfunc);
|
|
|
|
RBIMPL_ATTR_NODISCARD() bool assume_bop_not_redefined(block_t *block, int redefined_flag, enum ruby_basic_operators bop);
|
|
void assume_method_lookup_stable(VALUE receiver_klass, const rb_callable_method_entry_t *cme, block_t *block);
|
|
RBIMPL_ATTR_NODISCARD() bool assume_single_ractor_mode(block_t *block);
|
|
RBIMPL_ATTR_NODISCARD() bool assume_stable_global_constant_state(block_t *block);
|
|
|
|
// this function *must* return passed exit_pc
|
|
const VALUE *rb_yjit_count_side_exit_op(const VALUE *exit_pc);
|
|
|
|
void yjit_unlink_method_lookup_dependency(block_t *block);
|
|
void yjit_block_assumptions_free(block_t *block);
|
|
|
|
#endif // #ifndef YJIT_IFACE_
|