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      }