|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:49 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.1.1.1 1998/03/07 02:26:08 wsanchez ! 32: * Import of OSF Mach kernel (~mburg) ! 33: * ! 34: * Revision 1.1.5.2 1996/07/31 09:57:36 paire ! 35: * Added some more constraints to __asm__ functions for compilation ! 36: * under gcc2.7.1 for PROF_CNT_[L]{ADD|SUB} macros ! 37: * [96/06/14 paire] ! 38: * ! 39: * Revision 1.1.5.1 1995/01/06 19:53:52 devrcs ! 40: * mk6 CR668 - 1.3b26 merge ! 41: * new file for mk6 ! 42: * [1994/10/12 22:25:27 dwm] ! 43: * ! 44: * Revision 1.1.2.2 1994/05/16 19:19:26 meissner ! 45: * Add {,L}PROF_CNT_{SUB,LSUB,OVERFLOW} macros for gprof command. ! 46: * [1994/05/10 10:36:06 meissner] ! 47: * ! 48: * Correct 64-bit integer asms to specify result values as inputs, and use =g instead of =m. ! 49: * Cast the integer argument to PROF_CNT_ADD to unsigned long, so a short register is widened. ! 50: * Add more support for writing the gprof command. ! 51: * PROF_CNT_{EQ,NE} should not use ^=, it just uses ^. ! 52: * Round PROF_CNT_DIGITS up to 24 bytes so it is word aligned. ! 53: * _profile_cnt_to_decimal now takes the low/high values as separate arguments. ! 54: * Delete _profile_cnt_to_hex. ! 55: * [1994/04/28 21:45:07 meissner] ! 56: * ! 57: * Add more 64 bit arithmetic macros to support writing gprof. ! 58: * [1994/04/20 15:47:05 meissner] ! 59: * ! 60: * Revision 1.1.2.1 1994/04/08 17:51:56 meissner ! 61: * Correct spelling on LPROF_CNT_TO_LDOUBLE macro. ! 62: * [1994/04/08 16:18:06 meissner] ! 63: * ! 64: * Make LHISTCOUNTER be 64 bits. ! 65: * Define LPROF_CNT_INC to increment LHISTCOUNTER. ! 66: * [1994/04/08 12:40:32 meissner] ! 67: * ! 68: * Make most stats 64 bits, except for things like memory allocation. ! 69: * [1994/04/02 14:58:34 meissner] ! 70: * ! 71: * Add overflow support for {gprof,prof,old,dummy}_mcount counters. ! 72: * [1994/03/17 20:13:37 meissner] ! 73: * ! 74: * Add gprof/prof overflow support ! 75: * [1994/03/17 14:56:56 meissner] ! 76: * ! 77: * Define LHISTCOUNTER. ! 78: * [1994/02/28 12:05:16 meissner] ! 79: * ! 80: * Set HISTFRACTION to 4, so new lprofil call takes the same space. ! 81: * [1994/02/24 16:15:34 meissner] ! 82: * ! 83: * Add too_low/too_high to profile_stats. ! 84: * [1994/02/16 22:38:23 meissner] ! 85: * ! 86: * Make prof_cnt_t unsigned long. ! 87: * [1994/02/11 16:52:09 meissner] ! 88: * ! 89: * Remember function unique ptr in gfuncs structure to reset profiling. ! 90: * Add support for range checking gprof arc {from,self}pc addresses. ! 91: * Add counter for # times acontext was locked. ! 92: * Expand copyright. ! 93: * [1994/02/07 12:41:08 meissner] ! 94: * ! 95: * Keep track of the number of times the kernel overflows the HISTCOUNTER counter. ! 96: * [1994/02/03 20:13:31 meissner] ! 97: * ! 98: * Add stats for {user,kernel,idle} mode in the kernel. ! 99: * [1994/02/03 15:17:36 meissner] ! 100: * ! 101: * No change. ! 102: * [1994/02/03 00:58:59 meissner] ! 103: * ! 104: * Combine _profile_{vars,stats,md}; Allow more than one _profile_vars. ! 105: * [1994/02/01 12:04:04 meissner] ! 106: * ! 107: * Split # records to # gprof and # prof records. ! 108: * Add my_cpu/max_cpu fields. ! 109: * [1994/01/28 23:33:30 meissner] ! 110: * ! 111: * Eliminate hash_{size,mask} from gfuncs structure. ! 112: * [1994/01/26 20:23:41 meissner] ! 113: * ! 114: * Add structure size fields to _profile_{vars,stats,md}. ! 115: * Add major/minor version number to _profile_md. ! 116: * Move allocation context block pointer to main structure. ! 117: * Delete shift count for allocation contexts. ! 118: * [1994/01/25 01:46:08 meissner] ! 119: * ! 120: * Add HASHFRACTION ! 121: * [1994/01/22 01:14:02 meissner] ! 122: * ! 123: * Split profile-md.h into profile-internal.h and profile-md. ! 124: * [1994/01/20 20:57:18 meissner] ! 125: * ! 126: * Fixup copyright. ! 127: * [1994/01/18 23:08:14 meissner] ! 128: * ! 129: * Make flags byte-sized. ! 130: * Add have_bb flag. ! 131: * Add init_format flag. ! 132: * [1994/01/18 21:57:18 meissner] ! 133: * ! 134: * CR 10198 - Initial version. ! 135: * [1994/01/18 19:44:59 meissner] ! 136: * ! 137: * $EndLog$ ! 138: */ ! 139: ! 140: #ifndef _PROFILE_MD_H ! 141: #define _PROFILE_MD_H ! 142: ! 143: /* ! 144: * Define the interfaces between the assembly language profiling support ! 145: * that is common between the kernel, mach servers, and user space library. ! 146: */ ! 147: ! 148: /* ! 149: * Integer types used. ! 150: */ ! 151: ! 152: typedef long prof_ptrint_t; /* hold either pointer or signed int */ ! 153: typedef unsigned long prof_uptrint_t; /* hold either pointer or unsigned int */ ! 154: typedef long prof_lock_t; /* lock word type */ ! 155: typedef unsigned char prof_flag_t; /* type for boolean flags */ ! 156: ! 157: /* ! 158: * Double precision counter. ! 159: */ ! 160: ! 161: typedef struct prof_cnt_t { ! 162: prof_uptrint_t low; /* low 32 bits of counter */ ! 163: prof_uptrint_t high; /* high 32 bits of counter */ ! 164: } prof_cnt_t; ! 165: ! 166: #if defined(__GNUC__) && !defined(lint) ! 167: #define PROF_CNT_INC(cnt) \ ! 168: __asm__("addl $1,%0; adcl $0,%1" \ ! 169: : "=g" ((cnt).low), "=g" ((cnt).high) \ ! 170: : "0" ((cnt).low), "1" ((cnt).high)) ! 171: ! 172: #define PROF_CNT_ADD(cnt,val) \ ! 173: __asm__("addl %2,%0; adcl $0,%1" \ ! 174: : "=g,r" ((cnt).low), "=g,r" ((cnt).high) \ ! 175: : "r,g" ((unsigned long)(val)), \ ! 176: "0,0" ((cnt).low), "1,1" ((cnt).high)) ! 177: ! 178: #define PROF_CNT_LADD(cnt,val) \ ! 179: __asm__("addl %2,%0; adcl %3,%1" \ ! 180: : "=g,r" ((cnt).low), "=g,r" ((cnt).high) \ ! 181: : "r,g" ((val).low), "r,g" ((val).high), \ ! 182: "0,0" ((cnt).low), "1,1" ((cnt).high)) ! 183: ! 184: #define PROF_CNT_SUB(cnt,val) \ ! 185: __asm__("subl %2,%0; sbbl $0,%1" \ ! 186: : "=g,r" ((cnt).low), "=g,r" ((cnt).high) \ ! 187: : "r,g" ((unsigned long)(val)), \ ! 188: "0,0" ((cnt).low), "1,1" ((cnt).high)) ! 189: ! 190: #define PROF_CNT_LSUB(cnt,val) \ ! 191: __asm__("subl %2,%0; sbbl %3,%1" \ ! 192: : "=g,r" ((cnt).low), "=g,r" ((cnt).high) \ ! 193: : "r,g" ((val).low), "r,g" ((val).high), \ ! 194: "0,0" ((cnt).low), "1,1" ((cnt).high)) ! 195: ! 196: #else ! 197: #define PROF_CNT_INC(cnt) ((++((cnt).low) == 0) ? ++((cnt).high) : 0) ! 198: #define PROF_CNT_ADD(cnt,val) (((((cnt).low + (val)) < (val)) ? ((cnt).high++) : 0), ((cnt).low += (val))) ! 199: #define PROF_CNT_LADD(cnt,val) (PROF_CNT_ADD(cnt,(val).low), (cnt).high += (val).high) ! 200: #define PROF_CNT_SUB(cnt,val) (((((cnt).low - (val)) > (cnt).low) ? ((cnt).high--) : 0), ((cnt).low -= (val))) ! 201: #define PROF_CNT_LSUB(cnt,val) (PROF_CNT_SUB(cnt,(val).low), (cnt).high -= (val).high) ! 202: #endif ! 203: ! 204: #define PROF_ULONG_TO_CNT(cnt,val) (((cnt).high = 0), ((cnt).low = val)) ! 205: #define PROF_CNT_OVERFLOW(cnt,high,low) (((high) = (cnt).high), ((low) = (cnt).low)) ! 206: #define PROF_CNT_TO_ULONG(cnt) (((cnt).high == 0) ? (cnt).low : 0xffffffffu) ! 207: #define PROF_CNT_TO_LDOUBLE(cnt) ((((long double)(cnt).high) * 4294967296.0L) + (long double)(cnt).low) ! 208: #define PROF_CNT_TO_DECIMAL(buf,cnt) _profile_cnt_to_decimal(buf, (cnt).low, (cnt).high) ! 209: #define PROF_CNT_EQ_0(cnt) (((cnt).high | (cnt).low) == 0) ! 210: #define PROF_CNT_NE_0(cnt) (((cnt).high | (cnt).low) != 0) ! 211: #define PROF_CNT_EQ(cnt1,cnt2) ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) == 0) ! 212: #define PROF_CNT_NE(cnt1,cnt2) ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) != 0) ! 213: #define PROF_CNT_GT(cnt1,cnt2) (((cnt1).high > (cnt2).high) || ((cnt1).low > (cnt2).low)) ! 214: #define PROF_CNT_LT(cnt1,cnt2) (((cnt1).high < (cnt2).high) || ((cnt1).low < (cnt2).low)) ! 215: ! 216: /* max # digits + null to hold prof_cnt_t values (round up to multiple of 4) */ ! 217: #define PROF_CNT_DIGITS 24 ! 218: ! 219: /* ! 220: * Types of the profil counter. ! 221: */ ! 222: ! 223: typedef unsigned short HISTCOUNTER; /* profil */ ! 224: typedef prof_cnt_t LHISTCOUNTER; /* lprofil */ ! 225: ! 226: #define LPROF_ULONG_TO_CNT(cnt,val) PROF_ULONG_TO_CNT(cnt,val) ! 227: #define LPROF_CNT_INC(lp) PROF_CNT_INC(lp) ! 228: #define LPROF_CNT_ADD(lp,val) PROF_CNT_ADD(lp,val) ! 229: #define LPROF_CNT_LADD(lp,val) PROF_CNT_LADD(lp,val) ! 230: #define LPROF_CNT_SUB(lp,val) PROF_CNT_SUB(lp,val) ! 231: #define LPROF_CNT_LSUB(lp,val) PROF_CNT_LSUB(lp,val) ! 232: #define LPROF_CNT_OVERFLOW(lp,high,low) PROF_CNT_OVERFLOW(lp,high,low) ! 233: #define LPROF_CNT_TO_ULONG(lp) PROF_CNT_TO_ULONG(lp) ! 234: #define LPROF_CNT_TO_LDOUBLE(lp) PROF_CNT_TO_LDOUBLE(lp) ! 235: #define LPROF_CNT_TO_DECIMAL(buf,cnt) PROF_CNT_TO_DECIMAL(buf,cnt) ! 236: #define LPROF_CNT_EQ_0(cnt) PROF_CNT_EQ_0(cnt) ! 237: #define LPROF_CNT_NE_0(cnt) PROF_CNT_NE_0(cnt) ! 238: #define LPROF_CNT_EQ(cnt1,cnt2) PROF_CNT_EQ(cnt1,cnt2) ! 239: #define LPROF_CNT_NE(cnt1,cnt2) PROF_CNT_NE(cnt1,cnt2) ! 240: #define LPROF_CNT_GT(cnt1,cnt2) PROF_CNT_GT(cnt1,cnt2) ! 241: #define LPROF_CNT_LT(cnt1,cnt2) PROF_CNT_LT(cnt1,cnt2) ! 242: #define LPROF_CNT_DIGITS PROF_CNT_DIGITS ! 243: ! 244: /* ! 245: * fraction of text space to allocate for histogram counters ! 246: */ ! 247: ! 248: #define HISTFRACTION 4 ! 249: ! 250: /* ! 251: * Fraction of text space to allocate for from hash buckets. ! 252: */ ! 253: ! 254: #define HASHFRACTION HISTFRACTION ! 255: ! 256: /* ! 257: * Prof call count, external format. ! 258: */ ! 259: ! 260: struct prof_ext { ! 261: prof_uptrint_t cvalue; /* caller address */ ! 262: prof_uptrint_t cncall; /* # of calls */ ! 263: }; ! 264: ! 265: /* ! 266: * Prof call count, internal format. ! 267: */ ! 268: ! 269: struct prof_int { ! 270: struct prof_ext prof; /* external prof struct */ ! 271: prof_uptrint_t overflow; /* # times prof counter overflowed */ ! 272: }; ! 273: ! 274: /* ! 275: * Gprof arc, external format. ! 276: */ ! 277: ! 278: struct gprof_arc { ! 279: prof_uptrint_t frompc; /* caller's caller */ ! 280: prof_uptrint_t selfpc; /* caller's address */ ! 281: prof_uptrint_t count; /* # times arc traversed */ ! 282: }; ! 283: ! 284: /* ! 285: * Gprof arc, internal format. ! 286: */ ! 287: ! 288: struct hasharc { ! 289: struct hasharc *next; /* next gprof record */ ! 290: struct gprof_arc arc; /* gprof record */ ! 291: prof_uptrint_t overflow; /* # times counter overflowed */ ! 292: }; ! 293: ! 294: /* ! 295: * Linked list of all function profile blocks. ! 296: */ ! 297: ! 298: #define MAX_CACHE 3 /* # cache table entries */ ! 299: ! 300: struct gfuncs { ! 301: struct hasharc **hash_ptr; /* gprof hash table */ ! 302: struct hasharc **unique_ptr; /* function unique pointer */ ! 303: struct prof_int prof; /* -p stats for elf */ ! 304: struct hasharc *cache_ptr[MAX_CACHE]; /* cache element pointers */ ! 305: }; ! 306: ! 307: /* ! 308: * Profile information which might be written out in ELF {,g}mon.out files. ! 309: */ ! 310: ! 311: #define MAX_BUCKETS 9 /* max bucket chain to print out */ ! 312: ! 313: struct profile_stats { /* Debugging counters */ ! 314: prof_uptrint_t major_version; /* major version number */ ! 315: prof_uptrint_t minor_version; /* minor version number */ ! 316: prof_uptrint_t stats_size; /* size of profile_vars structure */ ! 317: prof_uptrint_t profil_buckets; /* # profil buckets */ ! 318: prof_uptrint_t my_cpu; /* identify current cpu/thread */ ! 319: prof_uptrint_t max_cpu; /* identify max cpu/thread */ ! 320: prof_uptrint_t prof_records; /* # of functions profiled */ ! 321: prof_uptrint_t gprof_records; /* # of gprof arcs */ ! 322: prof_uptrint_t hash_buckets; /* # gprof hash buckets */ ! 323: prof_uptrint_t bogus_count; /* # of bogus functions found in gprof */ ! 324: ! 325: prof_cnt_t cnt; /* # of calls to _{,g}prof_mcount */ ! 326: prof_cnt_t dummy; /* # of calls to _dummy_mcount */ ! 327: prof_cnt_t old_mcount; /* # of calls to old mcount */ ! 328: prof_cnt_t hash_search; /* # hash buckets searched */ ! 329: prof_cnt_t hash_num; /* # times hash table searched */ ! 330: prof_cnt_t user_ticks; /* # ticks in user space */ ! 331: prof_cnt_t kernel_ticks; /* # ticks in kernel space */ ! 332: prof_cnt_t idle_ticks; /* # ticks in idle mode */ ! 333: prof_cnt_t overflow_ticks; /* # ticks where HISTCOUNTER overflowed */ ! 334: prof_cnt_t acontext_locked; /* # times an acontext was locked */ ! 335: prof_cnt_t too_low; /* # times a histogram tick was too low */ ! 336: prof_cnt_t too_high; /* # times a histogram tick was too high */ ! 337: prof_cnt_t prof_overflow; /* # times a prof count field overflowed */ ! 338: prof_cnt_t gprof_overflow; /* # times a gprof count field overflowed */ ! 339: ! 340: /* allocation statistics */ ! 341: prof_uptrint_t num_alloc [(int)ACONTEXT_MAX]; /* # allocations */ ! 342: prof_uptrint_t bytes_alloc[(int)ACONTEXT_MAX]; /* bytes allocated */ ! 343: prof_uptrint_t num_context[(int)ACONTEXT_MAX]; /* # contexts */ ! 344: prof_uptrint_t wasted [(int)ACONTEXT_MAX]; /* wasted bytes */ ! 345: prof_uptrint_t overhead [(int)ACONTEXT_MAX]; /* overhead bytes */ ! 346: ! 347: prof_uptrint_t buckets[MAX_BUCKETS+1]; /* # hash indexes that have n buckets */ ! 348: prof_cnt_t cache_hits[MAX_CACHE]; /* # times nth cache entry matched */ ! 349: ! 350: prof_cnt_t stats_unused[64]; /* reserved for future use */ ! 351: }; ! 352: ! 353: #define PROFILE_MAJOR_VERSION 1 ! 354: #define PROFILE_MINOR_VERSION 1 ! 355: ! 356: /* ! 357: * Machine dependent fields. ! 358: */ ! 359: ! 360: struct profile_md { ! 361: int major_version; /* major version number */ ! 362: int minor_version; /* minor version number */ ! 363: size_t md_size; /* size of profile_md structure */ ! 364: struct hasharc **hash_ptr; /* gprof hash table */ ! 365: size_t hash_size; /* size of hash table */ ! 366: prof_uptrint_t num_cache; /* # of cache entries */ ! 367: void (*save_mcount_ptr)(void); /* save for _mcount_ptr */ ! 368: void (**mcount_ptr_ptr)(void); /* pointer to _mcount_ptr */ ! 369: struct hasharc *dummy_ptr; /* pointer to dummy gprof record */ ! 370: void *(*alloc_pages)(size_t); /* pointer to _profile_alloc_pages */ ! 371: char num_buffer[PROF_CNT_DIGITS]; /* convert 64 bit ints to string */ ! 372: long md_unused[58]; /* add unused fields */ ! 373: }; ! 374: ! 375: /* ! 376: * Record information about each function call. Specify ! 377: * caller, caller's caller, and a unique label for use by ! 378: * the profiling routines. ! 379: */ ! 380: extern void _prof_mcount(void); ! 381: extern void _gprof_mcount(void); ! 382: extern void _dummy_mcount(void); ! 383: extern void (*_mcount_ptr)(void); ! 384: ! 385: /* ! 386: * Function in profile-md.c to convert prof_cnt_t to string format (decimal & hex). ! 387: */ ! 388: extern char *_profile_cnt_to_decimal(char *, prof_uptrint_t, prof_uptrint_t); ! 389: ! 390: #endif /* _PROFILE_MD_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.