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     }