[PAHOLE]: Introduce --nr_methods
To show how many non inline functions receive as a parameter each of the structs in a project, example: [acme@newtoy ctracer_example]$ pahole --nr_methods vmlinux | sort -k2 -nr | head -5 file: 526 inode: 479 sk_buff: 386 sock: 383 dentry: 295 [acme@newtoy ctracer_example]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
7e57db18d7
commit
03530985c1
67
pahole.c
67
pahole.c
|
@ -35,6 +35,7 @@ struct structure {
|
||||||
const struct class *class;
|
const struct class *class;
|
||||||
const struct cu *cu;
|
const struct cu *cu;
|
||||||
uint32_t nr_files;
|
uint32_t nr_files;
|
||||||
|
uint32_t nr_methods;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct structure *structure__new(const struct class *class,
|
static struct structure *structure__new(const struct class *class,
|
||||||
|
@ -43,9 +44,10 @@ static struct structure *structure__new(const struct class *class,
|
||||||
struct structure *self = malloc(sizeof(*self));
|
struct structure *self = malloc(sizeof(*self));
|
||||||
|
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
self->class = class;
|
self->class = class;
|
||||||
self->cu = cu;
|
self->cu = cu;
|
||||||
self->nr_files = 1;
|
self->nr_files = 1;
|
||||||
|
self->nr_methods = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -82,6 +84,11 @@ static void nr_members_formatter(const struct structure *self)
|
||||||
class__nr_members(self->class));
|
class__nr_members(self->class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nr_methods_formatter(const struct structure *self)
|
||||||
|
{
|
||||||
|
printf("%s: %u\n", class__name(self->class), self->nr_methods);
|
||||||
|
}
|
||||||
|
|
||||||
static void size_formatter(const struct structure *self)
|
static void size_formatter(const struct structure *self)
|
||||||
{
|
{
|
||||||
printf("%s: %u %u\n", class__name(self->class),
|
printf("%s: %u %u\n", class__name(self->class),
|
||||||
|
@ -259,6 +266,53 @@ static int cu_unique_iterator(struct cu *cu, void *cookie)
|
||||||
return cu__for_each_tag(cu, unique_iterator, cookie, tag__filter);
|
return cu__for_each_tag(cu, unique_iterator, cookie, tag__filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct tag *nr_methods__filter(struct tag *tag, struct cu *cu,
|
||||||
|
void *cookie)
|
||||||
|
{
|
||||||
|
if (tag->tag != DW_TAG_subprogram)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (function__declared_inline(tag__function(tag)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nr_methods_iterator(struct tag *tag, struct cu *cu, void *cookie)
|
||||||
|
{
|
||||||
|
struct parameter *pos;
|
||||||
|
struct structure *str;
|
||||||
|
struct type *ctype;
|
||||||
|
|
||||||
|
list_for_each_entry(pos, &tag__ftype(tag)->parms, tag.node) {
|
||||||
|
struct tag *type =
|
||||||
|
cu__find_tag_by_id(cu, parameter__type(pos, cu));
|
||||||
|
|
||||||
|
if (type == NULL || type->tag != DW_TAG_pointer_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type = cu__find_tag_by_id(cu, type->type);
|
||||||
|
if (type == NULL || type->tag != DW_TAG_structure_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ctype = tag__type(type);
|
||||||
|
if (ctype->name == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
str = structures__find(ctype->name);
|
||||||
|
if (str != NULL)
|
||||||
|
++str->nr_methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cu_nr_methods_iterator(struct cu *cu, void *cookie)
|
||||||
|
{
|
||||||
|
return cu__for_each_tag(cu, nr_methods_iterator, cookie,
|
||||||
|
nr_methods__filter);
|
||||||
|
}
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{ "cacheline_size", required_argument, NULL, 'c' },
|
{ "cacheline_size", required_argument, NULL, 'c' },
|
||||||
{ "class_name_len", no_argument, NULL, 'N' },
|
{ "class_name_len", no_argument, NULL, 'N' },
|
||||||
|
@ -268,6 +322,7 @@ static struct option long_options[] = {
|
||||||
{ "nr_members", no_argument, NULL, 'n' },
|
{ "nr_members", no_argument, NULL, 'n' },
|
||||||
{ "sizes", no_argument, NULL, 's' },
|
{ "sizes", no_argument, NULL, 's' },
|
||||||
{ "nr_definitions", no_argument, NULL, 't' },
|
{ "nr_definitions", no_argument, NULL, 't' },
|
||||||
|
{ "nr_methods", no_argument, NULL, 'm' },
|
||||||
{ "exclude", required_argument, NULL, 'x' },
|
{ "exclude", required_argument, NULL, 'x' },
|
||||||
{ "cu_exclude", required_argument, NULL, 'X' },
|
{ "cu_exclude", required_argument, NULL, 'X' },
|
||||||
{ "decl_exclude", required_argument, NULL, 'D' },
|
{ "decl_exclude", required_argument, NULL, 'D' },
|
||||||
|
@ -288,6 +343,7 @@ static void usage(void)
|
||||||
" -c, --cacheline_size <size> set cacheline size (default=%d)\n"
|
" -c, --cacheline_size <size> set cacheline size (default=%d)\n"
|
||||||
" -n, --nr_members show number of members\n"
|
" -n, --nr_members show number of members\n"
|
||||||
" -N, --class_name_len show size of classes\n"
|
" -N, --class_name_len show size of classes\n"
|
||||||
|
" -m, --nr_methods show number of methods\n"
|
||||||
" -s, --sizes show size of classes\n"
|
" -s, --sizes show size of classes\n"
|
||||||
" -t, --nr_definitions show how many times struct was defined\n"
|
" -t, --nr_definitions show how many times struct was defined\n"
|
||||||
" -D, --decl_exclude <prefix> exclude classes declared in files with prefix\n"
|
" -D, --decl_exclude <prefix> exclude classes declared in files with prefix\n"
|
||||||
|
@ -305,7 +361,7 @@ int main(int argc, char *argv[])
|
||||||
char *class_name = NULL;
|
char *class_name = NULL;
|
||||||
void (*formatter)(const struct structure *s) = class_formatter;
|
void (*formatter)(const struct structure *s) = class_formatter;
|
||||||
|
|
||||||
while ((option = getopt_long(argc, argv, "B:c:D:hH:nNpstVx:X:",
|
while ((option = getopt_long(argc, argv, "B:c:D:hH:mnNpstVx:X:",
|
||||||
long_options, &option_index)) >= 0)
|
long_options, &option_index)) >= 0)
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'c': cacheline_size = atoi(optarg); break;
|
case 'c': cacheline_size = atoi(optarg); break;
|
||||||
|
@ -314,6 +370,7 @@ int main(int argc, char *argv[])
|
||||||
case 's': formatter = size_formatter; break;
|
case 's': formatter = size_formatter; break;
|
||||||
case 'n': formatter = nr_members_formatter; break;
|
case 'n': formatter = nr_members_formatter; break;
|
||||||
case 'N': formatter = class_name_len_formatter; break;
|
case 'N': formatter = class_name_len_formatter; break;
|
||||||
|
case 'm': formatter = nr_methods_formatter; break;
|
||||||
case 'p': show_packable = 1; break;
|
case 'p': show_packable = 1; break;
|
||||||
case 't': formatter = nr_definitions_formatter; break;
|
case 't': formatter = nr_definitions_formatter; break;
|
||||||
case 'D': decl_exclude_prefix = optarg;
|
case 'D': decl_exclude_prefix = optarg;
|
||||||
|
@ -355,6 +412,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
cus__for_each_cu(cus, cu_unique_iterator, NULL, cu__filter);
|
cus__for_each_cu(cus, cu_unique_iterator, NULL, cu__filter);
|
||||||
|
if (formatter == nr_methods_formatter)
|
||||||
|
cus__for_each_cu(cus, cu_nr_methods_iterator, NULL, cu__filter);
|
||||||
|
|
||||||
if (class_name != NULL) {
|
if (class_name != NULL) {
|
||||||
struct structure *s = structures__find(class_name);
|
struct structure *s = structures__find(class_name);
|
||||||
|
|
Loading…
Reference in New Issue