| | 1 | /* |
| | 2 | * Copyright (c) 2002 by Michael J. Roberts. All Rights Reserved. |
| | 3 | * |
| | 4 | * Please see the accompanying license file, LICENSE.TXT, for information |
| | 5 | * on using and copying this software. |
| | 6 | */ |
| | 7 | /* |
| | 8 | Name |
| | 9 | vmprof.h - T3 VM Profiler |
| | 10 | Function |
| | 11 | Definitions for the execution profiler, which captures information on |
| | 12 | the time the program spends in each function. Profiling information is |
| | 13 | useful for performance optimization, because it identifies the areas |
| | 14 | where the program is spending all of its time. |
| | 15 | |
| | 16 | Profiling can be optionally included when the VM is compiled. Builds |
| | 17 | of the VM intended for use by end users should normally not include |
| | 18 | the profiler, because they will have no use for profiling, and |
| | 19 | including the profiler in the build enlarges the code size and adds |
| | 20 | run-time overhead. Normally, the profiler should be included only in |
| | 21 | builds that include the interactive debugger. |
| | 22 | Notes |
| | 23 | |
| | 24 | Modified |
| | 25 | 08/03/02 MJRoberts - Creation |
| | 26 | */ |
| | 27 | |
| | 28 | #ifndef VMPROF_H |
| | 29 | #define VMPROF_H |
| | 30 | |
| | 31 | #include "vmtype.h" |
| | 32 | #include "vmprofty.h" |
| | 33 | |
| | 34 | |
| | 35 | /* ------------------------------------------------------------------------ */ |
| | 36 | /* |
| | 37 | * Enable the profiler when compiling the VM by #defining VM_PROFILER on |
| | 38 | * the compiler command line (usually done through the makefile's CFLAGS |
| | 39 | * compiler options variable or equivalent). When VM_PROFILE is not |
| | 40 | * defined at compile-time, the profiling code will be omitted, making for |
| | 41 | * a smaller executable and less run-time overhead. |
| | 42 | */ |
| | 43 | #ifdef VM_PROFILER |
| | 44 | |
| | 45 | /* include profiler-only code, and do not include non-profiler-only code */ |
| | 46 | #define VM_IF_PROFILER(x) x |
| | 47 | #define VM_IF_NOT_PROFILER(x) |
| | 48 | |
| | 49 | #else /* VM_PROFILER */ |
| | 50 | |
| | 51 | /* do not include profiler code; do include non-profiler code */ |
| | 52 | #define VM_IF_PROFILER(x) |
| | 53 | #define VM_IF_NOT_PROFILER(x) x |
| | 54 | |
| | 55 | #endif /* VM_PROFILER */ |
| | 56 | |
| | 57 | /* ------------------------------------------------------------------------ */ |
| | 58 | /* |
| | 59 | * Profiler function call record. |
| | 60 | * |
| | 61 | * We keep a stack of these records alongside the regular VM stack, to |
| | 62 | * track the amount of time spent in a function. A record in this stack |
| | 63 | * corresponds to an activation frame in the regular VM stack. |
| | 64 | * |
| | 65 | * We also keep a master table of these entries indexed by obj.prop/func |
| | 66 | * identifier. These records keep the running totals for each function. |
| | 67 | */ |
| | 68 | struct vm_profiler_rec |
| | 69 | { |
| | 70 | /* the object.property of the function, for a method */ |
| | 71 | vm_obj_id_t obj; |
| | 72 | vm_prop_id_t prop; |
| | 73 | |
| | 74 | /* the entrypoint of the function, for a function */ |
| | 75 | pool_ofs_t func; |
| | 76 | |
| | 77 | /* the cumulative time DIRECTLY in this function (not in children) */ |
| | 78 | vm_prof_time sum_direct; |
| | 79 | |
| | 80 | /* |
| | 81 | * the cumulative time in this function's children (but not directly in |
| | 82 | * the function itself) |
| | 83 | */ |
| | 84 | vm_prof_time sum_chi; |
| | 85 | |
| | 86 | /* |
| | 87 | * invocation count (this is used in the running total records only, |
| | 88 | * not in the stack) |
| | 89 | */ |
| | 90 | unsigned long call_cnt; |
| | 91 | }; |
| | 92 | |
| | 93 | /* ------------------------------------------------------------------------ */ |
| | 94 | /* |
| | 95 | * OS-specific profiler functions. These must be provided by the OS |
| | 96 | * implementation. |
| | 97 | */ |
| | 98 | |
| | 99 | /* |
| | 100 | * Get the current high-precision timer, filling in *t with the current |
| | 101 | * time. This indicates the time that has elapsed since an arbitrary zero |
| | 102 | * point, defined by the OS code. We only care about deltas from one time |
| | 103 | * to another, so the zero point doesn't matter to us, as long as all times |
| | 104 | * have a consistent zero time and can thus be subtracted to find elapsed |
| | 105 | * time values. The units are arbitrary; because this routine will be |
| | 106 | * called very frequently, it should be as fast as possible, and thus |
| | 107 | * should return the time in the native units the OS uses. |
| | 108 | */ |
| | 109 | void os_prof_curtime(vm_prof_time *t); |
| | 110 | |
| | 111 | /* |
| | 112 | * Convert the elapsed time value to microseconds and return it as an |
| | 113 | * unsigned long. This should simply multiply the time value by the number |
| | 114 | * of microseconds per OS-dependent unit that os_prof_curtime() returns, |
| | 115 | * and return the value as a 32-bit unsigned long. |
| | 116 | * |
| | 117 | * We use a separate routine to convert the OS time units to microseconds |
| | 118 | * so that we don't have to perform the conversion every time we note the |
| | 119 | * current time, which we must do very frequently; instead, we defer the |
| | 120 | * conversions until we're finished with a profiler run, at which point we |
| | 121 | * have a set of summary data that is typically much smaller than the raw |
| | 122 | * set we collect throughout execution. |
| | 123 | * |
| | 124 | * Note that our return precision of 32 bits can only represent time values |
| | 125 | * up to about 4000 seconds, or about 70 minutes. This is obviously not |
| | 126 | * enough for complete generality, but it's a fairly long time by profiler |
| | 127 | * standards, since the values we're measuring are the cumulative elapsed |
| | 128 | * time spent in particular functions. Given how much easier it is to work |
| | 129 | * with 32-bit values than anything longer, and given that 70 minutes is a |
| | 130 | * fairly generous ceiling for this particular application, we accept the |
| | 131 | * loss of generality in exchange for the simplifaction. |
| | 132 | */ |
| | 133 | unsigned long os_prof_time_to_ms(const vm_prof_time *t); |
| | 134 | |
| | 135 | |
| | 136 | #endif /* VMPROF_H */ |
| | 137 | |