2 * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
34 * Revision 1.1.1.1 1998/09/22 21:05:49 wsanchez
35 * Import of Mac OS X kernel (~semeria)
37 * Revision 1.1.1.1 1998/03/07 02:26:08 wsanchez
38 * Import of OSF Mach kernel (~mburg)
40 * Revision 1.1.5.2 1996/07/31 09:57:36 paire
41 * Added some more constraints to __asm__ functions for compilation
42 * under gcc2.7.1 for PROF_CNT_[L]{ADD|SUB} macros
45 * Revision 1.1.5.1 1995/01/06 19:53:52 devrcs
46 * mk6 CR668 - 1.3b26 merge
48 * [1994/10/12 22:25:27 dwm]
50 * Revision 1.1.2.2 1994/05/16 19:19:26 meissner
51 * Add {,L}PROF_CNT_{SUB,LSUB,OVERFLOW} macros for gprof command.
52 * [1994/05/10 10:36:06 meissner]
54 * Correct 64-bit integer asms to specify result values as inputs, and use =g instead of =m.
55 * Cast the integer argument to PROF_CNT_ADD to unsigned long, so a short register is widened.
56 * Add more support for writing the gprof command.
57 * PROF_CNT_{EQ,NE} should not use ^=, it just uses ^.
58 * Round PROF_CNT_DIGITS up to 24 bytes so it is word aligned.
59 * _profile_cnt_to_decimal now takes the low/high values as separate arguments.
60 * Delete _profile_cnt_to_hex.
61 * [1994/04/28 21:45:07 meissner]
63 * Add more 64 bit arithmetic macros to support writing gprof.
64 * [1994/04/20 15:47:05 meissner]
66 * Revision 1.1.2.1 1994/04/08 17:51:56 meissner
67 * Correct spelling on LPROF_CNT_TO_LDOUBLE macro.
68 * [1994/04/08 16:18:06 meissner]
70 * Make LHISTCOUNTER be 64 bits.
71 * Define LPROF_CNT_INC to increment LHISTCOUNTER.
72 * [1994/04/08 12:40:32 meissner]
74 * Make most stats 64 bits, except for things like memory allocation.
75 * [1994/04/02 14:58:34 meissner]
77 * Add overflow support for {gprof,prof,old,dummy}_mcount counters.
78 * [1994/03/17 20:13:37 meissner]
80 * Add gprof/prof overflow support
81 * [1994/03/17 14:56:56 meissner]
83 * Define LHISTCOUNTER.
84 * [1994/02/28 12:05:16 meissner]
86 * Set HISTFRACTION to 4, so new lprofil call takes the same space.
87 * [1994/02/24 16:15:34 meissner]
89 * Add too_low/too_high to profile_stats.
90 * [1994/02/16 22:38:23 meissner]
92 * Make prof_cnt_t unsigned long.
93 * [1994/02/11 16:52:09 meissner]
95 * Remember function unique ptr in gfuncs structure to reset profiling.
96 * Add support for range checking gprof arc {from,self}pc addresses.
97 * Add counter for # times acontext was locked.
99 * [1994/02/07 12:41:08 meissner]
101 * Keep track of the number of times the kernel overflows the HISTCOUNTER counter.
102 * [1994/02/03 20:13:31 meissner]
104 * Add stats for {user,kernel,idle} mode in the kernel.
105 * [1994/02/03 15:17:36 meissner]
108 * [1994/02/03 00:58:59 meissner]
110 * Combine _profile_{vars,stats,md}; Allow more than one _profile_vars.
111 * [1994/02/01 12:04:04 meissner]
113 * Split # records to # gprof and # prof records.
114 * Add my_cpu/max_cpu fields.
115 * [1994/01/28 23:33:30 meissner]
117 * Eliminate hash_{size,mask} from gfuncs structure.
118 * [1994/01/26 20:23:41 meissner]
120 * Add structure size fields to _profile_{vars,stats,md}.
121 * Add major/minor version number to _profile_md.
122 * Move allocation context block pointer to main structure.
123 * Delete shift count for allocation contexts.
124 * [1994/01/25 01:46:08 meissner]
127 * [1994/01/22 01:14:02 meissner]
129 * Split profile-md.h into profile-internal.h and profile-md.
130 * [1994/01/20 20:57:18 meissner]
133 * [1994/01/18 23:08:14 meissner]
135 * Make flags byte-sized.
137 * Add init_format flag.
138 * [1994/01/18 21:57:18 meissner]
140 * CR 10198 - Initial version.
141 * [1994/01/18 19:44:59 meissner]
146 #ifndef _PROFILE_MD_H
147 #define _PROFILE_MD_H
152 * Define the interfaces between the assembly language profiling support
153 * that is common between the kernel, mach servers, and user space library.
157 * Integer types used.
161 * These hold either a pointer or a signed/unsigned int.
162 * They are 32 bit on i386 and 64 bit on x86_64.
164 typedef long prof_ptrint_t
;
165 typedef unsigned long prof_uptrint_t
;
167 typedef long prof_lock_t
; /* lock word type */
168 typedef unsigned char prof_flag_t
; /* type for boolean flags */
171 * Double precision counter.
174 /* These are 64 bit on both i386 and x86_64 */
175 typedef unsigned long prof_cnt_t
;
178 #define PROF_CNT_INC(cnt) (cnt++)
179 #define PROF_CNT_ADD(cnt,val) (cnt+=val)
180 #define PROF_CNT_LADD(cnt,val) (cnt+=val)
181 #define PROF_CNT_SUB(cnt,val) (cnt-=val)
182 #define PROF_CNT_LSUB(cnt,val) (cnt-=val)
184 #define PROF_ULONG_TO_CNT(cnt,val) (((cnt).high = 0), ((cnt).low = val))
185 #define PROF_CNT_OVERFLOW(cnt,high,low) (((high) = (cnt).high), ((low) = (cnt).low))
186 #define PROF_CNT_TO_ULONG(cnt) (((cnt).high == 0) ? (cnt).low : 0xffffffffu)
187 #define PROF_CNT_TO_LDOUBLE(cnt) ((((long double)(cnt).high) * 4294967296.0L) + (long double)(cnt).low)
188 #define PROF_CNT_TO_DECIMAL(buf,cnt) _profile_cnt_to_decimal(buf, (cnt).low, (cnt).high)
189 #define PROF_CNT_EQ_0(cnt) (((cnt).high | (cnt).low) == 0)
190 #define PROF_CNT_NE_0(cnt) (((cnt).high | (cnt).low) != 0)
191 #define PROF_CNT_EQ(cnt1,cnt2) ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) == 0)
192 #define PROF_CNT_NE(cnt1,cnt2) ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) != 0)
193 #define PROF_CNT_GT(cnt1,cnt2) (((cnt1).high > (cnt2).high) || ((cnt1).low > (cnt2).low))
194 #define PROF_CNT_LT(cnt1,cnt2) (((cnt1).high < (cnt2).high) || ((cnt1).low < (cnt2).low))
196 /* max # digits + null to hold prof_cnt_t values (round up to multiple of 4) */
197 #define PROF_CNT_DIGITS 24
200 * Types of the profil counter.
203 typedef unsigned short HISTCOUNTER
; /* profil */
204 typedef prof_cnt_t LHISTCOUNTER
; /* lprofil */
206 #define LPROF_ULONG_TO_CNT(cnt,val) PROF_ULONG_TO_CNT(cnt,val)
207 #define LPROF_CNT_INC(lp) PROF_CNT_INC(lp)
208 #define LPROF_CNT_ADD(lp,val) PROF_CNT_ADD(lp,val)
209 #define LPROF_CNT_LADD(lp,val) PROF_CNT_LADD(lp,val)
210 #define LPROF_CNT_SUB(lp,val) PROF_CNT_SUB(lp,val)
211 #define LPROF_CNT_LSUB(lp,val) PROF_CNT_LSUB(lp,val)
212 #define LPROF_CNT_OVERFLOW(lp,high,low) PROF_CNT_OVERFLOW(lp,high,low)
213 #define LPROF_CNT_TO_ULONG(lp) PROF_CNT_TO_ULONG(lp)
214 #define LPROF_CNT_TO_LDOUBLE(lp) PROF_CNT_TO_LDOUBLE(lp)
215 #define LPROF_CNT_TO_DECIMAL(buf,cnt) PROF_CNT_TO_DECIMAL(buf,cnt)
216 #define LPROF_CNT_EQ_0(cnt) PROF_CNT_EQ_0(cnt)
217 #define LPROF_CNT_NE_0(cnt) PROF_CNT_NE_0(cnt)
218 #define LPROF_CNT_EQ(cnt1,cnt2) PROF_CNT_EQ(cnt1,cnt2)
219 #define LPROF_CNT_NE(cnt1,cnt2) PROF_CNT_NE(cnt1,cnt2)
220 #define LPROF_CNT_GT(cnt1,cnt2) PROF_CNT_GT(cnt1,cnt2)
221 #define LPROF_CNT_LT(cnt1,cnt2) PROF_CNT_LT(cnt1,cnt2)
222 #define LPROF_CNT_DIGITS PROF_CNT_DIGITS
225 * fraction of text space to allocate for histogram counters
228 #define HISTFRACTION 4
231 * Fraction of text space to allocate for from hash buckets.
234 #define HASHFRACTION HISTFRACTION
237 * Prof call count, external format.
241 prof_uptrint_t cvalue
; /* caller address */
242 prof_uptrint_t cncall
; /* # of calls */
246 * Prof call count, internal format.
250 struct prof_ext prof
; /* external prof struct */
251 prof_uptrint_t overflow
; /* # times prof counter overflowed */
255 * Gprof arc, external format.
259 prof_uptrint_t frompc
; /* caller's caller */
260 prof_uptrint_t selfpc
; /* caller's address */
261 prof_uptrint_t count
; /* # times arc traversed */
265 * Gprof arc, internal format.
269 struct hasharc
*next
; /* next gprof record */
270 struct gprof_arc arc
; /* gprof record */
271 prof_uptrint_t overflow
; /* # times counter overflowed */
275 * Linked list of all function profile blocks.
278 #define MAX_CACHE 3 /* # cache table entries */
281 struct hasharc
**hash_ptr
; /* gprof hash table */
282 struct hasharc
**unique_ptr
; /* function unique pointer */
283 struct prof_int prof
; /* -p stats for elf */
284 struct hasharc
*cache_ptr
[MAX_CACHE
]; /* cache element pointers */
288 * Profile information which might be written out in ELF {,g}mon.out files.
291 #define MAX_BUCKETS 9 /* max bucket chain to print out */
293 struct profile_stats
{ /* Debugging counters */
294 prof_uptrint_t major_version
; /* major version number */
295 prof_uptrint_t minor_version
; /* minor version number */
296 prof_uptrint_t stats_size
; /* size of profile_vars structure */
297 prof_uptrint_t profil_buckets
; /* # profil buckets */
298 prof_uptrint_t my_cpu
; /* identify current cpu/thread */
299 prof_uptrint_t max_cpu
; /* identify max cpu/thread */
300 prof_uptrint_t prof_records
; /* # of functions profiled */
301 prof_uptrint_t gprof_records
; /* # of gprof arcs */
302 prof_uptrint_t hash_buckets
; /* # gprof hash buckets */
303 prof_uptrint_t bogus_count
; /* # of bogus functions found in gprof */
305 prof_cnt_t cnt
; /* # of calls to _{,g}prof_mcount */
306 prof_cnt_t dummy
; /* # of calls to _dummy_mcount */
307 prof_cnt_t old_mcount
; /* # of calls to old mcount */
308 prof_cnt_t hash_search
; /* # hash buckets searched */
309 prof_cnt_t hash_num
; /* # times hash table searched */
310 prof_cnt_t user_ticks
; /* # ticks in user space */
311 prof_cnt_t kernel_ticks
; /* # ticks in kernel space */
312 prof_cnt_t idle_ticks
; /* # ticks in idle mode */
313 prof_cnt_t overflow_ticks
; /* # ticks where HISTCOUNTER overflowed */
314 prof_cnt_t acontext_locked
; /* # times an acontext was locked */
315 prof_cnt_t too_low
; /* # times a histogram tick was too low */
316 prof_cnt_t too_high
; /* # times a histogram tick was too high */
317 prof_cnt_t prof_overflow
; /* # times a prof count field overflowed */
318 prof_cnt_t gprof_overflow
; /* # times a gprof count field overflowed */
320 /* allocation statistics */
321 prof_uptrint_t num_alloc
[(int)ACONTEXT_MAX
]; /* # allocations */
322 prof_uptrint_t bytes_alloc
[(int)ACONTEXT_MAX
]; /* bytes allocated */
323 prof_uptrint_t num_context
[(int)ACONTEXT_MAX
]; /* # contexts */
324 prof_uptrint_t wasted
[(int)ACONTEXT_MAX
]; /* wasted bytes */
325 prof_uptrint_t overhead
[(int)ACONTEXT_MAX
]; /* overhead bytes */
327 prof_uptrint_t buckets
[MAX_BUCKETS
+1]; /* # hash indexes that have n buckets */
328 prof_cnt_t cache_hits
[MAX_CACHE
]; /* # times nth cache entry matched */
330 prof_cnt_t stats_unused
[64]; /* reserved for future use */
333 #define PROFILE_MAJOR_VERSION 1
334 #define PROFILE_MINOR_VERSION 1
337 * Machine dependent fields.
341 int major_version
; /* major version number */
342 int minor_version
; /* minor version number */
343 size_t md_size
; /* size of profile_md structure */
344 struct hasharc
**hash_ptr
; /* gprof hash table */
345 size_t hash_size
; /* size of hash table */
346 prof_uptrint_t num_cache
; /* # of cache entries */
347 void (*save_mcount_ptr
)(void); /* save for _mcount_ptr */
348 void (**mcount_ptr_ptr
)(void); /* pointer to _mcount_ptr */
349 struct hasharc
*dummy_ptr
; /* pointer to dummy gprof record */
350 void *(*alloc_pages
)(size_t); /* pointer to _profile_alloc_pages */
351 char num_buffer
[PROF_CNT_DIGITS
]; /* convert 64 bit ints to string */
352 long md_unused
[58]; /* add unused fields */
356 * Record information about each function call. Specify
357 * caller, caller's caller, and a unique label for use by
358 * the profiling routines.
360 extern void _prof_mcount(void);
361 extern void _gprof_mcount(void);
362 extern void _dummy_mcount(void);
363 extern void (*_mcount_ptr
)(void);
366 * Function in profile-md.c to convert prof_cnt_t to string format (decimal & hex).
368 extern char *_profile_cnt_to_decimal(char *, prof_uptrint_t
, prof_uptrint_t
);
370 #endif /* _PROFILE_MD_H */