Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
debug_counter.h
Go to the documentation of this file.
1/**********************************************************************
2
3 debug_counter.h -
4
5 created at: Tue Feb 21 16:51:18 2017
6
7 Copyright (C) 2017 Koichi Sasada
8
9**********************************************************************/
10
11#ifndef USE_DEBUG_COUNTER
12#define USE_DEBUG_COUNTER 0
13#endif
14
15#ifdef RB_DEBUG_COUNTER
16
17/*
18 * method cache (mc) counts.
19 *
20 * * mc_inline_hit/miss: inline mc hit/miss counts (VM send insn)
21 * * mc_global_hit/miss: global method cache hit/miss counts
22 * two types: (1) inline cache miss (VM send insn)
23 * (2) called from C (rb_funcall).
24 * * mc_global_state_miss: inline mc miss by global_state miss.
25 * * mc_class_serial_miss: ... by mc_class_serial_miss
26 * * mc_cme_complement: callable_method_entry complement counts.
27 * * mc_cme_complement_hit: callable_method_entry cache hit counts.
28 * * mc_search_super: search_method() call counts.
29 * * mc_miss_by_nome: inline mc miss by no ment.
30 * * mc_miss_by_distinct: ... by distinct ment.
31 * * mc_miss_by_refine: ... by ment being refined.
32 * * mc_miss_by_visi: ... by visibility change.
33 * * mc_miss_spurious: spurious inline mc misshit.
34 * * mc_miss_reuse_call: count of reuse of cc->call.
35 */
36RB_DEBUG_COUNTER(mc_inline_hit)
37RB_DEBUG_COUNTER(mc_inline_miss)
38RB_DEBUG_COUNTER(mc_global_hit)
39RB_DEBUG_COUNTER(mc_global_miss)
40RB_DEBUG_COUNTER(mc_global_state_miss)
41RB_DEBUG_COUNTER(mc_class_serial_miss)
42RB_DEBUG_COUNTER(mc_cme_complement)
43RB_DEBUG_COUNTER(mc_cme_complement_hit)
44RB_DEBUG_COUNTER(mc_search_super)
45RB_DEBUG_COUNTER(mc_miss_by_nome)
46RB_DEBUG_COUNTER(mc_miss_by_distinct)
47RB_DEBUG_COUNTER(mc_miss_by_refine)
48RB_DEBUG_COUNTER(mc_miss_by_visi)
49RB_DEBUG_COUNTER(mc_miss_spurious)
50RB_DEBUG_COUNTER(mc_miss_reuse_call)
51
52/*
53 * call cache fastpath usage
54 */
55RB_DEBUG_COUNTER(ccf_general)
56RB_DEBUG_COUNTER(ccf_iseq_setup)
57RB_DEBUG_COUNTER(ccf_iseq_setup_0start)
58RB_DEBUG_COUNTER(ccf_iseq_setup_tailcall_0start)
59RB_DEBUG_COUNTER(ccf_iseq_fix) /* several functions created with tool/mk_call_iseq_optimized.rb */
60RB_DEBUG_COUNTER(ccf_iseq_opt) /* has_opt == TRUE (has optional parameters), but other flags are FALSE */
61RB_DEBUG_COUNTER(ccf_iseq_kw1) /* vm_call_iseq_setup_kwparm_kwarg() */
62RB_DEBUG_COUNTER(ccf_iseq_kw2) /* vm_call_iseq_setup_kwparm_nokwarg() */
63RB_DEBUG_COUNTER(ccf_cfunc)
64RB_DEBUG_COUNTER(ccf_ivar) /* attr_reader */
65RB_DEBUG_COUNTER(ccf_attrset) /* attr_writer */
66RB_DEBUG_COUNTER(ccf_method_missing)
67RB_DEBUG_COUNTER(ccf_zsuper)
68RB_DEBUG_COUNTER(ccf_bmethod)
69RB_DEBUG_COUNTER(ccf_opt_send)
70RB_DEBUG_COUNTER(ccf_opt_call)
71RB_DEBUG_COUNTER(ccf_opt_block_call)
72RB_DEBUG_COUNTER(ccf_super_method)
73
74/*
75 * control frame push counts.
76 *
77 * * frame_push: frame push counts.
78 * * frame_push_*: frame push counts per each type.
79 * * frame_R2R: Ruby frame to Ruby frame
80 * * frame_R2C: Ruby frame to C frame
81 * * frame_C2C: C frame to C frame
82 * * frame_C2R: C frame to Ruby frame
83 */
84RB_DEBUG_COUNTER(frame_push)
85RB_DEBUG_COUNTER(frame_push_method)
86RB_DEBUG_COUNTER(frame_push_block)
87RB_DEBUG_COUNTER(frame_push_class)
88RB_DEBUG_COUNTER(frame_push_top)
89RB_DEBUG_COUNTER(frame_push_cfunc)
90RB_DEBUG_COUNTER(frame_push_ifunc)
91RB_DEBUG_COUNTER(frame_push_eval)
92RB_DEBUG_COUNTER(frame_push_rescue)
93RB_DEBUG_COUNTER(frame_push_dummy)
94
95RB_DEBUG_COUNTER(frame_R2R)
96RB_DEBUG_COUNTER(frame_R2C)
97RB_DEBUG_COUNTER(frame_C2C)
98RB_DEBUG_COUNTER(frame_C2R)
99
100/* instance variable counts
101 *
102 * * ivar_get_ic_hit/miss: ivar_get inline cache (ic) hit/miss counts (VM insn)
103 * * ivar_get_ic_miss_serial: ivar_get ic miss reason by serial (VM insn)
104 * * ivar_get_ic_miss_unset: ... by unset (VM insn)
105 * * ivar_get_ic_miss_noobject: ... by "not T_OBJECT" (VM insn)
106 * * ivar_set_...: same counts with ivar_set (VM insn)
107 * * ivar_get/set_base: call counts of "rb_ivar_get/set()".
108 * because of (1) ic miss.
109 * (2) direct call by C extensions.
110 */
111RB_DEBUG_COUNTER(ivar_get_ic_hit)
112RB_DEBUG_COUNTER(ivar_get_ic_miss)
113RB_DEBUG_COUNTER(ivar_get_ic_miss_serial)
114RB_DEBUG_COUNTER(ivar_get_ic_miss_unset)
115RB_DEBUG_COUNTER(ivar_get_ic_miss_noobject)
116RB_DEBUG_COUNTER(ivar_set_ic_hit)
117RB_DEBUG_COUNTER(ivar_set_ic_miss)
118RB_DEBUG_COUNTER(ivar_set_ic_miss_serial)
119RB_DEBUG_COUNTER(ivar_set_ic_miss_unset)
120RB_DEBUG_COUNTER(ivar_set_ic_miss_oorange)
121RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject)
122RB_DEBUG_COUNTER(ivar_get_base)
123RB_DEBUG_COUNTER(ivar_set_base)
124
125/* local variable counts
126 *
127 * * lvar_get: total lvar get counts (VM insn)
128 * * lvar_get_dynamic: lvar get counts if accessing upper env (VM insn)
129 * * lvar_set*: same as "get"
130 * * lvar_set_slowpath: counts using vm_env_write_slowpath()
131 */
132RB_DEBUG_COUNTER(lvar_get)
133RB_DEBUG_COUNTER(lvar_get_dynamic)
134RB_DEBUG_COUNTER(lvar_set)
135RB_DEBUG_COUNTER(lvar_set_dynamic)
136RB_DEBUG_COUNTER(lvar_set_slowpath)
137
138/* GC counts:
139 *
140 * * count: simple count
141 * * _minor: minor gc
142 * * _major: major gc
143 * * other suffix is corresponding to last_gc_info or
144 * gc_profile_record_flag in gc.c.
145 */
146RB_DEBUG_COUNTER(gc_count)
147RB_DEBUG_COUNTER(gc_minor_newobj)
148RB_DEBUG_COUNTER(gc_minor_malloc)
149RB_DEBUG_COUNTER(gc_minor_method)
150RB_DEBUG_COUNTER(gc_minor_capi)
151RB_DEBUG_COUNTER(gc_minor_stress)
152RB_DEBUG_COUNTER(gc_major_nofree)
153RB_DEBUG_COUNTER(gc_major_oldgen)
154RB_DEBUG_COUNTER(gc_major_shady)
155RB_DEBUG_COUNTER(gc_major_force)
156RB_DEBUG_COUNTER(gc_major_oldmalloc)
157
158RB_DEBUG_COUNTER(gc_isptr_trial)
159RB_DEBUG_COUNTER(gc_isptr_range)
160RB_DEBUG_COUNTER(gc_isptr_align)
161RB_DEBUG_COUNTER(gc_isptr_maybe)
162
163/* object allocation counts:
164 *
165 * * obj_newobj: newobj counts
166 * * obj_newobj_slowpath: newobj with slowpath counts
167 * * obj_newobj_wb_unprotected: newobj for wb_unprotecte.
168 * * obj_free: obj_free() counts
169 * * obj_promote: promoted counts (oldgen)
170 * * obj_wb_unprotect: wb unprotect counts
171 *
172 * * obj_[type]_[attr]: *free'ed counts* for each type.
173 * Note that it is not a allocated counts.
174 * * [type]
175 * * _obj: T_OBJECT
176 * * _str: T_STRING
177 * * _ary: T_ARRAY
178 * * _xxx: T_XXX (hash, struct, ...)
179 *
180 * * [attr]
181 * * _ptr: R?? is not embed.
182 * * _embed: R?? is embed.
183 * * _transient: R?? uses transient heap.
184 * * type specific attr.
185 * * str_shared: str is shared.
186 * * str_nofree: nofree
187 * * str_fstr: fstr
188 * * hash_empty: hash is empty
189 * * hash_1_4: has 1 to 4 entries
190 * * hash_5_8: has 5 to 8 entries
191 * * hash_g8: has n entries (n>8)
192 * * match_under4: has under 4 oniguruma regions allocated
193 * * match_ge4: has n regions allocated (4<=n<8)
194 * * match_ge8: has n regions allocated (8<=n)
195 * * data_empty: T_DATA but no memory free.
196 * * data_xfree: free'ed by xfree().
197 * * data_imm_free: free'ed immediately.
198 * * data_zombie: free'ed with zombie.
199 * * imemo_*: T_IMEMO with each type.
200 */
201RB_DEBUG_COUNTER(obj_newobj)
202RB_DEBUG_COUNTER(obj_newobj_slowpath)
203RB_DEBUG_COUNTER(obj_newobj_wb_unprotected)
204RB_DEBUG_COUNTER(obj_free)
205RB_DEBUG_COUNTER(obj_promote)
206RB_DEBUG_COUNTER(obj_wb_unprotect)
207
208RB_DEBUG_COUNTER(obj_obj_embed)
209RB_DEBUG_COUNTER(obj_obj_transient)
210RB_DEBUG_COUNTER(obj_obj_ptr)
211
212RB_DEBUG_COUNTER(obj_str_ptr)
213RB_DEBUG_COUNTER(obj_str_embed)
214RB_DEBUG_COUNTER(obj_str_shared)
215RB_DEBUG_COUNTER(obj_str_nofree)
216RB_DEBUG_COUNTER(obj_str_fstr)
217
218RB_DEBUG_COUNTER(obj_ary_embed)
219RB_DEBUG_COUNTER(obj_ary_transient)
220RB_DEBUG_COUNTER(obj_ary_ptr)
221RB_DEBUG_COUNTER(obj_ary_extracapa)
222/*
223 ary_shared_create: shared ary by Array#dup and so on.
224 ary_shared: finished in shard.
225 ary_shared_root_occupied: shared_root but has only 1 refcnt.
226 The number (ary_shared - ary_shared_root_occupied) is meaningful.
227 */
228RB_DEBUG_COUNTER(obj_ary_shared_create)
229RB_DEBUG_COUNTER(obj_ary_shared)
230RB_DEBUG_COUNTER(obj_ary_shared_root_occupied)
231
232RB_DEBUG_COUNTER(obj_hash_empty)
233RB_DEBUG_COUNTER(obj_hash_1)
234RB_DEBUG_COUNTER(obj_hash_2)
235RB_DEBUG_COUNTER(obj_hash_3)
236RB_DEBUG_COUNTER(obj_hash_4)
237RB_DEBUG_COUNTER(obj_hash_5_8)
238RB_DEBUG_COUNTER(obj_hash_g8)
239
240RB_DEBUG_COUNTER(obj_hash_null)
241RB_DEBUG_COUNTER(obj_hash_ar)
242RB_DEBUG_COUNTER(obj_hash_st)
243RB_DEBUG_COUNTER(obj_hash_transient)
244RB_DEBUG_COUNTER(obj_hash_force_convert)
245
246RB_DEBUG_COUNTER(obj_struct_embed)
247RB_DEBUG_COUNTER(obj_struct_transient)
248RB_DEBUG_COUNTER(obj_struct_ptr)
249
250RB_DEBUG_COUNTER(obj_data_empty)
251RB_DEBUG_COUNTER(obj_data_xfree)
252RB_DEBUG_COUNTER(obj_data_imm_free)
253RB_DEBUG_COUNTER(obj_data_zombie)
254
255RB_DEBUG_COUNTER(obj_match_under4)
256RB_DEBUG_COUNTER(obj_match_ge4)
257RB_DEBUG_COUNTER(obj_match_ge8)
258RB_DEBUG_COUNTER(obj_match_ptr)
259
260RB_DEBUG_COUNTER(obj_iclass_ptr)
261RB_DEBUG_COUNTER(obj_class_ptr)
262RB_DEBUG_COUNTER(obj_module_ptr)
263
264RB_DEBUG_COUNTER(obj_bignum_ptr)
265RB_DEBUG_COUNTER(obj_bignum_embed)
266RB_DEBUG_COUNTER(obj_float)
267RB_DEBUG_COUNTER(obj_complex)
268RB_DEBUG_COUNTER(obj_rational)
269
270RB_DEBUG_COUNTER(obj_regexp_ptr)
271RB_DEBUG_COUNTER(obj_file_ptr)
272RB_DEBUG_COUNTER(obj_symbol)
273
274RB_DEBUG_COUNTER(obj_imemo_ment)
275RB_DEBUG_COUNTER(obj_imemo_iseq)
276RB_DEBUG_COUNTER(obj_imemo_env)
277RB_DEBUG_COUNTER(obj_imemo_tmpbuf)
278RB_DEBUG_COUNTER(obj_imemo_ast)
279RB_DEBUG_COUNTER(obj_imemo_cref)
280RB_DEBUG_COUNTER(obj_imemo_svar)
281RB_DEBUG_COUNTER(obj_imemo_throw_data)
282RB_DEBUG_COUNTER(obj_imemo_ifunc)
283RB_DEBUG_COUNTER(obj_imemo_memo)
284RB_DEBUG_COUNTER(obj_imemo_parser_strterm)
285
286/* ar_table */
287RB_DEBUG_COUNTER(artable_hint_hit)
288RB_DEBUG_COUNTER(artable_hint_miss)
289RB_DEBUG_COUNTER(artable_hint_notfound)
290
291/* heap function counts
292 *
293 * * heap_xmalloc/realloc/xfree: call counts
294 */
295RB_DEBUG_COUNTER(heap_xmalloc)
296RB_DEBUG_COUNTER(heap_xrealloc)
297RB_DEBUG_COUNTER(heap_xfree)
298
299/* transient_heap */
300RB_DEBUG_COUNTER(theap_alloc)
301RB_DEBUG_COUNTER(theap_alloc_fail)
302RB_DEBUG_COUNTER(theap_evacuate)
303
304/* mjit_exec() counts */
305RB_DEBUG_COUNTER(mjit_exec)
306RB_DEBUG_COUNTER(mjit_exec_not_added)
307RB_DEBUG_COUNTER(mjit_exec_not_added_add_iseq)
308RB_DEBUG_COUNTER(mjit_exec_not_ready)
309RB_DEBUG_COUNTER(mjit_exec_not_compiled)
310RB_DEBUG_COUNTER(mjit_exec_call_func)
311
312/* MJIT <-> VM frame push counts */
313RB_DEBUG_COUNTER(mjit_frame_VM2VM)
314RB_DEBUG_COUNTER(mjit_frame_VM2JT)
315RB_DEBUG_COUNTER(mjit_frame_JT2JT)
316RB_DEBUG_COUNTER(mjit_frame_JT2VM)
317
318/* MJIT cancel counters */
319RB_DEBUG_COUNTER(mjit_cancel)
320RB_DEBUG_COUNTER(mjit_cancel_ivar_inline)
321RB_DEBUG_COUNTER(mjit_cancel_send_inline)
322RB_DEBUG_COUNTER(mjit_cancel_opt_insn) /* CALL_SIMPLE_METHOD */
323RB_DEBUG_COUNTER(mjit_cancel_invalidate_all)
324
325/* rb_mjit_unit_list length */
326RB_DEBUG_COUNTER(mjit_length_unit_queue)
327RB_DEBUG_COUNTER(mjit_length_active_units)
328RB_DEBUG_COUNTER(mjit_length_compact_units)
329RB_DEBUG_COUNTER(mjit_length_stale_units)
330
331/* Other MJIT counters */
332RB_DEBUG_COUNTER(mjit_compile_failures)
333
334/* load (not implemented yet) */
335/*
336RB_DEBUG_COUNTER(load_files)
337RB_DEBUG_COUNTER(load_path_is_not_realpath)
338*/
339#endif
340
341#ifndef RUBY_DEBUG_COUNTER_H
342#define RUBY_DEBUG_COUNTER_H 1
343
344#if !defined(__GNUC__) && USE_DEBUG_COUNTER
345#error "USE_DEBUG_COUNTER is not supported by other than __GNUC__"
346#endif
347
349#define RB_DEBUG_COUNTER(name) RB_DEBUG_COUNTER_##name,
350#include __FILE__
352#undef RB_DEBUG_COUNTER
354
355#if USE_DEBUG_COUNTER
356extern size_t rb_debug_counter[];
357
358inline static int
359rb_debug_counter_add(enum rb_debug_counter_type type, int add, int cond)
360{
361 if (cond) {
362 rb_debug_counter[(int)type] += add;
363 }
364 return cond;
365}
366
367VALUE rb_debug_counter_reset(VALUE klass);
368VALUE rb_debug_counter_show(VALUE klass);
369
370#define RB_DEBUG_COUNTER_INC(type) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, 1)
371#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (!rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, !(cond)))
372#define RB_DEBUG_COUNTER_INC_IF(type, cond) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, (cond))
373
374#else
375#define RB_DEBUG_COUNTER_INC(type) ((void)0)
376#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (cond)
377#define RB_DEBUG_COUNTER_INC_IF(type, cond) (cond)
378#endif
379
380void rb_debug_counter_show_results(const char *msg);
381
383
384size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr);
385void ruby_debug_counter_reset(void);
386void ruby_debug_counter_show_at_exit(int enable);
387
389
390#endif /* RUBY_DEBUG_COUNTER_H */
#define add(x, y)
Definition: date_strftime.c:23
@ RB_DEBUG_COUNTER_MAX
void rb_debug_counter_show_results(const char *msg)
#define RB_DEBUG_COUNTER(name)
RUBY_SYMBOL_EXPORT_BEGIN size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
void ruby_debug_counter_show_at_exit(int enable)
void ruby_debug_counter_reset(void)
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
#define RUBY_SYMBOL_EXPORT_BEGIN
unsigned long VALUE
#define RUBY_SYMBOL_EXPORT_END
__inline__ int