Subject: Profiling Weirdness Solved.
To: None <>
From: J.T. Conklin <>
List: current-users
Date: 08/29/1994 11:12:56
About two weeks ago, I posted some observations of unusal call graph
profile output.  To summarize, the "grandchildren" of some functions
were being counted as if they were children.  

Charles and Bill Paulsen mentioned tail call optimization as a
possible cause, but that wasn't it.  Since I didn't need new CVS
profiles at the time, I put the problem aside.

But investigating some CVS bogosities (CVS's hash function isn't
appropriate for the data it's hashing) required some more profiling,
so I looked into it a bit more.  I discovered that mcount() walks up
the stack frame to determine it's caller, but the ENTRY() macro used
by assembly language functions (like syscalls, string & memory ops,
etc.) doesn't set up a stack frame before calling mcount().  Thus a
function will always report that it's being called by its grandparent.

The enclosed change to asm.h seems to have fixed the problem for me.
The change simply sets up a stack frame, calls mcount(), and tears
down the stack frame.  It adds three instructions/cycles, but it is a
given that performance instrumentation and measurment is going to
effect the code being analyzed anyway.

I don't understand the "movl $1b,%eax" that I removed, or the .long 0
in the data segement.  %eax is likely to be clobbered by mcount(), and
the .long 0 doesn't look like it is ever referenced.


*** /usr/src/sys/arch/i386/include/asm.h	Sat Mar 12 03:04:51 1994
--- asm.h	Sat Aug 27 21:08:36 1994
*** 65,71 ****
   * XXX assumes that arguments are not passed in %eax
  # define _BEGIN_ENTRY	.data; 1:; .long 0; .text; .align 2
! # define _END_ENTRY	movl $1b,%eax; call PIC_PLT(mcount)
  # define _BEGIN_ENTRY	.text; .align 2
  # define _END_ENTRY
--- 65,71 ----
   * XXX assumes that arguments are not passed in %eax
  # define _BEGIN_ENTRY	.data; 1:; .long 0; .text; .align 2
! # define _END_ENTRY	pushl %ebp; movl %esp,%ebp; call PIC_PLT(mcount); popl %ebp
  # define _BEGIN_ENTRY	.text; .align 2
  # define _END_ENTRY