Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
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  */
36 RB_DEBUG_COUNTER(mc_inline_hit)
37 RB_DEBUG_COUNTER(mc_inline_miss)
38 RB_DEBUG_COUNTER(mc_global_hit)
39 RB_DEBUG_COUNTER(mc_global_miss)
40 RB_DEBUG_COUNTER(mc_global_state_miss)
41 RB_DEBUG_COUNTER(mc_class_serial_miss)
42 RB_DEBUG_COUNTER(mc_cme_complement)
43 RB_DEBUG_COUNTER(mc_cme_complement_hit)
44 RB_DEBUG_COUNTER(mc_search_super)
45 RB_DEBUG_COUNTER(mc_miss_by_nome)
46 RB_DEBUG_COUNTER(mc_miss_by_distinct)
47 RB_DEBUG_COUNTER(mc_miss_by_refine)
48 RB_DEBUG_COUNTER(mc_miss_by_visi)
49 RB_DEBUG_COUNTER(mc_miss_spurious)
50 RB_DEBUG_COUNTER(mc_miss_reuse_call)
51 
52 /*
53  * call cache fastpath usage
54  */
55 RB_DEBUG_COUNTER(ccf_general)
56 RB_DEBUG_COUNTER(ccf_iseq_setup)
57 RB_DEBUG_COUNTER(ccf_iseq_setup_0start)
58 RB_DEBUG_COUNTER(ccf_iseq_setup_tailcall_0start)
59 RB_DEBUG_COUNTER(ccf_iseq_fix) /* several functions created with tool/mk_call_iseq_optimized.rb */
60 RB_DEBUG_COUNTER(ccf_iseq_opt) /* has_opt == TRUE (has optional parameters), but other flags are FALSE */
61 RB_DEBUG_COUNTER(ccf_iseq_kw1) /* vm_call_iseq_setup_kwparm_kwarg() */
62 RB_DEBUG_COUNTER(ccf_iseq_kw2) /* vm_call_iseq_setup_kwparm_nokwarg() */
63 RB_DEBUG_COUNTER(ccf_cfunc)
64 RB_DEBUG_COUNTER(ccf_ivar) /* attr_reader */
65 RB_DEBUG_COUNTER(ccf_attrset) /* attr_writer */
66 RB_DEBUG_COUNTER(ccf_method_missing)
67 RB_DEBUG_COUNTER(ccf_zsuper)
68 RB_DEBUG_COUNTER(ccf_bmethod)
69 RB_DEBUG_COUNTER(ccf_opt_send)
70 RB_DEBUG_COUNTER(ccf_opt_call)
71 RB_DEBUG_COUNTER(ccf_opt_block_call)
72 RB_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  */
84 RB_DEBUG_COUNTER(frame_push)
85 RB_DEBUG_COUNTER(frame_push_method)
86 RB_DEBUG_COUNTER(frame_push_block)
87 RB_DEBUG_COUNTER(frame_push_class)
88 RB_DEBUG_COUNTER(frame_push_top)
89 RB_DEBUG_COUNTER(frame_push_cfunc)
90 RB_DEBUG_COUNTER(frame_push_ifunc)
91 RB_DEBUG_COUNTER(frame_push_eval)
92 RB_DEBUG_COUNTER(frame_push_rescue)
93 RB_DEBUG_COUNTER(frame_push_dummy)
94 
95 RB_DEBUG_COUNTER(frame_R2R)
96 RB_DEBUG_COUNTER(frame_R2C)
97 RB_DEBUG_COUNTER(frame_C2C)
98 RB_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  */
111 RB_DEBUG_COUNTER(ivar_get_ic_hit)
112 RB_DEBUG_COUNTER(ivar_get_ic_miss)
113 RB_DEBUG_COUNTER(ivar_get_ic_miss_serial)
114 RB_DEBUG_COUNTER(ivar_get_ic_miss_unset)
115 RB_DEBUG_COUNTER(ivar_get_ic_miss_noobject)
116 RB_DEBUG_COUNTER(ivar_set_ic_hit)
117 RB_DEBUG_COUNTER(ivar_set_ic_miss)
118 RB_DEBUG_COUNTER(ivar_set_ic_miss_serial)
119 RB_DEBUG_COUNTER(ivar_set_ic_miss_unset)
120 RB_DEBUG_COUNTER(ivar_set_ic_miss_oorange)
121 RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject)
122 RB_DEBUG_COUNTER(ivar_get_base)
123 RB_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  */
132 RB_DEBUG_COUNTER(lvar_get)
133 RB_DEBUG_COUNTER(lvar_get_dynamic)
134 RB_DEBUG_COUNTER(lvar_set)
135 RB_DEBUG_COUNTER(lvar_set_dynamic)
136 RB_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  */
146 RB_DEBUG_COUNTER(gc_count)
147 RB_DEBUG_COUNTER(gc_minor_newobj)
148 RB_DEBUG_COUNTER(gc_minor_malloc)
149 RB_DEBUG_COUNTER(gc_minor_method)
150 RB_DEBUG_COUNTER(gc_minor_capi)
151 RB_DEBUG_COUNTER(gc_minor_stress)
152 RB_DEBUG_COUNTER(gc_major_nofree)
153 RB_DEBUG_COUNTER(gc_major_oldgen)
154 RB_DEBUG_COUNTER(gc_major_shady)
155 RB_DEBUG_COUNTER(gc_major_force)
156 RB_DEBUG_COUNTER(gc_major_oldmalloc)
157 
158 RB_DEBUG_COUNTER(gc_isptr_trial)
159 RB_DEBUG_COUNTER(gc_isptr_range)
160 RB_DEBUG_COUNTER(gc_isptr_align)
161 RB_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  */
201 RB_DEBUG_COUNTER(obj_newobj)
202 RB_DEBUG_COUNTER(obj_newobj_slowpath)
203 RB_DEBUG_COUNTER(obj_newobj_wb_unprotected)
204 RB_DEBUG_COUNTER(obj_free)
205 RB_DEBUG_COUNTER(obj_promote)
206 RB_DEBUG_COUNTER(obj_wb_unprotect)
207 
208 RB_DEBUG_COUNTER(obj_obj_embed)
209 RB_DEBUG_COUNTER(obj_obj_transient)
210 RB_DEBUG_COUNTER(obj_obj_ptr)
211 
212 RB_DEBUG_COUNTER(obj_str_ptr)
213 RB_DEBUG_COUNTER(obj_str_embed)
214 RB_DEBUG_COUNTER(obj_str_shared)
215 RB_DEBUG_COUNTER(obj_str_nofree)
216 RB_DEBUG_COUNTER(obj_str_fstr)
217 
218 RB_DEBUG_COUNTER(obj_ary_embed)
219 RB_DEBUG_COUNTER(obj_ary_transient)
220 RB_DEBUG_COUNTER(obj_ary_ptr)
221 RB_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  */
228 RB_DEBUG_COUNTER(obj_ary_shared_create)
229 RB_DEBUG_COUNTER(obj_ary_shared)
230 RB_DEBUG_COUNTER(obj_ary_shared_root_occupied)
231 
232 RB_DEBUG_COUNTER(obj_hash_empty)
233 RB_DEBUG_COUNTER(obj_hash_1)
234 RB_DEBUG_COUNTER(obj_hash_2)
235 RB_DEBUG_COUNTER(obj_hash_3)
236 RB_DEBUG_COUNTER(obj_hash_4)
237 RB_DEBUG_COUNTER(obj_hash_5_8)
238 RB_DEBUG_COUNTER(obj_hash_g8)
239 
240 RB_DEBUG_COUNTER(obj_hash_null)
241 RB_DEBUG_COUNTER(obj_hash_ar)
242 RB_DEBUG_COUNTER(obj_hash_st)
243 RB_DEBUG_COUNTER(obj_hash_transient)
244 RB_DEBUG_COUNTER(obj_hash_force_convert)
245 
246 RB_DEBUG_COUNTER(obj_struct_embed)
247 RB_DEBUG_COUNTER(obj_struct_transient)
248 RB_DEBUG_COUNTER(obj_struct_ptr)
249 
250 RB_DEBUG_COUNTER(obj_data_empty)
251 RB_DEBUG_COUNTER(obj_data_xfree)
252 RB_DEBUG_COUNTER(obj_data_imm_free)
253 RB_DEBUG_COUNTER(obj_data_zombie)
254 
255 RB_DEBUG_COUNTER(obj_match_under4)
256 RB_DEBUG_COUNTER(obj_match_ge4)
257 RB_DEBUG_COUNTER(obj_match_ge8)
258 RB_DEBUG_COUNTER(obj_match_ptr)
259 
260 RB_DEBUG_COUNTER(obj_iclass_ptr)
261 RB_DEBUG_COUNTER(obj_class_ptr)
262 RB_DEBUG_COUNTER(obj_module_ptr)
263 
264 RB_DEBUG_COUNTER(obj_bignum_ptr)
265 RB_DEBUG_COUNTER(obj_bignum_embed)
266 RB_DEBUG_COUNTER(obj_float)
267 RB_DEBUG_COUNTER(obj_complex)
268 RB_DEBUG_COUNTER(obj_rational)
269 
270 RB_DEBUG_COUNTER(obj_regexp_ptr)
271 RB_DEBUG_COUNTER(obj_file_ptr)
272 RB_DEBUG_COUNTER(obj_symbol)
273 
274 RB_DEBUG_COUNTER(obj_imemo_ment)
275 RB_DEBUG_COUNTER(obj_imemo_iseq)
276 RB_DEBUG_COUNTER(obj_imemo_env)
277 RB_DEBUG_COUNTER(obj_imemo_tmpbuf)
278 RB_DEBUG_COUNTER(obj_imemo_ast)
279 RB_DEBUG_COUNTER(obj_imemo_cref)
280 RB_DEBUG_COUNTER(obj_imemo_svar)
281 RB_DEBUG_COUNTER(obj_imemo_throw_data)
282 RB_DEBUG_COUNTER(obj_imemo_ifunc)
283 RB_DEBUG_COUNTER(obj_imemo_memo)
284 RB_DEBUG_COUNTER(obj_imemo_parser_strterm)
285 
286 /* ar_table */
287 RB_DEBUG_COUNTER(artable_hint_hit)
288 RB_DEBUG_COUNTER(artable_hint_miss)
289 RB_DEBUG_COUNTER(artable_hint_notfound)
290 
291 /* heap function counts
292  *
293  * * heap_xmalloc/realloc/xfree: call counts
294  */
295 RB_DEBUG_COUNTER(heap_xmalloc)
296 RB_DEBUG_COUNTER(heap_xrealloc)
297 RB_DEBUG_COUNTER(heap_xfree)
298 
299 /* transient_heap */
300 RB_DEBUG_COUNTER(theap_alloc)
301 RB_DEBUG_COUNTER(theap_alloc_fail)
302 RB_DEBUG_COUNTER(theap_evacuate)
303 
304 /* mjit_exec() counts */
305 RB_DEBUG_COUNTER(mjit_exec)
306 RB_DEBUG_COUNTER(mjit_exec_not_added)
307 RB_DEBUG_COUNTER(mjit_exec_not_added_add_iseq)
308 RB_DEBUG_COUNTER(mjit_exec_not_ready)
309 RB_DEBUG_COUNTER(mjit_exec_not_compiled)
310 RB_DEBUG_COUNTER(mjit_exec_call_func)
311 
312 /* MJIT <-> VM frame push counts */
313 RB_DEBUG_COUNTER(mjit_frame_VM2VM)
314 RB_DEBUG_COUNTER(mjit_frame_VM2JT)
315 RB_DEBUG_COUNTER(mjit_frame_JT2JT)
316 RB_DEBUG_COUNTER(mjit_frame_JT2VM)
317 
318 /* MJIT cancel counters */
319 RB_DEBUG_COUNTER(mjit_cancel)
320 RB_DEBUG_COUNTER(mjit_cancel_ivar_inline)
321 RB_DEBUG_COUNTER(mjit_cancel_send_inline)
322 RB_DEBUG_COUNTER(mjit_cancel_opt_insn) /* CALL_SIMPLE_METHOD */
323 RB_DEBUG_COUNTER(mjit_cancel_invalidate_all)
324 
325 /* rb_mjit_unit_list length */
326 RB_DEBUG_COUNTER(mjit_length_unit_queue)
327 RB_DEBUG_COUNTER(mjit_length_active_units)
328 RB_DEBUG_COUNTER(mjit_length_compact_units)
329 RB_DEBUG_COUNTER(mjit_length_stale_units)
330 
331 /* Other MJIT counters */
332 RB_DEBUG_COUNTER(mjit_compile_failures)
333 
334 /* load (not implemented yet) */
335 /*
336 RB_DEBUG_COUNTER(load_files)
337 RB_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
353 };
354 
355 #if USE_DEBUG_COUNTER
356 extern size_t rb_debug_counter[];
357 
358 inline static int
359 rb_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 
367 VALUE rb_debug_counter_reset(VALUE klass);
368 VALUE 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 
380 void rb_debug_counter_show_results(const char *msg);
381 
383 
384 size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr);
385 void ruby_debug_counter_reset(void);
386 void ruby_debug_counter_show_at_exit(int enable);
387 
389 
390 #endif /* RUBY_DEBUG_COUNTER_H */
RUBY_SYMBOL_EXPORT_END
#define RUBY_SYMBOL_EXPORT_END
Definition: missing.h:49
ruby_debug_counter_show_at_exit
void ruby_debug_counter_show_at_exit(int enable)
Definition: debug_counter.c:131
VALUE
unsigned long VALUE
Definition: ruby.h:102
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
add
#define add(x, y)
Definition: date_strftime.c:23
rb_debug_counter_type
rb_debug_counter_type
Definition: debug_counter.h:348
RB_DEBUG_COUNTER_MAX
@ RB_DEBUG_COUNTER_MAX
Definition: debug_counter.h:351
RUBY_SYMBOL_EXPORT_BEGIN
#define RUBY_SYMBOL_EXPORT_BEGIN
Definition: missing.h:48
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
ruby_debug_counter_get
RUBY_SYMBOL_EXPORT_BEGIN size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
Definition: debug_counter.c:121
rb_debug_counter_show_results
void rb_debug_counter_show_results(const char *msg)
Definition: debug_counter.c:116
ruby_debug_counter_reset
void ruby_debug_counter_reset(void)
Definition: debug_counter.c:126
RB_DEBUG_COUNTER
#define RB_DEBUG_COUNTER(name)
Definition: debug_counter.h:349
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39