Commit Graph

112 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo
7150a7295e [CLASSES]: Rewrite cu__process_die
To get rid of the global variables and make it more clear.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 21:06:03 -02:00
Arnaldo Carvalho de Melo
1bd837749f [CLASSES]: function__print_inline_expansion has to use cu__find_function_by_id
Now that types and functions are in different lists.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 20:30:45 -02:00
Arnaldo Carvalho de Melo
2d4c37208f [PFUNCT]: Introduce --cc_uninlined
I.e. the functions declared as inline but not inlined by the compiler
DW_AT_inline with DW_INL_declared_not_inlined value.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 19:08:37 -02:00
Arnaldo Carvalho de Melo
179e15d553 [PFUNCT]: Differentiate inlining cases
Following what is in the DWARF2 specs:

Name                          Meaning
-----------------------------------------------------------------------------
DW_INL_not_inlined            Not declared inline nor inlined by the compiler
DW_INL_inlined                Not declared inline but inlined by the compiler
DW_INL_declared_not_inlined   Declared inline but not inlined by the compiler
DW_INL_declared_inlined       Declared inline and inlined by the compiler

Take advantae of this and use it in a new pfunct option: --cc_inlined, to
show which functions were of the DW_INL_inlined type.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 19:02:55 -02:00
Arnaldo Carvalho de Melo
c9e858a4d1 [CLASSES]: Check if current_function is null
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 16:54:25 -02:00
Arnaldo Carvalho de Melo
46158e90a6 [CLASSES]: Debugging helpers
Commented, not used when not debugging, so far.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 16:32:05 -02:00
Arnaldo Carvalho de Melo
bff3938037 [CLASSES]: Introduce struct function & struct parameter
And helper routines, so as to separate DW_TAG_subprogram from
the type tags (DW_TAG_structure_type, basic_type, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 14:33:48 -02:00
Arnaldo Carvalho de Melo
5afa478d8d [CLASSES]: Introduce struct tag
This should have been done from the start: all DW_TAG_s will be represented by
structs that has as its first member a struct tag, so that we can fully
represent the DWARF information, following csets will take continue the
restructuring.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 11:54:02 -02:00
Arnaldo Carvalho de Melo
47845f0f9b [PFUNCT]: Implement --externals
That uses the DW_AT_external attribute, that tells if the DW_TAG_subprogram
(a function) is visible externally.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-17 23:43:08 -02:00
Arnaldo Carvalho de Melo
84a05e88e1 [PREFCNT]: Handle inlined functions too
At least GCC only emits DW_TAG_subprogram for inline functions if they were
used somewhere in the CU, even if no DW_TAG_inlined_subroutine tag is emitted
due to optimizations reducing inline functions to nothing.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-17 21:54:34 -02:00
Arnaldo Carvalho de Melo
7ebee113cc [PAHOLE]: Check if we found the struct before calling class__is_struct
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-14 13:30:15 -02:00
Arnaldo Carvalho de Melo
d3b9b9bfcf [CLASSES]: Add backpointer to class in inline_expansion
And several assorted tidy-ups.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-13 00:31:48 -02:00
Arnaldo Carvalho de Melo
c49c7c8bee [CLASSES] class_member: add backpointer to the class
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:52:03 -02:00
Arnaldo Carvalho de Melo
9490088ae0 [CLASSES]: Use the struct cu backpointer
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:33:37 -02:00
Arnaldo Carvalho de Melo
570a00b29f [CLASSES] classes: Add a backpoint to the CU that owns the class
This fixes a problem with codiff usage of the ->class_to_diff member, as we
were looking at a different CU than the one intended, so we'd have to have a
pointer to the CU associated with ->class_to_diff, heck, its time to have this
backpointer :-)

Now to audit the rest of the code to look for simplifications since we now have
this backpointer and thus don't need to pass CU pointers around.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 16:59:47 -02:00
Arnaldo Carvalho de Melo
5d96b74eef [CODIFF]: Terse mode
Well, needs to be a bit more terse, as prints the types per CU, i.e. for
types defined in multiple CUs we get them repeated, but using grep +
sort -u does the trick.

[acme@newtoy pahole]$ codiff -t /tmp/ipv6.ko.before /tmp/ipv6.ko.after | grep ^struct | sort -u
struct inet_connection_sock: size, offset
struct inet_sock: size, nr_members, offset
struct proto: nr_members, type
struct raw6_sock: size, offset
struct tcp6_sock: size
struct tcp_sock: size, offset
struct udp_sock: size, offset
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 16:46:11 -02:00
Arnaldo Carvalho de Melo
b933faffcb [CLASSES]: Check the class__find_member_by_name name parameter against NULL
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 15:43:28 -02:00
Arnaldo Carvalho de Melo
d99bee8d7b [CODIFF]: Detect and print all sorts of changes in structs
[acme@newtoy examples]$ cat struct.c

static struct foo {
	char	       a:2;
	unsigned int   b;
	unsigned long  c;
	unsigned long  d;
	unsigned long  e;
} bar;

int main(int argc, char *argv[])
{
    printf("%d", bar.a);
}
[acme@newtoy examples]$

Then change "a:2" to "a:4":

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
 1 struct changed

Now, on top of that move a after b:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     4(4)     1(4) */
    b;
     from: unsigned int          /*     4(0)     4(0) */
     to:   unsigned int          /*     0(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

Move it back a to before b and change the type of e without changing its size,
i.e. from unsigned long to long:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
    e;
     from: long unsigned int     /*    16(0)     4(0) */
     to:   long int              /*    16(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

Now on top of this lets delete the c member:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   -4
   nr_members: -1
    -long unsigned int          c;                    /*     8     4 */
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
    d;
     from: long unsigned int     /*    12(0)     4(0) */
     to:   long unsigned int     /*     8(0)     4(0) */
    e;
     from: long unsigned int     /*    16(0)     4(0) */
     to:   long int              /*    12(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

WOW, many changes, what an ABI breakage, no? :-)

It started as:

[acme@newtoy examples]$ pahole old_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
        char                       a:2;                  /*     0     1 */

        /* XXX 3 bytes hole, try to pack */

        unsigned int               b;                    /*     4     4 */
        long unsigned int          c;                    /*     8     4 */
        long unsigned int          d;                    /*    12     4 */
        long unsigned int          e;                    /*    16     4 */
}; /* size: 20, sum members: 17, holes: 1, sum holes: 3 */

And ended up as:

[acme@newtoy examples]$ pahole new_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
        char                       a:4;                  /*     0     1 */

        /* XXX 3 bytes hole, try to pack */

        unsigned int               b;                    /*     4     4 */
        long unsigned int          d;                    /*     8     4 */
        long int                   e;                    /*    12     4 */
}; /* size: 16, sum members: 13, holes: 1, sum holes: 3 */

[acme@newtoy examples]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 15:07:21 -02:00
Arnaldo Carvalho de Melo
c322523dfd [CODIFF]: Add --verbose to show diff details (members removed, etc)
First step:

Show if struct members were removed or added:

[acme@newtoy net-2.6.20]$ codiff -sV /tmp/ipv6.ko.before /tmp/ipv6.ko.after
<SNIP>
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/tcp_ipv6.c:
  struct inet_sock            |   -4
   nr_members: -1
  struct inet_connection_sock |   -4
  struct tcp_sock             |   -4
  struct tcp6_sock            |   -4
 4 structs changed
<SNIP>

Oh, so struct inet_sock must be one of the members of the other structs that
haven't had changes in its number of members? Yes, this is the case :-)

Now lets see _which_ members were removed, added or had its type changed
causing a reduction in the struct size.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 12:56:52 -02:00
Arnaldo Carvalho de Melo
05b84f1c1c [CODIFF]: Allow showing only structs or function diffs
[acme@newtoy net-2.6.20]$ codiff --help
usage: codiff [options] <old_file> <new_file>
 where:
   -h, --help        usage options
   -s, --structs     show struct diffs
   -f, --functions   show function diffs
 without options all diffs are shown
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 12:41:44 -02:00
Arnaldo Carvalho de Melo
e4f5c8395c [CODIFF]: Show structure changes
[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before /tmp/ipv6.ko.after | head -12
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/af_inet6.c:
  struct inet_sock        |   -4
 1 struct changed
  inet6_init              |  +50
  inet6_create            |  -15
  inet6_getname           |  +13
  inet6_sk_rebuild_header |   +5
 4 functions changed, 68 bytes added, 15 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/anycast.c:
  ipv6_sock_ac_join |   +7
 1 function changed, 7 bytes added
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 12:29:33 -02:00
Arnaldo Carvalho de Melo
03122517ec [CODIFF]: Move printing total stats diff to separate function
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 11:09:15 -02:00
Arnaldo Carvalho de Melo
5e1bd5145e [CODIFF]: Print total stats on multi-cu files
[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before ../OUTPUT/qemu/net-2.6.20/net/ipv6/ipv6.ko | tail -7
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/inet6_connection_sock.c:
 inet6_csk_addr2sockaddr |   +2
 inet6_csk_xmit          |   +6
2 functions changed, 8 bytes added

../OUTPUT/qemu/net-2.6.20/net/ipv6/ipv6.ko:
 45 functions changed, 390 bytes added, 298 bytes removed
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 23:14:02 -02:00
Arnaldo Carvalho de Melo
0f5548a55f [CODIFF]: New tool
1. build, save the object
2. change it, build
3. do the diff!

[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before /tmp/ipv6.ko.after | head -22
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/af_inet6.c:
 inet6_init              |  +50
 inet6_create            |  -15
 inet6_getname           |  +13
 inet6_sk_rebuild_header |   +5
4 functions changed, 68 bytes added, 15 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/anycast.c:
 ipv6_sock_ac_join |   +7
1 function changed, 7 bytes added

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/ip6_output.c:
 ip6_output2             |  +14
 ip6_sk_dst_lookup       |   -2
 ip6_push_pending_frames |   +5
 ip6_xmit                |   +4
 ip6_forward             |   +1
 ip6_nd_hdr              |  +13
6 functions changed, 37 bytes added, 2 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/addrconf.c:
 ipv6_rcv_saddr_equal |  +16
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 16:31:04 -02:00
Arnaldo Carvalho de Melo
e45f877489 [MAKEFILE]: Use -Wall
And fix the warnings generated.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 14:15:50 -02:00
Arnaldo Carvalho de Melo
5b46f10f60 [CLASSES]: Fixup the dwarf_decl_line second arg signedness
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-10 21:18:06 -02:00
Arnaldo Carvalho de Melo
073176df3c [CLASSES]: Don't print the bit_offset in struct printing
Leftover from some previous tests.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-10 21:09:47 -02:00
Arnaldo Carvalho de Melo
b4b2f83057 [PFUNCT]: Tidy up --total_inline_stats column headers
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-10 21:08:42 -02:00
Arnaldo Carvalho de Melo
0d5f556dd7 [PREFCNT]: New tool
prefcnt is a new tool to do reference counting on all the TAGs, starting
from the list of DW_TAG_subroutine tags and going down thru the return type,
parameter list types, variables and inline expansions in the functions, to
help finding unused stuff, its not so effective because of bugs in gcc
DWARF emitting code for concrete inline instances, i.e. the inline expansions
are not all being emitted, see:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29792

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-10 19:19:58 -02:00
Arnaldo Carvalho de Melo
fd1b258e1b [CLASSES]: Show all structs, not just the ones with holes
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 18:32:20 -02:00
Arnaldo Carvalho de Melo
d2c9a9d726 [CLASSES]: Check if the last member had zero size before print cacheline boundary
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 18:30:10 -02:00
Arnaldo Carvalho de Melo
51c81fb099 [CLASSES]: namespace cleanups: just rename the classes__ with cu__
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 15:46:45 -02:00
Arnaldo Carvalho de Melo
633dd33a05 [PAHOLE]: Print cacheline boundaries
Cacheline size defaults to 32, sample output changing the default to 64 bytes:

pahole --cacheline=64 ../../acme/OUTPUT/qemu/net-2.6/net/ipv4/tcp.o inode

/* /pub/scm/linux/kernel/git/acme/net-2.6/include/linux/dcache.h:86 */
struct inode {
        struct hlist_node          i_hash;               /*     0     8 */
        struct list_head           i_list;               /*     8     8 */
        struct list_head           i_sb_list;            /*    16     8 */
        struct list_head           i_dentry;             /*    24     8 */
        long unsigned int          i_ino;                /*    32     4 */
        atomic_t                   i_count;              /*    36     4 */
        umode_t                    i_mode;               /*    40     2 */

        /* XXX 2 bytes hole, try to pack */

        unsigned int               i_nlink;              /*    44     4 */
        uid_t                      i_uid;                /*    48     4 */
        gid_t                      i_gid;                /*    52     4 */
        dev_t                      i_rdev;               /*    56     4 */
        loff_t                     i_size;               /*    60     8 */
        struct timespec            i_atime;              /*    68     8 */
        struct timespec            i_mtime;              /*    76     8 */
        struct timespec            i_ctime;              /*    84     8 */
        unsigned int               i_blkbits;            /*    92     4 */
        long unsigned int          i_version;            /*    96     4 */
        blkcnt_t                   i_blocks;             /*   100     4 */
        short unsigned int         i_bytes;              /*   104     2 */
        spinlock_t                 i_lock;               /*   106     0 */

        /* XXX 2 bytes hole, try to pack */

        struct mutex               i_mutex;              /*   108    24 */
        /* ---------- cacheline 2 boundary ---------- */
        struct rw_semaphore        i_alloc_sem;          /*   132    12 */
        struct inode_operations *  i_op;                 /*   144     4 */
        const struct file_operations  * i_fop;                /*   148     4 */
        struct super_block *       i_sb;                 /*   152     4 */
        struct file_lock *         i_flock;              /*   156     4 */
        struct address_space *     i_mapping;            /*   160     4 */
        struct address_space       i_data;               /*   164    72 */
        struct list_head           i_devices;            /*   236     8 */
        union                      ;                     /*   244     4 */
        int                        i_cindex;             /*   248     4 */
        __u32                      i_generation;         /*   252     4 */
        long unsigned int          i_dnotify_mask;       /*   256     4 */
        /* ---------- cacheline 4 boundary ---------- */
        struct dnotify_struct *    i_dnotify;            /*   260     4 */
        struct list_head           inotify_watches;      /*   264     8 */
        struct mutex               inotify_mutex;        /*   272    24 */
        long unsigned int          i_state;              /*   296     4 */
        long unsigned int          dirtied_when;         /*   300     4 */
        unsigned int               i_flags;              /*   304     4 */
        atomic_t                   i_writecount;         /*   308     4 */
        void *                     i_private;            /*   312     4 */
}; /* size: 316, sum members: 312, holes: 2, sum holes: 4 */

Has to be improved to show the other cacheline boundaries, that may be buried
into a included struct or union.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 15:34:54 -02:00
Arnaldo Carvalho de Melo
34b5f29576 [PAHOLE]: Add basic support for typedefs
[acme@newtoy guinea_pig-2.6]$ pahole mm/slab.o kmem_cache_t | head -6
/* include/linux/slab.h:12 */
struct kmem_cache {
        struct array_cache *array[8];    /*  0  32 */
        unsigned int        batchcount;  /* 32   4 */
        unsigned int        limit;       /* 36   4 */
        unsigned int        shared;      /* 40   4 */
[acme@newtoy guinea_pig-2.6]$ pahole --sizes fs/ext3/built-in.o | grep typedef | head -5
typedef pgd_t:struct(): 4 0
typedef pgprot_t:struct(): 4 0
typedef cpumask_t:struct(): 4 0
typedef mm_segment_t:struct(): 4 0
typedef raw_spinlock_t:struct(): 4 0
[acme@newtoy guinea_pig-2.6]$ pahole fs/ext3/built-in.o pgd_t
/* include/asm/page.h:57 */
struct  {
        long unsigned int          pgd;                  /*     0     4 */
}; /* size: 4 */

[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 02:17:19 -02:00
Arnaldo Carvalho de Melo
4f0c9ef164 [CLASSES]: Introduce struct variable
To represent DW_TAG_variable, for now all the variables in all the lexical
blocks, in addition to the top level function variables are in this list, next
step is to add support for DW_TAG_lexical_block, with support for nesting, and
to associate variables to the right place, be it the function itself (first,
implicit lexical block) or to the lexical blocks they belong too, this will be
useful for calculating stack usage.

So, with what we have now pfunct can do this:

[acme@newtoy guinea_pig-2.6]$ pfunct --variables net/ipv4/built-in.o tcp_v4_remember_stamp
/* net/ipv4/tcp_ipv4.c:1197 */
int tcp_v4_remember_stamp(struct sock * sk);

{
        /* variables in tcp_v4_remember_stamp: */
        struct inet_sock * inet;
        struct tcp_sock * tp;
        struct rtable * rt;
        struct inet_peer * peer;
        int release_it;
}
[acme@newtoy guinea_pig-2.6]$

That is already useful when you don't have the sources, huh? :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 01:31:41 -02:00
Arnaldo Carvalho de Melo
cfd870431f [CLASSES]: Upgrade all the types that are in uleb form to uint64_t
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 23:46:22 -03:00
Arnaldo Carvalho de Melo
2e195b9a4a [CLASSES]: Use tsearch to avoid duplicating strings
Now we're able to process a kernel built with make allyesconfig on a machine
with 1GB, of course there is still more things to optimize, but I'm lazy and
for now this gives the numbers I wanted to get.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 17:37:23 -03:00
Arnaldo Carvalho de Melo
dd482c5983 [PFUNCT]: Print the average size of inline expansions
Its just totsz / nrexp, i.e. total size of expansions divided by the number of
expansions found, but helps in analising the data.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 17:34:20 -03:00
Arnaldo Carvalho de Melo
8fcf984361 [CLASSES]: If a function size is 0, don't print the (useless) details
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 00:18:28 -03:00
Arnaldo Carvalho de Melo
d731cb8674 [PFUNCT]: Add some missing getopt entries
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 00:11:04 -03:00
Arnaldo Carvalho de Melo
31a5245c8c [CLASSES]: Use strdup for decl_file too
Not safe to directly point to the string parameter, probably its a inline
string, not an indirect one, one more reason to create a string table...

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 23:56:56 -03:00
Arnaldo Carvalho de Melo
41ca570938 [MAKEFILE]: Remove pfunct binary on make clean
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 23:55:29 -03:00
Arnaldo Carvalho de Melo
1ec7e4aa18 [PAHOLE]: Dwarf trivia: show number of files that include a struct
[acme@newtoy guinea_pig-2.6]$ pahole -t ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k2 -nr | head -5
list_head                          468
__wait_queue_head                  466
timespec                           466
rw_semaphore                       466
plist_head                         466
[acme@newtoy guinea_pig-2.6]$

Which leads to another, more non-trivia question, what if a struct
definition is included but there are no references to this function?

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 20:24:37 -03:00
Arnaldo Carvalho de Melo
784968cca1 [PFUNCT]: Add a header with the columns names
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 19:47:07 -03:00
Arnaldo Carvalho de Melo
05ca190f25 [PFUNCT]: Introduce --total_inline_stats
Top 10 inline functions expanded more than once by sum of its expansions,
columns are (name, nr expansions, sum of expansions, nr source files where
expansions ocurred):

[acme@newtoy guinea_pig-2.6]$ pfunct --total_inline_stats ../../acme/OUTPUT/qemu/net-2.6/vmlinux | grep -v ': 1 ' | sort -k3 -nr | head -10
get_current                        676   5732 155
xfrm_selector_match                  6   4778   2
__memcpy                           177   4326  89
kmalloc                            185   3991 119
__constant_c_memset                113   3556  69
__constant_c_and_count_memset      225   3161 156
prefetch                           333   2915 101
__ext3_journal_dirty_metadata       44   2810   6
skb_put                             34   2650  27
module_put                          80   2613  42
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 16:14:25 -03:00
Arnaldo Carvalho de Melo
2124d4f375 [PFUNCT]: Improve --cu_inline_expansions_stats
Now it shows the number that each of the inline functions were expanded in an
object file:

Top 10 inline functions expanded more than once in kernel/sched.o, by total
size of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct --cu_inline_expansions_stats kernel/sched.o | sort -k3 -nr | grep -v ': 1 ' | head -11
kernel/sched.c: 318 10217
get_current: 38 325
finish_task_switch: 2 238
normal_prio: 2 167
__cpus_and: 14 164
find_process_by_pid: 6 152
current_thread_info: 21 149
sched_find_first_bit: 2 148
update_cpu_clock: 2 140
task_rq_unlock: 14 137
variable_test_bit: 14 121
[acme@newtoy guinea_pig-2.6]$

Now we have these options:

[acme@newtoy guinea_pig-2.6]$ pfunct --help
usage: pfunct [options] <file_name> {<function_name>}
 where:
   -c, --class=<class>               functions that have <class> pointer parameters
   -g, --goto_labels                 show number of goto labels
   -i, --show_inline_expansions      show inline expansions
   -C, --cu_inline_expansions_stats  show CU inline expansions stats
   -s, --sizes                       show size of functions
   -N, --function_name_len           show size of functions
   -p, --nr_parameters               show number or parameters
   -S, --variables                   show number of variables
   -V, --verbose                     be verbose
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 15:22:12 -03:00
Arnaldo Carvalho de Melo
dcfe27a7ef [PFUNCT]: Do per CU inline statistics
Top five object files (CU, Compilation Unit) per number of inline expansions,
vmlinux being dissected is one built for QEMU, most things as modules, that
are not being taken into account as we're only looking at vmlinux:

[acme@newtoy guinea_pig-2.6]$ pfunct -C ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k2 -nr | head -5 | cut -c40-
net/ipv4/tcp_input.c: 274 20655
fs/buffer.c: 272 4597
kernel/sched.c: 214 3549
kernel/signal.c: 196 2730
fs/ext3/inode.c: 191 7961
[acme@newtoy guinea_pig-2.6]$

Top five object files (CU, Compilation Unit) per total size of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct -C ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k3 -nr | head -5 | cut -c40-
net/ipv4/tcp_input.c: 274 20655
net/xfrm/xfrm_policy.c: 173 11511
kernel/module.c: 95 10826
drivers/char/vt.c: 91 10050
net/xfrm/xfrm_user.c: 150 9682
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 14:38:43 -03:00
Johannes Berg
0330fb5d34 Corrects a few problems because dwarf libs use 64-bit types and we didn't.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 14:32:32 -03:00
Arnaldo Carvalho de Melo
a42afe1acf [CLASSES]: Add support for DW_TAG_inlined_subroutine
Output of pfunct using this information (all for a make allyesconfig build):

Top 5 functions by size of inlined functions in net/ipv4:

[acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k3 -nr | head -5
ip_route_input: 19 7086
tcp_ack: 33 6415
do_ip_vs_set_ctl: 23 4193
q931_help: 8 3822
ip_defrag: 19 3318
[acme@newtoy guinea_pig-2.6]$

And by number of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k2 -nr | head -5
dump_packet: 35 905
tcp_v4_rcv: 34 1773
tcp_recvmsg: 34 928
tcp_ack: 33 6415
tcp_rcv_established: 31 1195
[acme@newtoy guinea_pig-2.6]$

And the list of expansions on a specific function:

[acme@newtoy guinea_pig-2.6]$ pfunct -i net/ipv4/built-in.o tcp_v4_rcv
/* net/ipv4/tcp_ipv4.c:1054 */
int tcp_v4_rcv(struct sk_buff * skb);
/* size: 2189, variables: 8, goto labels: 6, inline expansions: 34 (1773 bytes) */

/* inline expansions in tcp_v4_rcv:
current_thread_info: 8
pskb_may_pull: 36
pskb_may_pull: 29
tcp_v4_checksum_init: 139
__fswab32: 2
__fswab32: 2
inet_iif: 12
__inet_lookup: 292
__fswab16: 20
inet_ehashfn: 25
inet_ehash_bucket: 18
prefetch: 4
prefetch: 4
prefetch: 4
sock_hold: 4
xfrm4_policy_check: 59
nf_reset: 66
sk_filter: 135
__skb_trim: 20
get_softnet_dma: 68
tcp_prequeue: 257
sk_add_backlog: 40
sock_put: 27
xfrm4_policy_check: 46
tcp_checksum_complete: 29
current_thread_info: 8
sock_put: 20
xfrm4_policy_check: 50
tcp_checksum_complete: 29
current_thread_info: 8
inet_iif: 9
inet_lookup_listener: 36
inet_twsk_put: 114
tcp_v4_timewait_ack: 153
*/
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 12:41:19 -03:00
Arnaldo Carvalho de Melo
7896f67c95 [CLASSES]: Initial support for DW_TAG_lexical_block
For now we just discard it so that all the variables in a function can be
accounted, but the right thing, as said in the comment added in this cset is to
have a list of lexical blocks, each with a list of its variables so that we can
find the biggest stack usage in functions.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-02 15:53:39 -03:00