1 salcianu 1.1.2.1 // Stats.java, created Tue Feb 29 11:55:35 2000 by salcianu 2 cananian 1.1.2.16 // Copyright (C) 2000 Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu> 3 salcianu 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 salcianu 1.1.2.1 package harpoon.Analysis.PointerAnalysis; 5 salcianu 1.1.2.1 6 salcianu 1.5 import harpoon.ClassFile.HMethod; 7 salcianu 1.5 import harpoon.ClassFile.HCode; 8 salcianu 1.5 import harpoon.ClassFile.HClass; 9 salcianu 1.5 import harpoon.ClassFile.HCodeFactory; 10 salcianu 1.5 11 salcianu 1.5 import harpoon.Util.LightBasicBlocks.LightBasicBlock; 12 salcianu 1.5 13 salcianu 1.5 import harpoon.Analysis.MetaMethods.MetaMethod; 14 salcianu 1.5 import harpoon.Util.Graphs.SCComponent; 15 salcianu 1.7 import harpoon.Util.Graphs.TopSortedCompDiGraph; 16 salcianu 1.5 17 salcianu 1.5 import harpoon.Util.Util; 18 salcianu 1.1.2.1 19 salcianu 1.1.2.1 import java.util.List; 20 salcianu 1.1.2.1 import java.util.HashMap; 21 salcianu 1.1.2.1 import java.util.Iterator; 22 salcianu 1.1.2.3 import java.util.Arrays; 23 salcianu 1.1.2.3 import java.util.Set; 24 salcianu 1.1.2.3 import java.util.HashSet; 25 salcianu 1.1.2.3 import java.util.Comparator; 26 salcianu 1.1.2.1 27 salcianu 1.1.2.1 28 salcianu 1.1.2.1 /** 29 salcianu 1.1.2.2 * <code>Stats</code> centralizes some pointer-analysis related statistics. 30 salcianu 1.1.2.1 * 31 salcianu 1.7 * @author Alexandru SALCIANU <salcianu@mit.edu> 32 salcianu 1.10 * @version $Id: Stats.java,v 1.10 2004/03/06 21:52:24 salcianu Exp $ 33 salcianu 1.1.2.1 */ 34 salcianu 1.1.2.14 abstract class Stats implements java.io.Serializable { 35 salcianu 1.1.2.1 36 salcianu 1.1.2.1 private static HashMap info = new HashMap(); 37 salcianu 1.1.2.1 38 salcianu 1.1.2.4 static class MetaMethodInfo{ 39 salcianu 1.1.2.1 int nb_instrs = 0; 40 salcianu 1.1.2.1 int nb_bbs = 0; 41 salcianu 1.1.2.1 int nb_sccs = 0; 42 salcianu 1.1.2.1 int nb_passes = 0; 43 salcianu 1.1.2.3 int nb_params = 0; 44 cananian 1.1.2.12 } 45 salcianu 1.1.2.1 46 salcianu 1.1.2.4 private static MetaMethodInfo getMetaMethodInfo(MetaMethod mm){ 47 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 48 salcianu 1.1.2.4 if(mmi == null){ 49 salcianu 1.1.2.4 mmi = new MetaMethodInfo(); 50 salcianu 1.1.2.4 info.put(mm,mmi); 51 salcianu 1.1.2.3 } 52 salcianu 1.1.2.4 return mmi; 53 salcianu 1.1.2.1 } 54 salcianu 1.1.2.1 55 salcianu 1.9 public static void record_mmethod_pass 56 salcianu 1.8 (MetaMethod mm, TopSortedCompDiGraph<LightBasicBlock> ts_sccs) { 57 salcianu 1.7 58 salcianu 1.1.2.4 MetaMethodInfo mmi = getMetaMethodInfo(mm); 59 salcianu 1.9 mmi.nb_passes++; 60 salcianu 1.9 if(mmi.nb_passes > 1) return; 61 salcianu 1.1.2.4 62 salcianu 1.1.2.4 // grab statistics about the number of SCC and BB 63 salcianu 1.1.2.4 int nb_sccs = 0; 64 salcianu 1.1.2.4 int nb_bbs = 0; 65 salcianu 1.1.2.4 int nb_instrs = 0; 66 salcianu 1.7 67 salcianu 1.8 for(SCComponent scc : ts_sccs.decrOrder()) { 68 salcianu 1.1.2.4 nb_sccs++; 69 salcianu 1.10 nb_bbs += scc.size(); 70 salcianu 1.10 for(Object bbkO : scc.nodes()){ 71 cananian 1.6 LightBasicBlock bbk = (LightBasicBlock) bbkO; 72 salcianu 1.1.2.7 nb_instrs += bbk.getElements().length; 73 salcianu 1.1.2.4 } 74 salcianu 1.1.2.4 } 75 salcianu 1.1.2.4 Stats.record_mmethod_instrs(mm, nb_instrs); 76 salcianu 1.1.2.4 Stats.record_mmethod_bbs(mm, nb_bbs); 77 salcianu 1.1.2.4 Stats.record_mmethod_sccs(mm, nb_sccs); 78 salcianu 1.1.2.4 } 79 salcianu 1.1.2.4 80 salcianu 1.1.2.4 public static void record_mmethod_instrs(MetaMethod mm, int nb_instrs){ 81 salcianu 1.1.2.4 MetaMethodInfo mmi = getMetaMethodInfo(mm); 82 salcianu 1.1.2.4 mmi.nb_instrs = nb_instrs; 83 salcianu 1.1.2.1 } 84 salcianu 1.1.2.1 85 salcianu 1.1.2.4 public static void record_mmethod_bbs(MetaMethod mm, int nb_bbs){ 86 salcianu 1.1.2.4 MetaMethodInfo mmi = getMetaMethodInfo(mm); 87 salcianu 1.1.2.4 mmi.nb_bbs = nb_bbs; 88 salcianu 1.1.2.1 } 89 salcianu 1.1.2.1 90 salcianu 1.1.2.4 public static void record_mmethod_sccs(MetaMethod mm, int nb_sccs){ 91 salcianu 1.1.2.4 MetaMethodInfo mmi = getMetaMethodInfo(mm); 92 salcianu 1.1.2.4 mmi.nb_sccs = nb_sccs; 93 salcianu 1.1.2.1 } 94 salcianu 1.1.2.1 95 salcianu 1.1.2.4 public static void record_mmethod_params(MetaMethod mm, int nb_params){ 96 salcianu 1.1.2.4 MetaMethodInfo mmi = getMetaMethodInfo(mm); 97 salcianu 1.1.2.4 mmi.nb_params = nb_params; 98 salcianu 1.1.2.3 } 99 salcianu 1.1.2.3 100 salcianu 1.1.2.3 private static int maxim_nb_instrs = -1; 101 salcianu 1.1.2.3 private static int maxim_nb_passes = -1; 102 salcianu 1.1.2.3 private static int maxim_nb_params = -1; // the maximum nb of parameters 103 salcianu 1.1.2.1 104 salcianu 1.1.2.1 public static void print_stats(){ 105 salcianu 1.1.2.1 System.out.println("STATISTICS:"); 106 salcianu 1.1.2.1 107 salcianu 1.1.2.4 int nb_mmethods = info.size(); 108 salcianu 1.1.2.4 System.out.println(nb_mmethods + " meta-method(s)"); 109 salcianu 1.1.2.1 110 salcianu 1.1.2.1 int total_instrs = 0; 111 salcianu 1.1.2.1 int total_bbs = 0; 112 salcianu 1.1.2.1 int total_sccs = 0; 113 salcianu 1.1.2.1 int total_passes = 0; 114 salcianu 1.1.2.3 int total_params = 0; // the total number of parameters 115 salcianu 1.1.2.8 // the set of all the analyzed methods (a method can be split 116 salcianu 1.1.2.8 // into many metamethods) 117 salcianu 1.1.2.8 Set methods = new HashSet(); 118 salcianu 1.1.2.1 119 salcianu 1.1.2.3 maxim_nb_instrs = -1; 120 salcianu 1.1.2.3 maxim_nb_passes = -1; 121 salcianu 1.1.2.3 maxim_nb_params = -1; 122 salcianu 1.1.2.1 123 cananian 1.6 for(Object mmO : info.keySet()){ 124 cananian 1.6 MetaMethod mm = (MetaMethod) mmO; 125 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 126 salcianu 1.1.2.4 127 salcianu 1.1.2.8 methods.add(mm.getHMethod()); 128 salcianu 1.1.2.8 129 salcianu 1.1.2.4 mmi.nb_params = compute_nb_params(mm.getHMethod()); 130 salcianu 1.1.2.4 131 salcianu 1.1.2.4 System.out.println(mm); 132 salcianu 1.1.2.4 System.out.println(" " + mmi.nb_instrs + " instrs\t" + 133 salcianu 1.1.2.4 mmi.nb_params + " obj param(s)\t" + 134 salcianu 1.1.2.4 mmi.nb_passes + " pass(es)\t" + 135 salcianu 1.1.2.4 mmi.nb_bbs + " BBs\t" + 136 salcianu 1.1.2.4 mmi.nb_sccs + " SCCs\t"); 137 salcianu 1.1.2.4 138 salcianu 1.1.2.4 total_params += mmi.nb_params; 139 salcianu 1.1.2.4 total_instrs += mmi.nb_instrs; 140 salcianu 1.1.2.4 total_bbs += mmi.nb_bbs; 141 salcianu 1.1.2.4 total_sccs += mmi.nb_sccs; 142 salcianu 1.1.2.4 total_passes += mmi.nb_passes; 143 salcianu 1.1.2.4 144 salcianu 1.1.2.4 if(mmi.nb_instrs > maxim_nb_instrs) 145 salcianu 1.1.2.4 maxim_nb_instrs = mmi.nb_instrs; 146 salcianu 1.1.2.4 if(mmi.nb_passes > maxim_nb_passes) 147 salcianu 1.1.2.4 maxim_nb_passes = mmi.nb_passes; 148 salcianu 1.1.2.4 if(mmi.nb_params > maxim_nb_params) 149 salcianu 1.1.2.4 maxim_nb_params = mmi.nb_params; 150 salcianu 1.1.2.1 } 151 salcianu 1.1.2.1 152 salcianu 1.1.2.8 // show some statistics about the size (in bytecode instrs) 153 salcianu 1.1.2.8 // of all the analyzed methods. 154 salcianu 1.1.2.8 int total_b_instrs = print_bytecode_size(methods); 155 salcianu 1.1.2.8 156 salcianu 1.1.2.1 System.out.println("--TOTALS----------------------------------"); 157 salcianu 1.1.2.4 System.out.println("Nb. of analyzed meta-methods : " + nb_mmethods); 158 salcianu 1.1.2.8 System.out.println("Total nb. of IR instrs : " + total_instrs); 159 salcianu 1.1.2.8 System.out.println("Total nb. of Bytecode instrs : " + total_b_instrs); 160 salcianu 1.1.2.4 System.out.println("Total nb. of BBs : " + total_bbs); 161 salcianu 1.1.2.4 System.out.println("Total nb. of SCCs : " + total_sccs); 162 salcianu 1.1.2.3 163 salcianu 1.1.2.1 System.out.println("--AVERAGES--------------------------------"); 164 salcianu 1.1.2.5 double appmm = (double)total_passes/(double)nb_mmethods; 165 salcianu 1.1.2.4 System.out.println("Average Passes/Meta-Method : " + 166 salcianu 1.5 Util.doubleRep(appmm, 6, 2)); 167 salcianu 1.1.2.5 double aipmm = (double)total_instrs/(double)nb_mmethods; 168 salcianu 1.1.2.4 System.out.println("Average Instrs/Meta-Method : " + 169 salcianu 1.5 Util.doubleRep(aipmm, 6, 2)); 170 salcianu 1.1.2.5 double abbpscc = (double)total_bbs/(double)total_sccs; 171 salcianu 1.1.2.4 System.out.println("Average BB(s)/SCC : " + 172 salcianu 1.5 Util.doubleRep(abbpscc, 6, 2)); 173 salcianu 1.1.2.5 double aipbb = (double)total_instrs/(double)total_bbs; 174 salcianu 1.1.2.4 System.out.println("Average Instrs/BB : " + 175 salcianu 1.5 Util.doubleRep(aipbb, 6, 2)); 176 salcianu 1.1.2.5 double aoppmm = (double)total_params/(double)nb_mmethods; 177 salcianu 1.1.2.4 System.out.println("Average Obj. Params/Meta-Method : " + 178 salcianu 1.5 Util.doubleRep(aoppmm, 6, 2)); 179 salcianu 1.1.2.3 180 salcianu 1.1.2.1 System.out.println("--EXTREMES--------------------------------"); 181 salcianu 1.1.2.4 System.out.println("Biggest nb of obj. params : " + maxim_nb_params); 182 salcianu 1.1.2.4 System.out.println("Maximum meta-method size : " + maxim_nb_instrs + 183 salcianu 1.1.2.3 " quad(s)"); 184 salcianu 1.1.2.4 System.out.println("Maximum nb of pass(es) over a meta-method : " + 185 salcianu 1.1.2.3 maxim_nb_passes); 186 salcianu 1.1.2.3 187 salcianu 1.1.2.3 print_extremes_examples(); 188 salcianu 1.1.2.3 189 salcianu 1.1.2.3 System.out.println("--PARAMS----------------------------------"); 190 salcianu 1.1.2.3 191 salcianu 1.1.2.3 int[] mwp = new int[maxim_nb_params + 1]; 192 salcianu 1.1.2.4 for(int i = 0; i < maxim_nb_params; i++) mwp[i] = 0; 193 salcianu 1.1.2.3 194 cananian 1.6 for(Object mmO : info.keySet()){ 195 cananian 1.6 MetaMethod mm = (MetaMethod) mmO; 196 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 197 salcianu 1.1.2.4 mwp[mmi.nb_params]++; 198 salcianu 1.1.2.3 } 199 salcianu 1.1.2.3 200 salcianu 1.1.2.4 for(int i=0;i<mwp.length;i++) 201 salcianu 1.1.2.4 if(mwp[i]!=0) System.out.println("Meta-Methods with " + i + 202 salcianu 1.1.2.4 " param(s): " + mwp[i]); 203 salcianu 1.1.2.8 } 204 salcianu 1.1.2.8 205 salcianu 1.1.2.8 206 salcianu 1.1.2.8 // display the size of the analyzed methods (in bytecode) along with 207 salcianu 1.1.2.8 // the total size 208 salcianu 1.1.2.8 private static final int print_bytecode_size(Set methods) { 209 salcianu 1.1.2.8 HCodeFactory bcf = harpoon.IR.Bytecode.Code.codeFactory(); 210 salcianu 1.1.2.8 int total = 0; 211 salcianu 1.1.2.10 Set cls = new HashSet(); 212 salcianu 1.1.2.8 System.out.println("ANALYZED METHODS SIZE (IN BYTECODE INSTRS)"); 213 cananian 1.6 for(Object hmO : methods) { 214 cananian 1.6 HMethod hm = (HMethod) hmO; 215 salcianu 1.1.2.8 HCode hcode = bcf.convert(hm); 216 salcianu 1.1.2.15 if(hcode == null) { 217 salcianu 1.1.2.15 System.out.println("WARNING: " + hm + " has no HCode"); 218 salcianu 1.1.2.15 continue; 219 salcianu 1.1.2.15 } 220 salcianu 1.1.2.8 int bsize = hcode.getElementsL().size(); 221 salcianu 1.1.2.8 total += bsize; 222 salcianu 1.1.2.9 System.out.println(hm + " " + bsize + " bytecode instrs"); 223 salcianu 1.1.2.10 cls.add(hm.getDeclaringClass()); 224 salcianu 1.1.2.8 } 225 salcianu 1.1.2.8 System.out.println("TOTAL: " + total + " bytecode instrs"); 226 salcianu 1.1.2.8 System.out.println(); 227 salcianu 1.1.2.10 228 salcianu 1.1.2.10 System.out.println("ANALYZED CLASSES:"); 229 cananian 1.6 for(Object hclassO : cls) { 230 cananian 1.6 HClass hclass = (HClass) hclassO; 231 salcianu 1.1.2.11 System.out.println("CLS " + hclass.getName()); 232 salcianu 1.1.2.10 StringBuffer buff = new StringBuffer(hclass.getPackage()); 233 salcianu 1.1.2.10 for(int i = 0; i < buff.length(); i++) 234 salcianu 1.1.2.10 if(buff.charAt(i) == '.') 235 salcianu 1.1.2.10 buff.setCharAt(i, '/'); 236 salcianu 1.1.2.10 if(buff.length() == 0) buff.append("."); 237 salcianu 1.1.2.10 238 salcianu 1.1.2.10 System.out.println("SRC " + buff + "/" + hclass.getSourceFile()); 239 salcianu 1.1.2.10 } 240 salcianu 1.1.2.8 return total; 241 salcianu 1.1.2.3 } 242 salcianu 1.1.2.3 243 salcianu 1.1.2.3 // computes the total number of parameters of the method hm; 244 salcianu 1.1.2.3 // it counts even the this parameter (for the non-static methods) 245 salcianu 1.1.2.3 private static final int compute_nb_params(HMethod hm){ 246 salcianu 1.1.2.3 return hm.getParameterTypes().length + (hm.isStatic()?0:1); 247 salcianu 1.1.2.3 } 248 salcianu 1.1.2.3 249 salcianu 1.1.2.4 private static class MethodInfo{ 250 salcianu 1.1.2.4 HMethod hm; 251 salcianu 1.1.2.4 int nbi; 252 salcianu 1.1.2.4 MethodInfo(HMethod hm, int nbi){ 253 salcianu 1.1.2.4 this.hm = hm; 254 salcianu 1.1.2.4 this.nbi = nbi; 255 salcianu 1.1.2.4 } 256 salcianu 1.1.2.4 public boolean equals(Object o){ 257 salcianu 1.1.2.4 MethodInfo mi2 = (MethodInfo) o; 258 salcianu 1.1.2.4 return hm.equals(mi2.hm) && (nbi == mi2.nbi); 259 salcianu 1.1.2.4 } 260 salcianu 1.1.2.4 public int hashCode(){ 261 salcianu 1.1.2.4 return hm.hashCode() + nbi; 262 salcianu 1.1.2.4 } 263 salcianu 1.1.2.4 }; 264 salcianu 1.1.2.3 265 salcianu 1.1.2.3 private static final void print_extremes_examples(){ 266 salcianu 1.1.2.3 System.out.println("--EXTREMES-2-(EXAMPLES)-------------------"); 267 salcianu 1.1.2.4 System.out.println("Biggest method(s) :"); 268 salcianu 1.1.2.4 // 1. select the biggest method(s) 269 salcianu 1.1.2.3 Set big_procs = new HashSet(); 270 cananian 1.6 for(Object mmO : info.keySet()){ 271 cananian 1.6 MetaMethod mm = (MetaMethod) mmO; 272 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 273 salcianu 1.1.2.4 if(mmi.nb_instrs >= (int) (0.5 * maxim_nb_instrs)) 274 salcianu 1.1.2.4 big_procs.add(new MethodInfo(mm.getHMethod(),mmi.nb_instrs)); 275 salcianu 1.1.2.3 } 276 salcianu 1.1.2.3 // 2. sort them 277 salcianu 1.1.2.4 MethodInfo[] big_procs_array = (MethodInfo[]) 278 salcianu 1.1.2.4 big_procs.toArray(new MethodInfo[big_procs.size()]); 279 salcianu 1.1.2.3 Arrays.sort(big_procs_array,new Comparator(){ 280 salcianu 1.1.2.3 public int compare(Object o1,Object o2){ 281 salcianu 1.1.2.4 MethodInfo mi1 = (MethodInfo) o1; 282 salcianu 1.1.2.4 MethodInfo mi2 = (MethodInfo) o2; 283 salcianu 1.1.2.4 if(mi1.nbi < mi2.nbi) return +1; 284 salcianu 1.1.2.4 if(mi1.nbi > mi2.nbi) return -1; 285 salcianu 1.1.2.3 return 0; 286 salcianu 1.1.2.3 } 287 salcianu 1.1.2.3 public boolean equals(Object obj){ 288 salcianu 1.1.2.3 return this == obj; 289 salcianu 1.1.2.3 } 290 salcianu 1.1.2.3 }); 291 salcianu 1.1.2.3 // 3. print them 292 salcianu 1.1.2.4 for(int i = 0; i < big_procs_array.length; i++){ 293 salcianu 1.1.2.4 MethodInfo mi = big_procs_array[i]; 294 salcianu 1.1.2.4 System.out.println(" " + mi.hm + " (" + mi.nbi + ")"); 295 salcianu 1.1.2.1 } 296 salcianu 1.1.2.3 297 salcianu 1.1.2.4 System.out.println("Most visited meta-method(s) :"); 298 salcianu 1.1.2.3 // 1. select the most visited methods 299 salcianu 1.1.2.3 Set most_visited = new HashSet(); 300 cananian 1.6 for(Object mmO : info.keySet()){ 301 cananian 1.6 MetaMethod mm = (MetaMethod) mmO; 302 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 303 salcianu 1.1.2.4 if(mmi.nb_passes >= (int) (0.5 * maxim_nb_passes)) 304 salcianu 1.1.2.4 most_visited.add(mm); 305 salcianu 1.1.2.3 } 306 salcianu 1.1.2.3 // 2. sort them 307 salcianu 1.1.2.4 MetaMethod[] most_visited_array = (MetaMethod[]) 308 salcianu 1.1.2.4 most_visited.toArray(new MetaMethod[most_visited.size()]); 309 salcianu 1.1.2.3 Arrays.sort(most_visited_array,new Comparator(){ 310 salcianu 1.1.2.3 public int compare(Object o1,Object o2){ 311 salcianu 1.1.2.4 MetaMethodInfo mmi1 = 312 salcianu 1.1.2.4 (MetaMethodInfo) info.get((MetaMethod) o1); 313 salcianu 1.1.2.4 MetaMethodInfo mmi2 = 314 salcianu 1.1.2.4 (MetaMethodInfo) info.get((MetaMethod) o2); 315 salcianu 1.1.2.4 if(mmi1.nb_passes < mmi2.nb_passes) return +1; 316 salcianu 1.1.2.4 if(mmi1.nb_passes > mmi2.nb_passes) return -1; 317 salcianu 1.1.2.3 return 0; 318 salcianu 1.1.2.3 } 319 salcianu 1.1.2.3 public boolean equals(Object obj){ 320 salcianu 1.1.2.3 return this == obj; 321 salcianu 1.1.2.3 } 322 salcianu 1.1.2.3 }); 323 salcianu 1.1.2.3 // 3. print them 324 salcianu 1.1.2.4 for(int i = 0; i < most_visited_array.length; i++){ 325 salcianu 1.1.2.4 MetaMethod mm = most_visited_array[i]; 326 salcianu 1.1.2.4 MetaMethodInfo mmi = (MetaMethodInfo) info.get(mm); 327 salcianu 1.1.2.4 System.out.println(" " + mm + " (" + mmi.nb_passes + ")"); 328 salcianu 1.1.2.1 } 329 salcianu 1.1.2.1 } 330 salcianu 1.1.2.1 331 cananian 1.2 }