Skip to content

Commit cdc614c

Browse files
committed
refactoring debug_counter.
* debug_counter.h: add comments for each counters. * debug_counter.h: add some counters (see added comments for details). * obj_newobj * obj_newobj_slowpath * obj_newobj_wb_unprotected * obj_hash_empty * obj_hash_under4 * obj_hash_ge4 * obj_hash_ge8 * heap_xmalloc * heap_xrealloc * heap_xfree * gc.c: add some debug counters (see the above list). * debug_counter.c (rb_debug_counter_show_results): accept a header message. * signal.c (ruby_default_signal): show debug counter results and malloc info (rb_malloc_info_show_results()) before SIGNAL exit. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64841 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 989fc2d commit cdc614c

File tree

4 files changed

+138
-20
lines changed

4 files changed

+138
-20
lines changed

debug_counter.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
**********************************************************************/
1010

1111
#include "debug_counter.h"
12-
#include <stdio.h>
13-
1412
#if USE_DEBUG_COUNTER
13+
#include <stdio.h>
14+
#include <locale.h>
1515
#include "internal.h"
1616

1717
static const char *const debug_counter_names[] = {
@@ -23,19 +23,33 @@ static const char *const debug_counter_names[] = {
2323

2424
size_t rb_debug_counter[numberof(debug_counter_names)];
2525

26-
__attribute__((destructor))
27-
static void
28-
rb_debug_counter_show_results(void)
26+
void
27+
rb_debug_counter_show_results(const char *msg)
2928
{
3029
const char *env = getenv("RUBY_DEBUG_COUNTER_DISABLE");
30+
31+
setlocale(LC_NUMERIC, "");
32+
3133
if (env == NULL || strcmp("1", env) != 0) {
3234
int i;
35+
fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%d %s\n", getpid(), msg);
3336
for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
34-
fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%s\t%"PRIuSIZE"\n",
37+
fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%-30s\t%'12"PRIuSIZE"\n",
3538
debug_counter_names[i],
3639
rb_debug_counter[i]);
3740
}
3841
}
3942
}
4043

44+
__attribute__((destructor))
45+
static void
46+
debug_counter_show_results_at_exit(void)
47+
{
48+
rb_debug_counter_show_results("normal exit.");
49+
}
50+
#else
51+
void
52+
rb_debug_counter_show_results(const char *msg)
53+
{
54+
}
4155
#endif /* USE_DEBUG_COUNTER */

debug_counter.h

+81-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,19 @@
1414

1515
#ifdef RB_DEBUG_COUNTER
1616

17-
/* method search */
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: cme complement counts.
27+
* * mc_cme_complement_hit: cme cache hit counts.
28+
* * mc_search_super: search_method() call counts.
29+
*/
1830
RB_DEBUG_COUNTER(mc_inline_hit)
1931
RB_DEBUG_COUNTER(mc_inline_miss)
2032
RB_DEBUG_COUNTER(mc_global_hit)
@@ -25,7 +37,17 @@ RB_DEBUG_COUNTER(mc_cme_complement)
2537
RB_DEBUG_COUNTER(mc_cme_complement_hit)
2638
RB_DEBUG_COUNTER(mc_search_super)
2739

28-
/* ivar access */
40+
/* instance variable counts
41+
*
42+
* * ivar_get_ic_hit/miss: ivar_get inline cache (ic) hit/miss counts (VM insn)
43+
* * ivar_get_ic_miss_serial: ivar_get ic miss reason by serial (VM insn)
44+
* * ivar_get_ic_miss_unset: ... by unset (VM insn)
45+
* * ivar_get_ic_miss_noobject: ... by "not T_OBJECT" (VM insn)
46+
* * ivar_set_...: same counts with ivar_set (VM insn)
47+
* * ivar_get/set_base: call counts of "rb_ivar_get/set()".
48+
* because of (1) ic miss.
49+
* (2) direct call by C extensions.
50+
*/
2951
RB_DEBUG_COUNTER(ivar_get_ic_hit)
3052
RB_DEBUG_COUNTER(ivar_get_ic_miss)
3153
RB_DEBUG_COUNTER(ivar_get_ic_miss_serial)
@@ -40,16 +62,53 @@ RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject)
4062
RB_DEBUG_COUNTER(ivar_get_base)
4163
RB_DEBUG_COUNTER(ivar_set_base)
4264

43-
/* lvar access */
65+
/* local variable counts
66+
*
67+
* * lvar_get: total lvar get counts (VM insn)
68+
* * lvar_get_dynamic: lvar get counts if accessing upper env (VM insn)
69+
* * lvar_set*: same as "get"
70+
* * lvar_set_slowpath: counts using vm_env_write_slowpath()
71+
*/
4472
RB_DEBUG_COUNTER(lvar_get)
4573
RB_DEBUG_COUNTER(lvar_get_dynamic)
4674
RB_DEBUG_COUNTER(lvar_set)
4775
RB_DEBUG_COUNTER(lvar_set_dynamic)
4876
RB_DEBUG_COUNTER(lvar_set_slowpath)
4977

50-
/* object counts */
78+
/* object allocation counts:
79+
*
80+
* * obj_newobj: newobj counts
81+
* * obj_newobj_slowpath: newobj with slowpath counts
82+
* * obj_newobj_wb_unprotected: newobj for wb_unprotecte.
83+
* * obj_free: obj_free() counts
84+
*
85+
* * obj_[type]_[attr]: free'ed counts for each type.
86+
* * [type]
87+
* * _obj: T_OBJECT
88+
* * _str: T_STRING
89+
* * _ary: T_ARRAY
90+
* * _hash: T_HASH
91+
*
92+
* * [attr]
93+
* * _ptr: R?? is not embed.
94+
* * _embed: R?? is embed.
95+
* * type specific attr.
96+
* * str_shared: str is shared.
97+
* * str_nofree: nofree
98+
* * str_fstr: fstr
99+
* * hash_empty: hash is empty
100+
* * hash_under4: has under 4 entries
101+
* * hash_ge4: has n entries (4<=n<8)
102+
* * hash_ge8: has n entries (8<=n)
103+
*/
104+
RB_DEBUG_COUNTER(obj_newobj)
105+
RB_DEBUG_COUNTER(obj_newobj_slowpath)
106+
RB_DEBUG_COUNTER(obj_newobj_wb_unprotected)
51107
RB_DEBUG_COUNTER(obj_free)
52108

109+
RB_DEBUG_COUNTER(obj_obj_ptr)
110+
RB_DEBUG_COUNTER(obj_obj_embed)
111+
53112
RB_DEBUG_COUNTER(obj_str_ptr)
54113
RB_DEBUG_COUNTER(obj_str_embed)
55114
RB_DEBUG_COUNTER(obj_str_shared)
@@ -59,13 +118,24 @@ RB_DEBUG_COUNTER(obj_str_fstr)
59118
RB_DEBUG_COUNTER(obj_ary_ptr)
60119
RB_DEBUG_COUNTER(obj_ary_embed)
61120

62-
RB_DEBUG_COUNTER(obj_obj_ptr)
63-
RB_DEBUG_COUNTER(obj_obj_embed)
64-
65-
/* load */
121+
RB_DEBUG_COUNTER(obj_hash_empty)
122+
RB_DEBUG_COUNTER(obj_hash_under4)
123+
RB_DEBUG_COUNTER(obj_hash_ge4)
124+
RB_DEBUG_COUNTER(obj_hash_ge8)
125+
126+
/* heap function counts
127+
*
128+
* * heap_xmalloc/realloc/xfree: call counts
129+
*/
130+
RB_DEBUG_COUNTER(heap_xmalloc)
131+
RB_DEBUG_COUNTER(heap_xrealloc)
132+
RB_DEBUG_COUNTER(heap_xfree)
133+
134+
/* load (not implemented yet) */
135+
/*
66136
RB_DEBUG_COUNTER(load_files)
67137
RB_DEBUG_COUNTER(load_path_is_not_realpath)
68-
138+
*/
69139
#endif
70140

71141
#ifndef RUBY_DEBUG_COUNTER_H
@@ -106,4 +176,6 @@ rb_debug_counter_add(enum rb_debug_counter_type type, int add, int cond)
106176
#define RB_DEBUG_COUNTER_INC_IF(type, cond) (cond)
107177
#endif
108178

179+
void rb_debug_counter_show_results(const char *msg);
180+
109181
#endif /* RUBY_DEBUG_COUNTER_H */

gc.c

+29-5
Original file line numberDiff line numberDiff line change
@@ -1948,6 +1948,9 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protect
19481948
rb_objspace_t *objspace = &rb_objspace;
19491949
VALUE obj;
19501950

1951+
RB_DEBUG_COUNTER_INC(obj_newobj);
1952+
(void)RB_DEBUG_COUNTER_INC_IF(obj_newobj_wb_unprotected, !wb_protected);
1953+
19511954
#if GC_DEBUG_STRESS_TO_CLASS
19521955
if (UNLIKELY(stress_to_class)) {
19531956
long i, cnt = RARRAY_LEN(stress_to_class);
@@ -1964,6 +1967,8 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protect
19641967
return newobj_init(klass, flags, v1, v2, v3, wb_protected, objspace, obj);
19651968
}
19661969
else {
1970+
RB_DEBUG_COUNTER_INC(obj_newobj_slowpath);
1971+
19671972
return wb_protected ?
19681973
newobj_slowpath_wb_protected(klass, flags, v1, v2, v3, objspace) :
19691974
newobj_slowpath_wb_unprotected(klass, flags, v1, v2, v3, objspace);
@@ -2256,7 +2261,20 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
22562261
case T_HASH:
22572262
if (RANY(obj)->as.hash.ntbl) {
22582263
st_free_table(RANY(obj)->as.hash.ntbl);
2264+
2265+
if (RHASH_SIZE(obj) >= 8) {
2266+
RB_DEBUG_COUNTER_INC(obj_hash_ge8);
2267+
}
2268+
if (RHASH_SIZE(obj) >= 4) {
2269+
RB_DEBUG_COUNTER_INC(obj_hash_ge4);
2270+
}
2271+
else {
2272+
RB_DEBUG_COUNTER_INC(obj_hash_under4);
2273+
}
22592274
}
2275+
else {
2276+
RB_DEBUG_COUNTER_INC(obj_hash_empty);
2277+
}
22602278
break;
22612279
case T_REGEXP:
22622280
if (RANY(obj)->as.regexp.ptr) {
@@ -7959,6 +7977,7 @@ objspace_xmalloc0(rb_objspace_t *objspace, size_t size)
79597977

79607978
size = objspace_malloc_prepare(objspace, size);
79617979
TRY_WITH_GC(mem = malloc(size));
7980+
RB_DEBUG_COUNTER_INC(heap_xmalloc);
79627981
return objspace_malloc_fixup(objspace, mem, size);
79637982
}
79647983

@@ -8012,11 +8031,11 @@ objspace_xrealloc(rb_objspace_t *objspace, void *ptr, size_t new_size, size_t ol
80128031

80138032
objspace_malloc_increase(objspace, mem, new_size, old_size, MEMOP_TYPE_REALLOC);
80148033

8034+
RB_DEBUG_COUNTER_INC(heap_xrealloc);
80158035
return mem;
80168036
}
80178037

8018-
#if CALC_EXACT_MALLOC_SIZE
8019-
#if USE_GC_MALLOC_OBJ_INFO_DETAILS
8038+
#if CALC_EXACT_MALLOC_SIZE && USE_GC_MALLOC_OBJ_INFO_DETAILS
80208039

80218040
#define MALLOC_INFO_GEN_SIZE 100
80228041
#define MALLOC_INFO_SIZE_SIZE 10
@@ -8037,8 +8056,8 @@ mmalloc_info_file_i(st_data_t key, st_data_t val, st_data_t dmy)
80378056
}
80388057

80398058
__attribute__((destructor))
8040-
static void
8041-
malloc_info_show_results(void)
8059+
void
8060+
rb_malloc_info_show_results(void)
80428061
{
80438062
int i;
80448063

@@ -8064,7 +8083,11 @@ malloc_info_show_results(void)
80648083
st_foreach(malloc_info_file_table, mmalloc_info_file_i, 0);
80658084
}
80668085
}
8067-
#endif
8086+
#else
8087+
void
8088+
rb_malloc_info_show_results(void)
8089+
{
8090+
}
80688091
#endif
80698092

80708093
static void
@@ -8129,6 +8152,7 @@ objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t old_size)
81298152
old_size = objspace_malloc_size(objspace, ptr, old_size);
81308153

81318154
free(ptr);
8155+
RB_DEBUG_COUNTER_INC(heap_xfree);
81328156

81338157
objspace_malloc_increase(objspace, ptr, 0, old_size, MEMOP_TYPE_FREE);
81348158
}

signal.c

+8
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,17 @@ interrupt_init(int argc, VALUE *argv, VALUE self)
395395
return rb_call_super(2, args);
396396
}
397397

398+
#include "debug_counter.h"
399+
void rb_malloc_info_show_results(void); /* gc.c */
400+
398401
void
399402
ruby_default_signal(int sig)
400403
{
404+
#if USE_DEBUG_COUNTER
405+
rb_debug_counter_show_results("killed by signal.");
406+
#endif
407+
rb_malloc_info_show_results();
408+
401409
signal(sig, SIG_DFL);
402410
raise(sig);
403411
}

0 commit comments

Comments
 (0)