001 // Stats.java, created by wbeebee 002 // Copyright (C) 2001 Wes Beebee <wbeebee@mit.edu> 003 // Licensed under the terms of the GNU GPL; see COPYING for details. 004 package javax.realtime; 005 006 /** <code>Stats</code> keeps track of Runtime statistics of how many 007 * objects are created, access checks done from which MemoryArea to 008 * which MemoryArea, etc. Stats.print() allows you to print out 009 * this information and must be present right before termination of 010 * any program which you want to collect these statistics from. 011 * 012 * @author Wes Beebee <<a href="mailto:wbeebee@mit.edu">wbeebee@mit.edu</a>> 013 */ 014 015 public final class Stats { 016 017 /** Count how many access checks are done in total. */ 018 private static long accessChecks = 0; 019 020 /** Count how many new objects are created. */ 021 private static long newObjects = 0; 022 023 /** Count how many array objects are created. */ 024 private static long newArrayObjects = 0; 025 026 /** How many HeapMemory -> HeapMemory assignments? */ 027 private static long HEAP_TO_HEAP = 0; 028 029 /** How many HeapMemory -> ScopedMemory assignments? */ 030 private static long HEAP_TO_SCOPE = 0; 031 032 /** How many HeapMemory -> ImmortalMemory assignments? */ 033 private static long HEAP_TO_IMMORTAL = 0; 034 035 /** How many ScopedMemory -> HeapMemory assignments? */ 036 private static long SCOPE_TO_HEAP = 0; 037 038 /** How many ScopedMemory -> ScopedMemory assignments? */ 039 private static long SCOPE_TO_SCOPE = 0; 040 041 /** How many ScopedMemory -> ImmortalMemory assignments? */ 042 private static long SCOPE_TO_IMMORTAL = 0; 043 044 /** How many ImmortalMemory -> HeapMemory assignments? */ 045 private static long IMMORTAL_TO_HEAP = 0; 046 047 /** How many ImmortalMemory -> ScopedMemory assignments? */ 048 private static long IMMORTAL_TO_SCOPE = 0; 049 050 /** How many ImmortalMemory -> ImmortalMemory assignments? */ 051 private static long IMMORTAL_TO_IMMORTAL = 0; 052 053 /** How many objects were allocated out of HeapMemory? */ 054 private static long NEW_HEAP = 0; 055 056 /** How many objects were allocated out of ScopedMemory? */ 057 private static long NEW_SCOPE = 0; 058 059 /** How many objects were allocated out of ImmortalMemory? */ 060 private static long NEW_IMMORTAL = 0; 061 062 /** How many array objects were allocated out of HeapMemory? */ 063 private static long NEW_ARRAY_HEAP = 0; 064 065 /** How many array objects were allocated out of ScopedMemory? */ 066 private static long NEW_ARRAY_SCOPE = 0; 067 068 /** How many array objects were allocated out of ImmortalMemory? */ 069 private static long NEW_ARRAY_IMMORTAL = 0; 070 071 /** How many checks to the heap were there? */ 072 public static long heapChecks = 0; 073 074 /** How many pointers to the heap were dereferenced? */ 075 public static long heapRefs = 0; 076 077 /** How many checks on READ of a base pointer were there? */ 078 public static long READ_CHECKS = 0; 079 080 /** How many base pointers on READ were actually pointing to the heap? */ 081 public static long READ_REFS = 0; 082 083 /** How many checks on WRITE to a location were there? */ 084 public static long WRITE_CHECKS = 0; 085 086 /** How many checks on WRITE to a location previously pointing to the heap? 087 */ 088 public static long WRITE_REFS = 0; 089 090 /** How many checks on NATIVECALL returns were there? */ 091 public static long NATIVECALL_CHECKS = 0; 092 093 /** How many NATIVECALL's returned something that pointed to the heap? */ 094 public static long NATIVECALL_REFS = 0; 095 096 /** How many checks on CALL returns were there? */ 097 public static long CALL_CHECKS = 0; 098 099 /** How many CALL's returned something that pointed to the heap? */ 100 public static long CALL_REFS = 0; 101 102 /** How many checks on METHOD calls were there? */ 103 public static long METHOD_CHECKS = 0; 104 105 /** How many parameters passed into METHODs were actually pointing to 106 * the heap? 107 */ 108 public static long METHOD_REFS = 0; 109 110 /** Should we still be collecting heap reference statistics? */ 111 public static long COLLECT_HEAP_STATS = 1; 112 113 /** Has anything been added? */ 114 /** If not, it's possible that the user 115 * did not compile with the _STATS compiler option to add Runtime 116 * statistics to the compiled output. 117 */ 118 private static boolean touched = false; 119 120 /** Add an access check from one MemoryArea to another MemoryArea. 121 */ 122 public synchronized final static void addCheck(MemoryArea from, 123 MemoryArea to) { 124 touched = true; 125 if (from.heap) { 126 if (to.heap) { 127 HEAP_TO_HEAP++; 128 } else if (to.scoped) { 129 HEAP_TO_SCOPE++; 130 } else { 131 HEAP_TO_IMMORTAL++; 132 } 133 } else if (from.scoped) { 134 if (to.heap) { 135 SCOPE_TO_HEAP++; 136 } else if (to.scoped) { 137 SCOPE_TO_SCOPE++; 138 } else { 139 SCOPE_TO_IMMORTAL++; 140 } 141 } else { 142 if (to.heap) { 143 IMMORTAL_TO_HEAP++; 144 } else if (to.scoped) { 145 IMMORTAL_TO_SCOPE++; 146 } else { 147 IMMORTAL_TO_IMMORTAL++; 148 } 149 } 150 accessChecks++; 151 } 152 153 /** Add a new object to the statistics for that MemoryArea. 154 */ 155 public synchronized final static void addNewObject(MemoryArea to) { 156 touched = true; 157 if (to.heap) { 158 NEW_HEAP++; 159 } else if (to.scoped) { 160 NEW_SCOPE++; 161 } else { 162 NEW_IMMORTAL++; 163 } 164 newObjects++; 165 } 166 167 /** Add a new array object to the statistics for that MemoryArea. 168 */ 169 public synchronized final static void addNewArrayObject(MemoryArea to) { 170 touched = true; 171 if (to.heap) { 172 NEW_ARRAY_HEAP++; 173 } else if (to.scoped) { 174 NEW_ARRAY_SCOPE++; 175 } else { 176 NEW_ARRAY_IMMORTAL++; 177 } 178 newArrayObjects++; 179 } 180 181 /** Print out the statistics for this program. You must place 182 * Stats.print() at the end of your programs if you want to 183 * display the Runtime statistics of your program. You also 184 * need to compile with the _STATS option to tell the compiler 185 * to output calls to the above methods in order to collect these 186 * statistics. Note that when _STATS is on, you cannot say 187 * anything about the runtime of the program, because it takes 188 * significant time to collect information about your program. 189 */ 190 191 public synchronized final static void print() { 192 COLLECT_HEAP_STATS = 0; 193 if (touched) { 194 NoHeapRealtimeThread.print("-------------------------------------\n"); 195 NoHeapRealtimeThread.print("Dynamic statistics for Realtime Java:\n"); 196 NoHeapRealtimeThread.print("Number of access checks: "); 197 NoHeapRealtimeThread.print(accessChecks); 198 NoHeapRealtimeThread.print("\nNumber of objects created: "); 199 NoHeapRealtimeThread.print(newObjects); 200 NoHeapRealtimeThread.print("\nNumber of array objects created: "); 201 NoHeapRealtimeThread.print(newArrayObjects); 202 NoHeapRealtimeThread.print("\n-------------------------------------\n"); 203 204 NoHeapRealtimeThread.print("Checks:\n Heap -> Heap: "); 205 NoHeapRealtimeThread.print(HEAP_TO_HEAP); 206 NoHeapRealtimeThread.print("\n Heap -> Scope: "); 207 NoHeapRealtimeThread.print(HEAP_TO_SCOPE); 208 NoHeapRealtimeThread.print("\n Heap -> Immortal:"); 209 NoHeapRealtimeThread.print(HEAP_TO_IMMORTAL); 210 NoHeapRealtimeThread.print("\n Scope -> Heap: "); 211 NoHeapRealtimeThread.print(SCOPE_TO_HEAP); 212 NoHeapRealtimeThread.print("\n Scope -> Scope: "); 213 NoHeapRealtimeThread.print(SCOPE_TO_SCOPE); 214 NoHeapRealtimeThread.print("\n Scope -> Immortal:"); 215 NoHeapRealtimeThread.print(SCOPE_TO_IMMORTAL); 216 NoHeapRealtimeThread.print("\n Immortal -> Heap: "); 217 NoHeapRealtimeThread.print(IMMORTAL_TO_HEAP); 218 NoHeapRealtimeThread.print("\n Immortal -> Scope: "); 219 NoHeapRealtimeThread.print(IMMORTAL_TO_SCOPE); 220 NoHeapRealtimeThread.print("\n Immortal -> Immortal:"); 221 NoHeapRealtimeThread.print(IMMORTAL_TO_IMMORTAL); 222 NoHeapRealtimeThread.print("\n\nNew objects: \n in heap: "); 223 NoHeapRealtimeThread.print(NEW_HEAP); 224 NoHeapRealtimeThread.print("\n in scope: "); 225 NoHeapRealtimeThread.print(NEW_SCOPE); 226 NoHeapRealtimeThread.print("\n in immortal:"); 227 NoHeapRealtimeThread.print(NEW_IMMORTAL); 228 NoHeapRealtimeThread.print("\n\nNew arrays: "); 229 NoHeapRealtimeThread.print("\n in heap: "); 230 NoHeapRealtimeThread.print(NEW_ARRAY_HEAP); 231 NoHeapRealtimeThread.print("\n in scope: "); 232 NoHeapRealtimeThread.print(NEW_ARRAY_SCOPE); 233 NoHeapRealtimeThread.print("\n in immortal:"); 234 NoHeapRealtimeThread.print(NEW_ARRAY_IMMORTAL); 235 } 236 if ((heapChecks!=0)||(heapRefs!=0)) { 237 touched = true; 238 NoHeapRealtimeThread.print("\n-------------------------------------"); 239 NoHeapRealtimeThread.print("\nHeap checks: "); 240 NoHeapRealtimeThread.print(heapChecks); 241 NoHeapRealtimeThread.print(" refs: "); 242 NoHeapRealtimeThread.print(heapRefs); 243 NoHeapRealtimeThread.print("\n Write checks: "); 244 NoHeapRealtimeThread.print(WRITE_CHECKS); 245 NoHeapRealtimeThread.print(" refs: "); 246 NoHeapRealtimeThread.print(WRITE_REFS); 247 NoHeapRealtimeThread.print("\n Read checks: "); 248 NoHeapRealtimeThread.print(READ_CHECKS); 249 NoHeapRealtimeThread.print(" refs: "); 250 NoHeapRealtimeThread.print(READ_REFS); 251 NoHeapRealtimeThread.print("\n NATIVECALL checks: "); 252 NoHeapRealtimeThread.print(NATIVECALL_CHECKS); 253 NoHeapRealtimeThread.print(" refs: "); 254 NoHeapRealtimeThread.print(NATIVECALL_REFS); 255 NoHeapRealtimeThread.print("\n CALL checks: "); 256 NoHeapRealtimeThread.print(CALL_CHECKS); 257 NoHeapRealtimeThread.print(" refs: "); 258 NoHeapRealtimeThread.print(CALL_REFS); 259 NoHeapRealtimeThread.print("\n METHOD checks: "); 260 NoHeapRealtimeThread.print(METHOD_CHECKS); 261 NoHeapRealtimeThread.print(" refs: "); 262 NoHeapRealtimeThread.print(METHOD_REFS); 263 } 264 if (touched) { 265 NoHeapRealtimeThread.print("\n-------------------------------------\n"); 266 if ((HEAP_TO_HEAP+HEAP_TO_SCOPE+HEAP_TO_IMMORTAL+SCOPE_TO_HEAP+ 267 SCOPE_TO_SCOPE+SCOPE_TO_IMMORTAL+IMMORTAL_TO_HEAP+ 268 IMMORTAL_TO_SCOPE+IMMORTAL_TO_IMMORTAL)!=accessChecks) { 269 NoHeapRealtimeThread.print("Access checks don't add up!\n"); 270 } 271 if ((NEW_HEAP+NEW_SCOPE+NEW_IMMORTAL)!=newObjects) { 272 NoHeapRealtimeThread.print("New object's don't add up!\n"); 273 } 274 if ((NEW_ARRAY_HEAP+NEW_ARRAY_SCOPE+ 275 NEW_ARRAY_IMMORTAL)!=newArrayObjects) { 276 NoHeapRealtimeThread.print("New array objects don't add up!\n"); 277 } 278 if ((WRITE_CHECKS+READ_CHECKS+NATIVECALL_CHECKS+CALL_CHECKS+ 279 METHOD_CHECKS)!=heapChecks) { 280 NoHeapRealtimeThread.print("Heap checks just don't add up!\n"); 281 } 282 if ((WRITE_REFS+READ_REFS+NATIVECALL_REFS+CALL_REFS+ 283 METHOD_REFS)!=heapRefs) { 284 NoHeapRealtimeThread.print("Heap refs just don't add up!\n"); 285 } 286 } else { 287 NoHeapRealtimeThread.print("Did you forget to compile with the STATS option?\n"); 288 } 289 } 290 }