1 cananian 1.1.2.3 // CHStats.java, created Mon Aug 2 11:15:22 1999 by cananian 2 cananian 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Main; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.CachingCodeFactory; 7 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 8 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 9 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 10 cananian 1.1.2.7 import harpoon.ClassFile.Linker; 11 cananian 1.1.2.7 import harpoon.ClassFile.Loader; 12 cananian 1.3 import net.cscott.jutil.UniqueVector; 13 cananian 1.1.2.1 14 cananian 1.1.2.7 import java.util.Collections; 15 cananian 1.1.2.4 import java.util.Iterator; 16 cananian 1.1.2.1 /** 17 cananian 1.1.2.1 * <code>CHStats</code> computes interesting statistics of the 18 cananian 1.1.2.1 * compiler class hierarchy for inclusion in papers and theses. 19 cananian 1.1.2.1 * 20 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 21 cananian 1.3 * @version $Id: CHStats.java,v 1.3 2004/02/08 01:58:13 cananian Exp $ 22 cananian 1.1.2.1 */ 23 cananian 1.1.2.1 24 cananian 1.1.2.1 public abstract class CHStats extends harpoon.IR.Registration { 25 cananian 1.1.2.1 26 cananian 1.1.2.1 public static final void main(String args[]) { 27 cananian 1.1.2.1 java.io.PrintWriter out = new java.io.PrintWriter(System.out, true); 28 cananian 1.1.2.7 Linker linker = Loader.systemLinker; 29 cananian 1.1.2.1 HMethod m = null; 30 cananian 1.1.2.1 31 cananian 1.1.2.1 if (args.length < 2) { 32 cananian 1.1.2.1 System.err.println("Needs class and method name."); 33 cananian 1.1.2.1 return; 34 cananian 1.1.2.1 } 35 cananian 1.1.2.1 36 cananian 1.1.2.1 { 37 cananian 1.1.2.7 HClass cls = linker.forName(args[0]); 38 cananian 1.1.2.1 HMethod hm[] = cls.getDeclaredMethods(); 39 cananian 1.1.2.1 for (int i=0; i<hm.length; i++) 40 cananian 1.1.2.1 if (hm[i].getName().equals(args[1])) { 41 cananian 1.1.2.1 m = hm[i]; 42 cananian 1.1.2.1 break; 43 cananian 1.1.2.1 } 44 cananian 1.1.2.1 } 45 cananian 1.1.2.1 46 cananian 1.1.2.1 HCodeFactory hcf = 47 cananian 1.1.2.1 new CachingCodeFactory(harpoon.IR.Quads.QuadNoSSA.codeFactory()); 48 cananian 1.1.2.5 harpoon.Analysis.ClassHierarchy ch = 49 cananian 1.1.2.7 new harpoon.Analysis.Quads.QuadClassHierarchy 50 cananian 1.1.2.7 (linker, Collections.singleton(m), hcf); 51 cananian 1.1.2.1 System.out.println("For call graph rooted at "+m.getName()+":"); 52 cananian 1.1.2.1 int totalclasses=0, depthsum=0, maxdepth=-1; HClass maxc=null; 53 cananian 1.1.2.4 for (Iterator it=ch.classes().iterator();it.hasNext(); totalclasses++){ 54 cananian 1.1.2.4 HClass c = (HClass) it.next(); 55 cananian 1.1.2.2 int depth=depth(c); 56 cananian 1.1.2.1 if (depth > maxdepth) { maxdepth = depth; maxc=c; } 57 cananian 1.1.2.1 depthsum+=depth; 58 cananian 1.1.2.1 } 59 cananian 1.1.2.1 System.out.println(" Total classes: "+totalclasses); 60 cananian 1.1.2.1 System.out.println(" Maximum depth: "+maxdepth+" ("+maxc+")"); 61 cananian 1.1.2.1 System.out.println(" Average depth: "+((float)depthsum/totalclasses)); 62 cananian 1.1.2.2 } 63 cananian 1.1.2.2 private static java.util.Map dm = new java.util.HashMap(); 64 cananian 1.1.2.2 private static int depth(HClass c) { 65 cananian 1.1.2.2 if (dm.containsKey(c)) { // use cached value. 66 cananian 1.1.2.2 Integer dI = (Integer) dm.get(c); 67 cananian 1.1.2.2 if (dI!=null) return dI.intValue(); 68 cananian 1.1.2.2 System.err.println("Circular reference to "+c); 69 cananian 1.1.2.2 dm.put(c, new Integer(0)); 70 cananian 1.1.2.2 return 0; 71 cananian 1.1.2.2 } 72 cananian 1.1.2.2 dm.put(c, null); 73 cananian 1.1.2.2 if (c.isInterface()) { 74 cananian 1.1.2.2 int depth=0; 75 cananian 1.1.2.2 HClass in[] = c.getInterfaces(); 76 cananian 1.1.2.2 for (int i=0; i<in.length; i++) { 77 cananian 1.1.2.2 int d = 1 + depth(in[i]); 78 cananian 1.1.2.2 if (d>depth) depth=d; 79 cananian 1.1.2.2 } 80 cananian 1.1.2.2 dm.put(c, new Integer(depth)); 81 cananian 1.1.2.2 return depth; 82 cananian 1.1.2.2 } else { 83 cananian 1.1.2.2 int depth = 0; 84 cananian 1.1.2.2 HClass sc=c.getSuperclass(); 85 cananian 1.1.2.2 if (sc!=null) depth = 1 + depth(sc); 86 cananian 1.1.2.2 dm.put(c, new Integer(depth)); 87 cananian 1.1.2.2 return depth; 88 cananian 1.1.2.2 } 89 cananian 1.1.2.1 } 90 cananian 1.2 }