Arnaldo Carvalho de Melo
9d21d3d72d
[CLASSES]: Add support for DW_TAG_inheritance
...
So that languages such as C++ can have its inheritance concepts
covered, example:
[acme@newtoy examples]$ pahole qsettings.o QSettingsPrivate
/* io/qsettings_p.h:159 */
class QSettingsPrivate {
class QObjectPrivate; /* ancestor class */ /* 0 0 */
/* XXX 56 bytes hole, try to pack */
/* --- cacheline 1 boundary (32 bytes) was 24 bytes ago --- */
class QStack<QSettingsGroup> groupStack; /* 56 4 */
class QString groupPrefix; /* 60 4 */
/* --- cacheline 2 boundary (64 bytes) --- */
int spec; /* 64 4 */
bool fallbacks; /* 68 1 */
bool pendingChanges; /* 69 1 */
/* XXX 2 bytes hole, try to pack */
enum Status status; /* 72 4 */
}; /* size: 76, cachelines: 3 */
/* sum members: 18, holes: 2, sum holes: 58 */
/* last cacheline: 12 bytes */
Nevermind about the "/* XXX 56 bytes hole, try to pack */" and sizeof(class
QObjectPrivate) being zero, its just gcc compressing the DWARF tags avoiding
including definitions that are not used in this specific object file, i.e.
there are not accesses to 'class QObjectPrivate' members.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 20:00:45 -02:00
Arnaldo Carvalho de Melo
fd1b4cadc2
[CLASSES]: Print cacheline boundary at the end of a struct too
...
Useful for structs where cacheline crossings happens on the last
member:
[acme@newtoy net-2.6]$ pahole --cacheline 32 net/ipv4/route.o hh_cache
/* /pub/scm/linux/kernel/git/acme/net-2.6/include/linux/netdevice.h:193 */
struct hh_cache {
struct hh_cache * hh_next; /* 0 4 */
atomic_t hh_refcnt; /* 4 4 */
__be16 hh_type; /* 8 2 */
u16 hh_len; /* 10 2 */
int (*hh_output)(); /* 12 4 */
rwlock_t hh_lock; /* 16 0 */
long unsigned int hh_data[24]; /* 16 96 */
/* --- cacheline 3 boundary (96 bytes) was 16 bytes ago --- */
}; /* size: 112, cachelines: 4 */
/* last cacheline: 16 bytes */
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 19:20:46 -02:00
Arnaldo Carvalho de Melo
d479b9c8e5
[CLASSES]: Disambiguate the cu__find_class_by_name
...
We want just DW_TAG_structure_type classes, but for now there are
enums, C++ inline classes, etc, have to fix this later.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 18:40:00 -02:00
Arnaldo Carvalho de Melo
41f58c52ca
[CLASSES]: Make tag_name return "class" if object file is C++
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 17:21:52 -02:00
Arnaldo Carvalho de Melo
cb883f6a8f
[PAHOLE]: First stab at implementing --packable
...
That is to find structs that have combinable holes, trying to pack the struct
by suggesting a move, for now it just prints structs that have holes that can
be combined, but these hints are not guaranteed to generate struct size
reductions, more has to be done and that involves understanding the alignment
rules that depend on the arch being 32 or 64 bits, but it at least reduces the
number of packing candidates.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 16:14:15 -02:00
Arnaldo Carvalho de Melo
82892cd9dd
[CLASSES]: First stab at implementing class__find_bit_hole
...
This new function searches the first member before the one being traversed that
has a bit hole (or byte_hole, I've just normalised it on bits to make it
generic) that can be used to combine with the class_member at hand to possibly
kill a hole, possibly because for now it doesn't guarantees that moving the
member being traversed to just after the hole after the member returned by
class__find_bit_hole will indeed reduce the struct size, but its a good first
stab, next csets should provide a member to start from so that we can try to
find other holes after the one that proved not enough to reduce the struct
size.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 16:11:47 -02:00
Arnaldo Carvalho de Melo
ff0dc936d7
[CLASSES]: Tidy up holes printing, plural form
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:24:18 -02:00
Arnaldo Carvalho de Melo
c5a4d29825
[PAHOLE]: Introduce --bit_holes
...
So that we can see only the structs that have more than the specified number of
bit holes.
Can be combined with --holes to see structs that have bit and byte holes.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:08:20 -02:00
Arnaldo Carvalho de Melo
2ac0afbf8e
[CLASSES]: Tidy up holes annotations
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:07:22 -02:00
Arnaldo Carvalho de Melo
a373c28ba9
[CLASSES]: Find bit holes
...
An example is worth a thousand words, look for "XXX ... bit hole, try to pack"
and the stats at the bottom:
[acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/inode.o task_struct
/* include2/asm/system.h:11 */
struct task_struct {
volatile long int state; /* 0 4 */
struct thread_info * thread_info; /* 4 4 */
atomic_t usage; /* 8 4 */
long unsigned int flags; /* 12 4 */
long unsigned int ptrace; /* 16 4 */
int lock_depth; /* 20 4 */
int load_weight; /* 24 4 */
int prio; /* 28 4 */
/* --- cacheline 1 boundary (32 bytes) --- */
int static_prio; /* 32 4 */
int normal_prio; /* 36 4 */
struct list_head run_list; /* 40 8 */
struct prio_array * array; /* 48 4 */
short unsigned int ioprio; /* 52 2 */
/* XXX 2 bytes hole, try to pack */
long unsigned int sleep_avg; /* 56 4 */
long long unsigned int timestamp; /* 60 8 */
/* --- cacheline 2 boundary (64 bytes) was 4 bytes ago --- */
long long unsigned int last_ran; /* 68 8 */
long long unsigned int sched_time; /* 76 8 */
enum sleep_type sleep_type; /* 84 4 */
long unsigned int policy; /* 88 4 */
cpumask_t cpus_allowed; /* 92 4 */
/* --- cacheline 3 boundary (96 bytes) --- */
unsigned int time_slice; /* 96 4 */
unsigned int first_time_slice; /* 100 4 */
struct list_head tasks; /* 104 8 */
struct list_head ptrace_children; /* 112 8 */
struct list_head ptrace_list; /* 120 8 */
/* --- cacheline 4 boundary (128 bytes) --- */
struct mm_struct * mm; /* 128 4 */
struct mm_struct * active_mm; /* 132 4 */
struct linux_binfmt * binfmt; /* 136 4 */
long int exit_state; /* 140 4 */
int exit_code; /* 144 4 */
int exit_signal; /* 148 4 */
int pdeath_signal; /* 152 4 */
long unsigned int personality; /* 156 4 */
/* --- cacheline 5 boundary (160 bytes) --- */
unsigned int did_exec:1; /* 160 4 */
/* XXX 31 bits hole, try to pack */
pid_t pid; /* 164 4 */
pid_t tgid; /* 168 4 */
struct task_struct * real_parent; /* 172 4 */
struct task_struct * parent; /* 176 4 */
struct list_head children; /* 180 8 */
struct list_head sibling; /* 188 8 */
/* --- cacheline 6 boundary (192 bytes) was 4 bytes ago --- */
struct task_struct * group_leader; /* 196 4 */
struct pid_link pids[3]; /* 200 36 */
/* --- cacheline 7 boundary (224 bytes) was 12 bytes ago --- */
struct list_head thread_group; /* 236 8 */
struct completion * vfork_done; /* 244 4 */
int * set_child_tid; /* 248 4 */
int * clear_child_tid; /* 252 4 */
/* --- cacheline 8 boundary (256 bytes) --- */
long unsigned int rt_priority; /* 256 4 */
cputime_t utime; /* 260 4 */
cputime_t stime; /* 264 4 */
long unsigned int nvcsw; /* 268 4 */
long unsigned int nivcsw; /* 272 4 */
struct timespec start_time; /* 276 8 */
long unsigned int min_flt; /* 284 4 */
/* --- cacheline 9 boundary (288 bytes) --- */
long unsigned int maj_flt; /* 288 4 */
cputime_t it_prof_expires; /* 292 4 */
cputime_t it_virt_expires; /* 296 4 */
long long unsigned int it_sched_expires; /* 300 8 */
struct list_head cpu_timers[3]; /* 308 24 */
/* --- cacheline 10 boundary (320 bytes) was 12 bytes ago --- */
uid_t uid; /* 332 4 */
uid_t euid; /* 336 4 */
uid_t suid; /* 340 4 */
uid_t fsuid; /* 344 4 */
gid_t gid; /* 348 4 */
/* --- cacheline 11 boundary (352 bytes) --- */
gid_t egid; /* 352 4 */
gid_t sgid; /* 356 4 */
gid_t fsgid; /* 360 4 */
struct group_info * group_info; /* 364 4 */
kernel_cap_t cap_effective; /* 368 4 */
kernel_cap_t cap_inheritable; /* 372 4 */
kernel_cap_t cap_permitted; /* 376 4 */
unsigned int keep_capabilities:1; /* 380 4 */
/* XXX 31 bits hole, try to pack */
/* --- cacheline 12 boundary (384 bytes) --- */
struct user_struct * user; /* 384 4 */
struct key * request_key_auth; /* 388 4 */
struct key * thread_keyring; /* 392 4 */
unsigned char jit_keyring; /* 396 1 */
unsigned char fpu_counter; /* 397 1 */
/* XXX 2 bytes hole, try to pack */
int oomkilladj; /* 400 4 */
char comm[16]; /* 404 16 */
/* --- cacheline 13 boundary (416 bytes) was 4 bytes ago --- */
int link_count; /* 420 4 */
int total_link_count; /* 424 4 */
struct sysv_sem sysvsem; /* 428 4 */
struct thread_struct thread; /* 432 656 */
/* --- cacheline 34 boundary (1088 bytes) --- */
struct fs_struct * fs; /* 1088 4 */
struct files_struct * files; /* 1092 4 */
struct nsproxy * nsproxy; /* 1096 4 */
struct signal_struct * signal; /* 1100 4 */
struct sighand_struct * sighand; /* 1104 4 */
sigset_t blocked; /* 1108 8 */
sigset_t real_blocked; /* 1116 8 */
/* --- cacheline 35 boundary (1120 bytes) was 4 bytes ago --- */
sigset_t saved_sigmask; /* 1124 8 */
struct sigpending pending; /* 1132 16 */
long unsigned int sas_ss_sp; /* 1148 4 */
/* --- cacheline 36 boundary (1152 bytes) --- */
size_t sas_ss_size; /* 1152 4 */
int (*notifier)(); /* 1156 4 */
void * notifier_data; /* 1160 4 */
sigset_t * notifier_mask; /* 1164 4 */
void * security; /* 1168 4 */
struct audit_context * audit_context; /* 1172 4 */
seccomp_t seccomp; /* 1176 0 */
u32 parent_exec_id; /* 1176 4 */
u32 self_exec_id; /* 1180 4 */
/* --- cacheline 37 boundary (1184 bytes) --- */
spinlock_t alloc_lock; /* 1184 40 */
/* --- cacheline 38 boundary (1216 bytes) was 8 bytes ago --- */
spinlock_t pi_lock; /* 1224 40 */
/* --- cacheline 39 boundary (1248 bytes) was 16 bytes ago --- */
struct plist_head pi_waiters; /* 1264 20 */
/* --- cacheline 40 boundary (1280 bytes) was 4 bytes ago --- */
struct rt_mutex_waiter * pi_blocked_on; /* 1284 4 */
struct mutex_waiter * blocked_on; /* 1288 4 */
unsigned int irq_events; /* 1292 4 */
int hardirqs_enabled; /* 1296 4 */
long unsigned int hardirq_enable_ip; /* 1300 4 */
unsigned int hardirq_enable_event; /* 1304 4 */
long unsigned int hardirq_disable_ip; /* 1308 4 */
/* --- cacheline 41 boundary (1312 bytes) --- */
unsigned int hardirq_disable_event; /* 1312 4 */
int softirqs_enabled; /* 1316 4 */
long unsigned int softirq_disable_ip; /* 1320 4 */
unsigned int softirq_disable_event; /* 1324 4 */
long unsigned int softirq_enable_ip; /* 1328 4 */
unsigned int softirq_enable_event; /* 1332 4 */
int hardirq_context; /* 1336 4 */
int softirq_context; /* 1340 4 */
/* --- cacheline 42 boundary (1344 bytes) --- */
u64 curr_chain_key; /* 1344 8 */
int lockdep_depth; /* 1352 4 */
struct held_lock held_locks[30]; /* 1356 1200 */
/* --- cacheline 79 boundary (2528 bytes) was 28 bytes ago --- */
unsigned int lockdep_recursion; /* 2556 4 */
/* --- cacheline 80 boundary (2560 bytes) --- */
void * journal_info; /* 2560 4 */
struct reclaim_state * reclaim_state; /* 2564 4 */
struct backing_dev_info * backing_dev_info; /* 2568 4 */
struct io_context * io_context; /* 2572 4 */
long unsigned int ptrace_message; /* 2576 4 */
siginfo_t * last_siginfo; /* 2580 4 */
wait_queue_t * io_wait; /* 2584 4 */
u64 rchar; /* 2588 8 */
/* --- cacheline 81 boundary (2592 bytes) was 4 bytes ago --- */
u64 wchar; /* 2596 8 */
u64 syscr; /* 2604 8 */
u64 syscw; /* 2612 8 */
struct robust_list_head * robust_list; /* 2620 4 */
/* --- cacheline 82 boundary (2624 bytes) --- */
struct list_head pi_state_list; /* 2624 8 */
struct futex_pi_state * pi_state_cache; /* 2632 4 */
atomic_t fs_excl; /* 2636 4 */
struct rcu_head rcu; /* 2640 8 */
struct pipe_inode_info * splice_pipe; /* 2648 4 */
}; /* size: 2656, cachelines: 83 */
/* sum members: 2648, holes: 2, sum holes: 4 */
/* bit holes: 2, sum bit holes: 62 bits */
/* padding: 4 */
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 12:26:50 -02:00
Arnaldo Carvalho de Melo
fb4fed3164
[CLASSES]: Fix cacheline boundary crossings
...
I not taking into account the sum of holes, so the math drifted when holes were
present.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 11:26:48 -02:00
Arnaldo Carvalho de Melo
8d19574248
[CLASSES]: Improve cacheline boundary printing
...
Now we show more cacheline boundaries by looking at when we cross cachelines,
not just when there is a exact cacheline boundary, an (long) example to
clarify:
[acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/built-in.o task_struct
/* include2/asm/system.h:11 */
struct task_struct {
volatile long int state; /* 0 4 */
struct thread_info * thread_info; /* 4 4 */
atomic_t usage; /* 8 4 */
long unsigned int flags; /* 12 4 */
long unsigned int ptrace; /* 16 4 */
int lock_depth; /* 20 4 */
int load_weight; /* 24 4 */
int prio; /* 28 4 */
/* ----- cacheline 1 boundary ----- */
int static_prio; /* 32 4 */
int normal_prio; /* 36 4 */
struct list_head run_list; /* 40 8 */
struct prio_array * array; /* 48 4 */
short unsigned int ioprio; /* 52 2 */
/* XXX 2 bytes hole, try to pack */
long unsigned int sleep_avg; /* 56 4 */
long long unsigned int timestamp; /* 60 8 */
/* ----- cacheline 2 boundary was 2 bytes ago ----- */
long long unsigned int last_ran; /* 68 8 */
long long unsigned int sched_time; /* 76 8 */
enum sleep_type sleep_type; /* 84 4 */
long unsigned int policy; /* 88 4 */
cpumask_t cpus_allowed; /* 92 4 */
unsigned int time_slice; /* 96 4 */
/* ----- cacheline 3 boundary was 2 bytes ago ----- */
unsigned int first_time_slice; /* 100 4 */
struct list_head tasks; /* 104 8 */
struct list_head ptrace_children; /* 112 8 */
struct list_head ptrace_list; /* 120 8 */
struct mm_struct * mm; /* 128 4 */
/* ----- cacheline 4 boundary was 2 bytes ago ----- */
struct mm_struct * active_mm; /* 132 4 */
struct linux_binfmt * binfmt; /* 136 4 */
long int exit_state; /* 140 4 */
int exit_code; /* 144 4 */
int exit_signal; /* 148 4 */
int pdeath_signal; /* 152 4 */
long unsigned int personality; /* 156 4 */
unsigned int did_exec:1; /* 160 4 */
/* ----- cacheline 5 boundary was 2 bytes ago ----- */
pid_t pid; /* 164 4 */
pid_t tgid; /* 168 4 */
struct task_struct * real_parent; /* 172 4 */
struct task_struct * parent; /* 176 4 */
struct list_head children; /* 180 8 */
struct list_head sibling; /* 188 8 */
/* ----- cacheline 6 boundary was 2 bytes ago ----- */
struct task_struct * group_leader; /* 196 4 */
struct pid_link pids[3]; /* 200 36 */
/* ----- cacheline 7 boundary was 10 bytes ago ----- */
struct list_head thread_group; /* 236 8 */
struct completion * vfork_done; /* 244 4 */
int * set_child_tid; /* 248 4 */
int * clear_child_tid; /* 252 4 */
long unsigned int rt_priority; /* 256 4 */
/* ----- cacheline 8 boundary was 2 bytes ago ----- */
cputime_t utime; /* 260 4 */
cputime_t stime; /* 264 4 */
long unsigned int nvcsw; /* 268 4 */
long unsigned int nivcsw; /* 272 4 */
struct timespec start_time; /* 276 8 */
long unsigned int min_flt; /* 284 4 */
long unsigned int maj_flt; /* 288 4 */
/* ----- cacheline 9 boundary was 2 bytes ago ----- */
cputime_t it_prof_expires; /* 292 4 */
cputime_t it_virt_expires; /* 296 4 */
long long unsigned int it_sched_expires; /* 300 8 */
struct list_head cpu_timers[3]; /* 308 24 */
/* ----- cacheline 10 boundary was 10 bytes ago ----- */
uid_t uid; /* 332 4 */
uid_t euid; /* 336 4 */
uid_t suid; /* 340 4 */
uid_t fsuid; /* 344 4 */
gid_t gid; /* 348 4 */
gid_t egid; /* 352 4 */
/* ----- cacheline 11 boundary was 2 bytes ago ----- */
gid_t sgid; /* 356 4 */
gid_t fsgid; /* 360 4 */
struct group_info * group_info; /* 364 4 */
kernel_cap_t cap_effective; /* 368 4 */
kernel_cap_t cap_inheritable; /* 372 4 */
kernel_cap_t cap_permitted; /* 376 4 */
unsigned int keep_capabilities:1; /* 380 4 */
struct user_struct * user; /* 384 4 */
/* ----- cacheline 12 boundary was 2 bytes ago ----- */
struct key * request_key_auth; /* 388 4 */
struct key * thread_keyring; /* 392 4 */
unsigned char jit_keyring; /* 396 1 */
unsigned char fpu_counter; /* 397 1 */
/* XXX 2 bytes hole, try to pack */
int oomkilladj; /* 400 4 */
char comm[16]; /* 404 16 */
/* ----- cacheline 13 boundary ----- */
int link_count; /* 420 4 */
int total_link_count; /* 424 4 */
struct sysv_sem sysvsem; /* 428 4 */
struct thread_struct thread; /* 432 656 */
/* ----- cacheline 33 boundary was 28 bytes ago ----- */
struct fs_struct * fs; /* 1088 4 */
/* ----- cacheline 34 boundary ----- */
struct files_struct * files; /* 1092 4 */
struct nsproxy * nsproxy; /* 1096 4 */
struct signal_struct * signal; /* 1100 4 */
struct sighand_struct * sighand; /* 1104 4 */
sigset_t blocked; /* 1108 8 */
sigset_t real_blocked; /* 1116 8 */
/* ----- cacheline 35 boundary ----- */
sigset_t saved_sigmask; /* 1124 8 */
struct sigpending pending; /* 1132 16 */
long unsigned int sas_ss_sp; /* 1148 4 */
size_t sas_ss_size; /* 1152 4 */
/* ----- cacheline 36 boundary ----- */
int (*notifier)(); /* 1156 4 */
void * notifier_data; /* 1160 4 */
sigset_t * notifier_mask; /* 1164 4 */
void * security; /* 1168 4 */
struct audit_context * audit_context; /* 1172 4 */
seccomp_t seccomp; /* 1176 0 */
u32 parent_exec_id; /* 1176 4 */
u32 self_exec_id; /* 1180 4 */
spinlock_t alloc_lock; /* 1184 40 */
/* ----- cacheline 38 boundary was 4 bytes ago ----- */
spinlock_t pi_lock; /* 1224 40 */
/* ----- cacheline 39 boundary was 12 bytes ago ----- */
struct plist_head pi_waiters; /* 1264 20 */
/* ----- cacheline 40 boundary ----- */
struct rt_mutex_waiter * pi_blocked_on; /* 1284 4 */
struct mutex_waiter * blocked_on; /* 1288 4 */
unsigned int irq_events; /* 1292 4 */
int hardirqs_enabled; /* 1296 4 */
long unsigned int hardirq_enable_ip; /* 1300 4 */
unsigned int hardirq_enable_event; /* 1304 4 */
long unsigned int hardirq_disable_ip; /* 1308 4 */
unsigned int hardirq_disable_event; /* 1312 4 */
/* ----- cacheline 41 boundary ----- */
int softirqs_enabled; /* 1316 4 */
long unsigned int softirq_disable_ip; /* 1320 4 */
unsigned int softirq_disable_event; /* 1324 4 */
long unsigned int softirq_enable_ip; /* 1328 4 */
unsigned int softirq_enable_event; /* 1332 4 */
int hardirq_context; /* 1336 4 */
int softirq_context; /* 1340 4 */
u64 curr_chain_key; /* 1344 8 */
/* ----- cacheline 42 boundary was 4 bytes ago ----- */
int lockdep_depth; /* 1352 4 */
struct held_lock held_locks[30]; /* 1356 1200 */
/* ----- cacheline 79 boundary was 24 bytes ago ----- */
unsigned int lockdep_recursion; /* 2556 4 */
void * journal_info; /* 2560 4 */
/* ----- cacheline 80 boundary ----- */
struct reclaim_state * reclaim_state; /* 2564 4 */
struct backing_dev_info * backing_dev_info; /* 2568 4 */
struct io_context * io_context; /* 2572 4 */
long unsigned int ptrace_message; /* 2576 4 */
siginfo_t * last_siginfo; /* 2580 4 */
wait_queue_t * io_wait; /* 2584 4 */
u64 rchar; /* 2588 8 */
/* ----- cacheline 81 boundary ----- */
u64 wchar; /* 2596 8 */
u64 syscr; /* 2604 8 */
u64 syscw; /* 2612 8 */
struct robust_list_head * robust_list; /* 2620 4 */
struct list_head pi_state_list; /* 2624 8 */
/* ----- cacheline 82 boundary was 4 bytes ago ----- */
struct futex_pi_state * pi_state_cache; /* 2632 4 */
atomic_t fs_excl; /* 2636 4 */
struct rcu_head rcu; /* 2640 8 */
struct pipe_inode_info * splice_pipe; /* 2648 4 */
}; /* size: 2656, sum members: 2648, holes: 2, sum holes: 4, padding: 4, cachelines: 83 */
[acme@newtoy net-2.6]$
See the "cacheline 82 boundary was 4 bytes ago" type comments? They show cases
where members cross cachelines (in this case a 32 bytes cacheline was used, the
default when one doesn't specify one with --cacheline in the pahole cmd line).
This should help in reorganizing struct layouts to avoid bringing two
cachelines when, say, a 'int' member is accessed, i.e. better aligning the
members to avoid cacheline trashing.
One seemingly interesting idea now that we have this infrastructure is to write
code to suggest reorganizing a struct to avoid these cacheline boundary
crossings, kill holes, etc, this together with static analysis on binaries or
using sparse to look member usage patterns, i.e. if io_wait is almost always
used after wchar in task_struct, we would move them to be on the same
cacheline, of course there are cases where data dependency may be an obstacle,
we'd need blacklists to help the tool avoid moving these cases.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 04:20:42 -02:00
Arnaldo Carvalho de Melo
91c91fc822
[CLASSES]: Fix class__print_struct identation
...
No code changes
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 15:09:36 -02:00
Arnaldo Carvalho de Melo
441d9e0d5c
[CLASSES]: Make class_member__print just print the member
...
Not printing the identation neither the newline, so that in the next csets
it'll be possible to show members that cross cacheline boundaries and also do
multiple levels of identation when we start supporting classes within classes
printing, to properly support C++.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 15:00:48 -02:00
Arnaldo Carvalho de Melo
2e0b628f16
[CLASSES]: Default to create classes for non structs too in class context
...
Supporting the C++ a bit more, enums, etc are basically handled inside
cu__process_class.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 14:23:54 -02:00
Arnaldo Carvalho de Melo
c6ad98fc08
[CLASSES]: First bits of C++ support
...
Now we support classes within classes, i.e. DW_TAG_structure_type entries
within DW_TAG_structure_type, a C++ feature, see the FIXME in the new code.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 11:35:21 -02:00
Arnaldo Carvalho de Melo
314d8f65bb
[MAKEFILE]: Use -fPIC in CFLAGS
...
To fix this on parisc:
acme@parisc:~/pahole$ make
gcc -g -O2 -Wall -I. -I/usr/include/elfutils -c -o pahole.o pahole.c
gcc -g -O2 -Wall -I. -I/usr/include/elfutils -c -o classes.o classes.c
gcc -shared \
-o libclasses.so.1.0.0 classes.o
/usr/bin/ld: classes.o: relocation R_PARISC_DPREL21L can not be used when making a shared object; recompile with -fPIC
classes.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [libclasses.so] Error 1
acme@parisc:~/pahole$
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 22:05:54 -02:00
Bernhard Fischer
c9be4684fe
[PAHOLE]: make some functions static
...
These are currently only used by pahole and would live in classes otherwise.
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:58:27 -02:00
Bernhard Fischer
a35aa33be8
[PAHOLE]: trim some superfluous whitespace
...
No object-code changes.
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:56:47 -02:00
Bernhard Fischer
10b1299dea
[PAHOLE]: save a few bytes on-disk
...
Merge option parsing variables into one opts variable.
text data bss dec hex filename
25006 660 44 25710 646e pahole.orig
24974 660 44 25678 644e pahole
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:55:31 -02:00
Bernhard Fischer
76bf0ada17
[CLASSES]: avoid mixing declarations and code
...
avoid mixing declarations and code to please ISO C90.
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:53:50 -02:00
Bernhard Fischer
88343b7460
[CLASSES]: build classes as a library
...
Build classes.c as a library. If STATIC=1, then link against the static lib,
else use a shared libclasses.
For the lazy, specify an rpath when linking dynamically (for now).
Set initial libclasses version to 1.0.0, don't use any fancy ld flags for now.
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:48:50 -02:00
Arnaldo Carvalho de Melo
1347cff6d9
[PAHOLE]: Make --holes require an argument
...
The minimum number of holes that a struct must have for it to be
reported, to help in combining holes.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-02 12:51:59 -02:00
Arnaldo Carvalho de Melo
b73c5c8d0f
[CLASSES]: Print info about cacheline use
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 12:22:30 -02:00
Arnaldo Carvalho de Melo
d5620cc7fd
[PAHOLE]: Implement --decl_exclude
...
pahole -D /pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/ \
../OUTPUT/qemu/net-2.6.20/net/ipv4/tcp.o
Will exclude all the classes that were defined in files in the
/pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/ directory, note that its
a prefix, not a directory, so one could as well pass
/pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/tcp_ to exclude just the
files in the include/net directory and that start with 'tcp_'.
Now I think I implemented what Bernard wanted, and that is useful for me
as well, of course :-)
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 00:08:10 -02:00
Arnaldo Carvalho de Melo
5c777371cd
[CLASSES]: Make cu__for_each_class receive a filter
...
Same semantic as in the cus__for_each_cu filter.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 00:00:24 -02:00
Arnaldo Carvalho de Melo
e5a400d01f
[CLASSES]: Make cus__for_each_cu receive an optional filter
...
To simplify the callsites and make implementing the same thing on the other
dwarves (prefcnt, pfunct, etc) easy.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:48:34 -02:00
Arnaldo Carvalho de Melo
512cb6fce5
[PAHOLE]: Implement --cu_exclude
...
Doesn't make that much sense for structs, because of the usual includes hell in
most projects, but makes sense for pfunct, so implement it now and later move
it to classes.c.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:36:55 -02:00
Arnaldo Carvalho de Melo
a9adcc2349
[PAHOLE]: Add 'class__' prefix to exclude_prefix{_len}
...
As we'll have cu__exclude_prefix{_len} too.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:23:41 -02:00
Arnaldo Carvalho de Melo
5631a94760
[PAHOLE]: Introduce class__filter()
...
That checks for constraints, the first one being a exclude prefix, and is used
by all the iterators.
Additional constraints can be things like specifying prefixes for compilation
unit names, i.e. "show me only the object files which name starts with
net/ipv4/", etc.
Initial patch provided by Bernhard Fischer, who also had the --exclude idea.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:12:21 -02:00
Arnaldo Carvalho de Melo
f428efa335
[pahole]: reimplement --class_name_len
...
I somehow deleted this functionality at some point, spotted by Bernhard
Fischer.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 19:35:29 -02:00
Bernhard Fischer
23785f65b7
[pahole]: typo in help text
...
Correct short option for nr_members in help text.
Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 19:03:59 -02:00
Arnaldo Carvalho de Melo
71cdd0f588
[CLASSES]: Follow const types to get to the real type
...
Fixes a bug where 'const char name[29]' was being printed as
'const char name;'.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-29 18:33:22 -02:00
Arnaldo Carvalho de Melo
fceec841ca
[PAHOLE]: Implement --holes to show only the structs with holes
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-27 15:54:02 -02:00
Arnaldo Carvalho de Melo
674d99e8fa
[CLASSES]: Make cu__process_function receive a lexblock pointer
...
That starts with the root lexblock (&struct function->lexblock), next step will
be to create child lexblocks when finding DW_TAG_lexical_block tags.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:59:51 -02:00
Arnaldo Carvalho de Melo
2600c462c2
[CLASSES]: Move the lexblock initialization to lexblock__init
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:54:39 -02:00
Arnaldo Carvalho de Melo
b31090f722
[CLASSES]: Move more stuff to the lexblock namespace
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:51:42 -02:00
Arnaldo Carvalho de Melo
6a3cc448d1
[CLASSES]: Introduce struct lexblock
...
To represent DW_TAG_lexical_block, for now just group the lists of
labels, inline expansions and variables, struct function now has
the root of the tree as ->lexblock.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:38:47 -02:00
Arnaldo Carvalho de Melo
460c5d91f4
[CLASSES]: Implement DW_TAG_label full support
...
And use it in function__print:
[acme@newtoy net-2.6.20]$ pfunct -Ti net/ipv4/tcp_ipv4.o tcp_v4_err
/* net/ipv4/tcp_ipv4.c:352 */
void tcp_v4_err(struct sk_buff * skb, u32 info);
{
struct iphdr * iph; // 353
struct tcphdr * th; // 354
struct tcp_sock * tp; // 355
struct inet_sock * inet; // 356
int type; // 357
int code; // 358
struct sock * sk; // 359
__u32 seq; // 360
int err; // 361
inet_lookup(); // 368
inet_iif(); // 368
inet_twsk_put(); // 375
__fswab32(); // 390
do_pmtu_discovery(); // 410
struct request_sock * req; // 424
struct request_sock * * prev; // 424
inet_csk_reqsk_queue_drop(); // 450
tcp_done(); // 462
out: // 493
sock_put(); // 495
}
/* size: 1538, variables: 11, goto labels: 1, inline expansions: 10 (1066 bytes) */
Now to support DW_TAG_lexical_block, then to study libelf to fill in the
missing parts with assembly (or C snippets automagically rebuilt from the
assembly ;) ).
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:17:42 -02:00
Arnaldo Carvalho de Melo
139cfd3318
[CLASSES]: Enhance function__print
...
Introducing function__print_body, that orders the tags in a function by the
souce code line where it was declared or inlined.
This finally takes advantage of the struct tag "superclass", more to come in
the form of lexical blocks and goto labels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 15:43:39 -02:00
Arnaldo Carvalho de Melo
78313d93e7
[CLASSES]: DW_TAG_inlined_subroutines doesn't have DW_AT_decl_{file,line}
...
It has DW_AT_call_{file,line}, fixed.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 00:36:11 -02:00
Arnaldo Carvalho de Melo
bcc85784fe
[CLASSES]: Remove stray ; in function__print
...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 00:26:04 -02:00
Arnaldo Carvalho de Melo
a1c8aefe4e
[CLASSES]: Support DW_TAG_unspecified_parameters
...
aka "..."
[acme@newtoy net-2.6.20]$ pfunct kernel/panic.o panic
/* kernel/panic.c:61 */
void panic(const char * fmt, ...);
/* size: 241, variables: 3, inline expansions: 1 (3 bytes) */
[acme@newtoy net-2.6.20]$
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 21:15:36 -02:00
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