1 cananian 1.1.2.1 // Sizer.java, created Sun Jul 16 21:25:17 2000 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 2000 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.Analysis.ClassHierarchy;
  7 cananian 1.1.2.1 import harpoon.Analysis.Quads.QuadClassHierarchy;
  8 cananian 1.3     import harpoon.Backend.Generic.Frame;
  9 salcianu 1.5     import harpoon.Backend.Backend;
 10 cananian 1.1.2.2 import harpoon.ClassFile.CachingCodeFactory;
 11 cananian 1.1.2.2 import harpoon.ClassFile.HClass;
 12 cananian 1.1.2.2 import harpoon.ClassFile.HCode;
 13 cananian 1.1.2.2 import harpoon.ClassFile.HCodeFactory;
 14 cananian 1.1.2.2 import harpoon.ClassFile.HMethod;
 15 cananian 1.1.2.2 import harpoon.ClassFile.Linker;
 16 cananian 1.1.2.2 import harpoon.ClassFile.Loader;
 17 cananian 1.6     import harpoon.Util.ParseUtil;
 18 cananian 1.1.2.2 import java.util.HashSet;
 19 cananian 1.1.2.2 import java.util.Iterator;
 20 cananian 1.1.2.2 import java.util.List;
 21 cananian 1.1.2.2 import java.util.Set;
 22 cananian 1.1.2.1 /**
 23 cananian 1.1.2.1  * <code>Sizer</code> computes the sizes of all the methods used in
 24 cananian 1.1.2.1  * a given program.  It is used for generating paper statistics on
 25 cananian 1.1.2.1  * our benchmarks.
 26 cananian 1.1.2.1  * 
 27 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 28 cananian 1.7      * @version $Id: Sizer.java,v 1.7 2004/02/08 03:21:38 cananian Exp $
 29 cananian 1.1.2.1  */
 30 cananian 1.1.2.1 public class Sizer extends harpoon.IR.Registration {
 31 salcianu 1.4     
 32 cananian 1.1.2.1     public static void main(String[] args) {
 33 cananian 1.1.2.1         if (args.length!=1) {
 34 cananian 1.1.2.1             System.err.println("USAGE: java harpoon.Main.Sizer <classname>");
 35 cananian 1.1.2.1             System.exit(1);
 36 cananian 1.1.2.1         }
 37 cananian 1.6             final Linker linker = Loader.systemLinker;
 38 cananian 1.1.2.1         HCodeFactory hcf = harpoon.IR.Bytecode.Code.codeFactory();
 39 cananian 1.1.2.1         HCodeFactory bytecode = new CachingCodeFactory(hcf) {
 40 cananian 1.1.2.1             public void clear(HMethod m) {
 41 cananian 1.1.2.1                 /* don't clear our cache, but go ahead and clear our parent */
 42 cananian 1.1.2.1                 parent.clear(m);
 43 cananian 1.1.2.1             }
 44 cananian 1.1.2.1         };
 45 cananian 1.1.2.1         hcf = new CachingCodeFactory
 46 cananian 1.1.2.1             (harpoon.IR.Quads.QuadNoSSA.codeFactory(hcf));
 47 cananian 1.1.2.1         
 48 cananian 1.1.2.1         HClass root = linker.forName(args[0]);
 49 cananian 1.1.2.1         HMethod mainMethod = root.getMethod("main", "([Ljava/lang/String;)V");
 50 cananian 1.3             // any frame will do:
 51 salcianu 1.5             Frame frame = Backend.getFrame(Backend.PRECISEC, mainMethod);
 52 cananian 1.6             final Set roots = new HashSet
 53 cananian 1.3                 (frame.getRuntime().runtimeCallableMethods());
 54 cananian 1.1.2.1         roots.add(mainMethod);
 55 cananian 1.6             // other roots
 56 cananian 1.6             String fileName="myroots";
 57 cananian 1.6             try {
 58 cananian 1.6                 ParseUtil.readResource(fileName, new ParseUtil.StringParser() {
 59 cananian 1.6                         public void parseString(String s)
 60 cananian 1.6                             throws ParseUtil.BadLineException {
 61 cananian 1.6                             if (s.indexOf('(') < 0) // parse as class name.
 62 cananian 1.6                                 roots.add(ParseUtil.parseClass(linker, s));
 63 cananian 1.6                             else // parse as method name.
 64 cananian 1.6                                 roots.add(ParseUtil.parseMethod(linker, s));
 65 cananian 1.6                         }
 66 cananian 1.6                     });
 67 cananian 1.6             } catch(java.io.IOException ex) {
 68 cananian 1.6                 System.err.println("Error reading " + fileName + ": " + ex);
 69 cananian 1.6                 ex.printStackTrace();
 70 cananian 1.6                 System.exit(1);
 71 cananian 1.6             }
 72 cananian 1.6             // okay, now build class hierarchy
 73 cananian 1.1.2.1         ClassHierarchy ch = new QuadClassHierarchy(linker, roots, hcf);
 74 cananian 1.1.2.1 
 75 cananian 1.1.2.1         System.out.println("CLASSES:               " +
 76 cananian 1.1.2.1                            ch.classes().size());
 77 cananian 1.1.2.1         System.out.println("INSTANTIATED CLASSES:  " +
 78 cananian 1.1.2.1                            ch.instantiatedClasses().size());
 79 cananian 1.1.2.1         System.out.println("CALLABLE METHODS:      " +
 80 cananian 1.1.2.1                            ch.callableMethods().size());
 81 cananian 1.1.2.1 
 82 cananian 1.1.2.1         long app_bytecode_size = 0, app_quad_size = 0;
 83 cananian 1.1.2.1         long lib_bytecode_size = 0, lib_quad_size = 0;
 84 cananian 1.7             for (Object hmO : ch.callableMethods()) {
 85 cananian 1.7                 HMethod hm = (HMethod) hmO;
 86 cananian 1.1.2.1             HCode hcB = bytecode.convert(hm);
 87 cananian 1.1.2.1             int bsize = (hcB==null) ? 0 : hcB.getElementsL().size();
 88 cananian 1.1.2.1             HCode hcQ = hcf.convert(hm);
 89 cananian 1.1.2.1             int qsize = (hcQ==null) ? 0 : hcQ.getElementsL().size();
 90 cananian 1.1.2.1             if (hm.getDeclaringClass().getName().startsWith("java") ||
 91 cananian 1.1.2.1                 hm.getDeclaringClass().getName().startsWith("sun")) {
 92 cananian 1.1.2.1                 lib_bytecode_size += bsize; lib_quad_size += qsize;
 93 cananian 1.1.2.1             } else {
 94 cananian 1.1.2.1                 app_bytecode_size += bsize; app_quad_size += qsize;
 95 cananian 1.1.2.1             }
 96 cananian 1.1.2.1         }
 97 cananian 1.1.2.1         System.out.println("TOTAL BYTECODE INSTRS: "+
 98 cananian 1.1.2.1                            (app_bytecode_size + lib_bytecode_size) +
 99 cananian 1.1.2.1                            "  ("+app_bytecode_size+" app / "
100 cananian 1.1.2.1                                 +lib_bytecode_size+" lib)");
101 cananian 1.1.2.1         System.out.println("TOTAL QUAD INSTRS:     "+
102 cananian 1.1.2.1                            (app_quad_size + lib_quad_size) +
103 cananian 1.1.2.1                            "  ("+app_quad_size+" app / "
104 cananian 1.1.2.1                                 +lib_quad_size+" lib)");
105 cananian 1.1.2.1     }    
106 cananian 1.2     }