Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Main.java

00001 package ca.mcgill.sable.soot.jimple;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Jimple, a 3-address code Java(TM) bytecode representation.        *
00005  * Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca)    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * Modifications by Etienne Gagnon (gagnon@sable.mcgill.ca) are      *
00009  * Copyright (C) 1998 Etienne Gagnon (gagnon@sable.mcgill.ca).  All  *
00010  * rights reserved.                                                  *
00011  *                                                                   *
00012  * Modifications by Patrick Lam (plam@sable.mcgill.ca) are           *
00013  * Copyright (C) 1999 Patrick Lam.  All rights reserved.             *
00014  *                                                                   *
00015  * This work was done as a project of the Sable Research Group,      *
00016  * School of Computer Science, McGill University, Canada             *
00017  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00018  * modification not identified as such is not covered by the         *
00019  * preceding statement.                                              *
00020  *                                                                   *
00021  * This work is free software; you can redistribute it and/or        *
00022  * modify it under the terms of the GNU Library General Public       *
00023  * License as published by the Free Software Foundation; either      *
00024  * version 2 of the License, or (at your option) any later version.  *
00025  *                                                                   *
00026  * This work is distributed in the hope that it will be useful,      *
00027  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00028  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00029  * Library General Public License for more details.                  *
00030  *                                                                   *
00031  * You should have received a copy of the GNU Library General Public *
00032  * License along with this library; if not, write to the             *
00033  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00034  * Boston, MA  02111-1307, USA.                                      *
00035  *                                                                   *
00036  * Java is a trademark of Sun Microsystems, Inc.                     *
00037  *                                                                   *
00038  * To submit a bug report, send a comment, or get the latest news on *
00039  * this project and other Sable Research Group projects, please      *
00040  * visit the web site: http://www.sable.mcgill.ca/                   *
00041  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00042 
00043 /*
00044  Reference Version
00045  -----------------
00046  This is the latest official version on which this file is based.
00047  The reference version is: $SootVersion: 1.beta.4 $
00048 
00049  Change History
00050  --------------
00051  A) Notes:
00052 
00053  Please use the following template.  Most recent changes should
00054  appear at the top of the list.
00055 
00056  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00057    [description of modification].
00058 
00059  Any Modification flagged with "(*)" was done as a project of the
00060  Sable Research Group, School of Computer Science,
00061  McGill University, Canada (http://www.sable.mcgill.ca/).
00062 
00063  You should add your copyright, using the following template, at
00064  the top of this file, along with other copyrights.
00065 
00066  *                                                                   *
00067  * Modifications by [name] are                                       *
00068  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00069  * reserved.                                                         *
00070  *                                                                   *
00071 
00072  B) Changes:
00073 
00074  - Modified on February 3, 1999 by Patrick Lam (plam@sable.mcgill.ca) (*)
00075    Added changes in support of the Grimp intermediate
00076    representation (with aggregated-expressions).
00077 
00078  - Modified on November 2, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00079    Repackaged all source files and performed extensive modifications.
00080    First initial release of Soot.
00081 
00082  - Modified on October 4, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00083    Added flag and option to print debugging information.
00084 
00085  - Modified on 12-Sep-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00086    Changed the output options, and redirected the output to files.
00087 
00088  - Modified on 8-Sep-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00089    Corrected the jimplification of several classes.
00090 
00091  - Modified on 1-Sep-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00092    Allows multiple arguments on the command line.  Useful for
00093    timing the jimplification of several classes.
00094 
00095  - Modified on 28-Aug-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00096    Changed the displayed copyright on program execution.
00097 
00098  - Modified on July 29, 1998 by Etienne Gagnon (gagnon@sable.mcgill.ca). (*)
00099    Added -nosplitting and -oldtyping parameters.
00100 
00101  - Modified on 23-Jul-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00102    Minor changes.
00103 
00104  - Modified on July 5, 1998 by Etienne Gagnon (gagnon@sable.mcgill.ca). (*)
00105    Added jimpleClassPath parameter.
00106    Updated copyright notice.
00107 
00108  - Modified on 15-Jun-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00109    First internal release (Version 0.1).
00110 */
00111 
00112 import ca.mcgill.sable.soot.*;
00113 import ca.mcgill.sable.util.*;
00114 import ca.mcgill.sable.soot.grimp.*;
00115 
00116 import java.io.*;
00117 
00118 public class Main
00119 {
00120     static boolean naiveJimplification;
00121     static boolean onlyJimpleOutput;
00122     public static boolean isVerbose;
00123     static boolean onlyJasminOutput;
00124     static boolean isProfilingOptimization;
00125     static boolean oldTyping;
00126     static boolean isInDebugMode;
00127     static boolean usePackedLive;
00128     static boolean usePackedDefs = true;
00129     static boolean isTestingPerformance;
00130 
00131     public static String jimpleClassPath;
00132 
00133     static boolean produceJimpleFile,
00134         produceJasminFile,
00135         produceJimpFile = true;
00136 
00137     static int totalFlowNodes,
00138            totalFlowComputations;
00139            
00140     static Timer copiesTimer = new Timer(),
00141         defsTimer = new Timer(),
00142         usesTimer = new Timer(),
00143         liveTimer = new Timer(),
00144         splitTimer = new Timer(),
00145         packTimer = new Timer(),
00146         cleanup1Timer = new Timer(),
00147         cleanup2Timer = new Timer(),
00148         conversionTimer = new Timer(),
00149         cleanupAlgorithmTimer = new Timer(),
00150         graphTimer = new Timer(),
00151         assignTimer = new Timer(),
00152         resolveTimer = new Timer(),
00153         totalTimer = new Timer(),
00154         splitPhase1Timer = new Timer(),
00155         splitPhase2Timer = new Timer(),
00156         defsSetupTimer = new Timer(),
00157         defsAnalysisTimer = new Timer(),
00158         defsPostTimer = new Timer(),
00159         liveSetupTimer = new Timer(),
00160         liveAnalysisTimer = new Timer(),
00161         livePostTimer = new Timer(),
00162         aggregationTimer = new Timer(),
00163         grimpAggregationTimer = new Timer(),
00164         deadCodeTimer = new Timer(),
00165         propagatorTimer = new Timer();
00166         
00167     static int conversionLocalCount,
00168         cleanup1LocalCount,
00169         splitLocalCount,
00170         assignLocalCount,
00171         packLocalCount,
00172         cleanup2LocalCount;
00173 
00174     static int conversionStmtCount,
00175         cleanup1StmtCount,
00176         splitStmtCount,
00177         assignStmtCount,
00178         packStmtCount,
00179         cleanup2StmtCount;
00180 
00181 
00182     private static void handleClass(SootClass c, String postFix, PrintWriter writerOut, int buildBodyOptions)
00183     {
00184         if(postFix.equals(".jasmin"))
00185             new JasminClass(c, new BuildBody(Grimp.v(), new StoredBody(ClassFile.v()))).print(writerOut);
00186         else if(postFix.equals(".jimp"))
00187         {
00188             c.printTo(new BuildBody(Jimple.v(), new StoredBody(ClassFile.v()), buildBodyOptions),
00189                 writerOut, PrintJimpleBodyOption.USE_ABBREVIATIONS);
00190         }
00191         else
00192             c.printTo(new BuildBody(Jimple.v(), new StoredBody(ClassFile.v()), buildBodyOptions),
00193                 writerOut);
00194     }
00195     public static void main(String[] args) throws RuntimeException
00196     {
00197         int firstNonOption = 0;
00198         long stmtCount = 0;
00199         int buildBodyOptions = 0;
00200 
00201         totalTimer.start();
00202 
00203         SootClassManager cm = new SootClassManager();
00204 
00205         if(args.length == 0)
00206         {
00207 // $Format: "            System.out.println(\"Jimple version $ProjectVersion$\");"$
00208             System.out.println("Jimple version 1.beta.4");
00209             System.out.println("Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca).");
00210             System.out.println("All rights reserved.");
00211             System.out.println("");
00212             System.out.println("Portions copyright (C) 1997 Clark Verbrugge (clump@sable.mcgill.ca).");
00213             System.out.println("All rights reserved.");
00214             System.out.println("");
00215             System.out.println("Modifications are copyright (C) 1997, 1998 by their respective contributors.");
00216             System.out.println("See individual source files for details.");
00217             System.out.println("");
00218             System.out.println("Jimple comes with ABSOLUTELY NO WARRANTY.  This is free software,");
00219             System.out.println("and you are welcome to redistribute it under certain conditions.");
00220             System.out.println("See the accompanying file 'COPYING' for details.");
00221             System.out.println("");
00222             System.out.println("Syntax: java ca.mcgill.sable.soot.jimple.Main [options] class");
00223             System.out.println("");
00224             System.out.println("Classpath Option:");
00225             System.out.println("    -jimpleClassPath <path>   uses <path> as classpath for finding classes");
00226             System.out.println("");
00227             System.out.println("Output Options:");
00228             System.out.println("    -jimple                   produce .jimple code");
00229             System.out.println("    -jimp                     produce .jimp (abbreviated .jimple) code [default]");
00230             System.out.println("    -jasmin                   produce .jasmin code");
00231             System.out.println("");
00232             System.out.println("Jimplification Options:");
00233             System.out.println("    -nocleanup                no constant or copy propagation is performed");
00234             System.out.println("    -nosplitting              no splitting of variables is performed");
00235             System.out.println("    -nocleanup                no constant or copy propagation is performed");
00236             System.out.println("    -oldtyping                use old typing algorithm");
00237             System.out.println("    -typeless                 do not assign types.  Cannot be used with -jasmin");
00238             System.out.println("                              or -nolocalpacking ");
00239             System.out.println("    -nolocalpacking           do not re-use locals after jimplification");
00240             System.out.println("    -noaggregating            do not perform any Jimple-level aggregation");
00241             System.out.println("");
00242             System.out.println("Profiling/Debugging Options:");
00243             System.out.println("    -timetransform            perform full transformation and print timings");
00244             System.out.println("    -verbose                  print out jimplification process");
00245             System.out.println("    -debug                    avoid catching errors during jimplification");
00246             System.out.println("    -testperf                 jimplify all classes & methods and gather stats");
00247             System.out.println("                              does not throw exception if error in typing");
00248             System.exit(0);
00249         }
00250 
00251         // Handle all the options
00252             for(int i = 0; i < args.length; i++)
00253             {
00254                 if(args[i].equals("-jimple"))
00255                     produceJimpleFile = true;
00256                 else if(args[i].equals("-jasmin"))
00257                     produceJasminFile = true;
00258                 else if(args[i].equals("-jimp"))
00259                     produceJimpFile = true;
00260                 else if(args[i].equals("-nocleanup"))
00261                     buildBodyOptions |= BuildJimpleBodyOption.NO_CLEANUP;
00262                 else if(args[i].equals("-typeless"))
00263                     buildBodyOptions |= BuildJimpleBodyOption.NO_TYPING;
00264                 else if(args[i].equals("-nolocalpacking"))
00265                     buildBodyOptions |= BuildJimpleBodyOption.NO_PACKING;
00266                 else if(args[i].equals("-noaggregating"))
00267                     buildBodyOptions |= BuildJimpleBodyOption.NO_AGGREGATING;
00268                 else if(args[i].equals("-timetransform"))
00269                     isProfilingOptimization = true;
00270                 else if(args[i].equals("-verbose"))
00271                     isVerbose = true;
00272                 else if(args[i].equals("-nosplitting"))
00273                     buildBodyOptions |= BuildJimpleBodyOption.NO_SPLITTING;
00274                 else if(args[i].equals("-oldtyping"))
00275                     oldTyping = true;
00276                 else if(args[i].equals("-usepackedlive"))
00277                     usePackedLive = true;
00278                 else if(args[i].equals("-usepackeddefs"))
00279                     usePackedDefs = true;    
00280                 else if(args[i].equals("-testperf"))
00281                 {
00282                     isProfilingOptimization = true;
00283                     isTestingPerformance = true;
00284                 }
00285                 else if(args[i].equals("-jimpleClassPath"))
00286                 {   if(++i < args.length)
00287                         jimpleClassPath = args[i];
00288                 }
00289                 else if(args[i].equals("-debug"))
00290                     isInDebugMode = true;
00291                 else if(args[i].startsWith("-"))
00292                 {
00293                     System.out.println("Unrecognized option: " + args[i]);
00294                     System.exit(0);
00295                 }
00296                 else
00297                     break;
00298 
00299                 firstNonOption = i + 1;
00300             }
00301 
00302         // Handle all the classes
00303         {
00304             int numFailed = 0;
00305             int numSuccess = 0;
00306 
00307             List listBodies = new ArrayList();
00308 
00309             for(int i = firstNonOption; i < args.length; i++)
00310             {
00311                 SootClass c = cm.getClass(args[i]);
00312                 String postFix;
00313                 PrintWriter writerOut = null;
00314                 FileOutputStream streamOut = null;
00315 
00316                 System.out.print("Jimplifying " + c.getName() + "... " );
00317                 System.out.flush();
00318 
00319                 // Open output file.
00320                 {
00321                     if(produceJasminFile)
00322                         postFix = ".jasmin";
00323                     else if(produceJimpleFile)
00324                         postFix = ".jimple";
00325                     else
00326                         postFix = ".jimp";
00327 
00328                     try {
00329                         streamOut = new FileOutputStream(c.getName() + postFix);
00330                         writerOut = new PrintWriter(streamOut);
00331                     }
00332                     catch (IOException e)
00333                     {
00334                         System.out.println("Cannot output file " + c.getName() + postFix);
00335                     }
00336                 }
00337 
00338                 if(isTestingPerformance)
00339                 {
00340                     Iterator methodIt = c.getMethods().iterator();
00341                     long localStmtCount = 0;
00342 
00343                     try {
00344                         while(methodIt.hasNext())
00345                         {
00346                             SootMethod m = (SootMethod) methodIt.next();
00347                             JimpleBody listBody = (JimpleBody) new BuildBody(Jimple.v(), new StoredBody(ClassFile.v())).resolveFor(m);
00348                             
00349                             listBodies.add(listBody);
00350                             localStmtCount += listBody.getStmtList().size();
00351                         }
00352 
00353                         stmtCount += localStmtCount;
00354 
00355                         System.out.println(localStmtCount + " stmts  ");
00356                         numSuccess++;
00357                     }
00358                     catch(Exception e)
00359                     {
00360                         System.out.println("failed due to: " + e);
00361                         numFailed++;
00362                     }
00363                 }
00364                 else
00365                 {
00366                     // Produce the file
00367                     {
00368                         if(!isInDebugMode)
00369                         {
00370                             try {
00371                                 handleClass(c, postFix, writerOut, buildBodyOptions);
00372                             }
00373                             catch(Exception e)
00374                             {
00375                                 System.out.println("failed due to: " + e);
00376                             }
00377                         }
00378                         else {
00379                             handleClass(c, postFix, writerOut, buildBodyOptions);
00380                         }
00381     
00382                         try {
00383                             writerOut.flush();
00384                             streamOut.close();
00385                         }
00386                         catch(IOException e )
00387                         {
00388                             System.out.println("Cannot close output file " + c.getName() + postFix);
00389                         }
00390     
00391                         System.out.println();
00392                     }
00393                 }
00394             }
00395             
00396             if(isProfilingOptimization)
00397             {
00398                 if(isTestingPerformance)
00399                 {
00400                     System.out.println("Successfully jimplified " + numSuccess + " classfiles; failed on " + numFailed + ".");
00401     
00402                     // Count number of statements stored
00403                     {
00404                         Iterator bodyIt = listBodies.iterator();
00405                         long storedStmtCount = 0;
00406     
00407                         while(bodyIt.hasNext())
00408                         {
00409                             JimpleBody listBody = (JimpleBody) bodyIt.next();
00410                             storedStmtCount += listBody.getStmtList().size();
00411                         }
00412     
00413                         System.out.println("Confirmed " + storedStmtCount + " stored statements.");
00414                         System.out.println();
00415                     }
00416                 }
00417                 
00418                 totalTimer.end();
00419                     
00420                 long totalTime = totalTimer.getTime();
00421                     
00422                 System.out.println("Time measurements");
00423                 System.out.println();
00424                 
00425                 System.out.println("      Building graphs: " + toTimeString(graphTimer, totalTime));
00426                 System.out.println("  Computing LocalDefs: " + toTimeString(defsTimer, totalTime));
00427 //                System.out.println("                setup: " + toTimeString(defsSetupTimer, totalTime));
00428 //                System.out.println("             analysis: " + toTimeString(defsAnalysisTimer, totalTime));
00429 //                System.out.println("                 post: " + toTimeString(defsPostTimer, totalTime));
00430                 System.out.println("  Computing LocalUses: " + toTimeString(usesTimer, totalTime));
00431                 System.out.println("     Cleaning up code: " + toTimeString(cleanupAlgorithmTimer, totalTime));
00432                 System.out.println("Computing LocalCopies: " + toTimeString(copiesTimer, totalTime));
00433                 System.out.println(" Computing LiveLocals: " + toTimeString(liveTimer, totalTime));
00434 //                System.out.println("                setup: " + toTimeString(liveSetupTimer, totalTime));
00435 //                System.out.println("             analysis: " + toTimeString(liveAnalysisTimer, totalTime));
00436 //                System.out.println("                 post: " + toTimeString(livePostTimer, totalTime));
00437                 
00438                 System.out.println("Coading coffi structs: " + toTimeString(resolveTimer, totalTime));
00439 
00440                 
00441                 System.out.println();
00442 
00443                 // Print out time stats.
00444                 {
00445                     float timeInSecs;
00446 
00447                     System.out.println(" Bytecode -> jimple (naive): " + toTimeString(conversionTimer, totalTime)); 
00448                     System.out.println("        Splitting variables: " + toTimeString(splitTimer, totalTime));
00449                     System.out.println("            Assigning types: " + toTimeString(assignTimer, totalTime));
00450                     System.out.println("  Propagating copies & csts: " + toTimeString(propagatorTimer, totalTime));
00451                     System.out.println("      Eliminating dead code: " + toTimeString(deadCodeTimer, totalTime));
00452                     System.out.println("                Aggregation: " + toTimeString(aggregationTimer, totalTime));
00453                     System.out.println("            Coloring locals: " + toTimeString(packTimer, totalTime));
00454 
00455                                             
00456 //                    System.out.println("           Cleaning up code: " + toTimeString(cleanup1Timer, totalTime) +
00457 //                        "\t" + cleanup1LocalCount + " locals  " + cleanup1StmtCount + " stmts");
00458                     
00459 
00460                        
00461                        
00462 //                    System.out.println("               Split phase1: " + toTimeString(splitPhase1Timer, totalTime));
00463 //                    System.out.println("               Split phase2: " + toTimeString(splitPhase2Timer, totalTime));
00464                     
00465                         
00466                 
00467                         /*
00468                     System.out.println("cleanup2Timer:   " + cleanup2Time +
00469                         "(" + (cleanup2Time * 100 / totalTime) + "%) " +
00470                         cleanup2LocalCount + " locals  " + cleanup2StmtCount + " stmts");
00471 */
00472 
00473                     timeInSecs = (float) totalTime / 1000.0f;
00474                     float memoryUsed = (float) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000.0f;
00475 
00476                     System.out.println("totalTime:" + toTimeString(totalTimer, totalTime));
00477                     System.out.println("totalMemory:" + memoryUsed + "k  ");
00478 
00479                     if(isTestingPerformance)
00480                     {
00481                         System.out.println("Time/Space performance");
00482                         System.out.println();
00483                         
00484                         System.out.println(toFormattedString(stmtCount / timeInSecs) + " stmt/s");
00485                         System.out.println(toFormattedString((float) memoryUsed / stmtCount) + " k/stmt");
00486                         
00487                     }
00488                     
00489                     System.out.println("totalFlowNodes: " + totalFlowNodes + 
00490                         " totalFlowComputations: " + totalFlowComputations + " avg: " + 
00491                         truncatedOf((double) totalFlowComputations / totalFlowNodes, 2));
00492         
00493                 }
00494             }
00495         }
00496     }
00497     public static String paddedLeftOf(String s, int length)
00498     {
00499         if(s.length() >= length)
00500             return s;
00501         else {
00502             int diff = length - s.length();
00503             char[] padding = new char[diff];
00504             
00505             for(int i = 0; i < diff; i++)
00506                 padding[i] = ' ';
00507             
00508             return new String(padding) + s;
00509         }    
00510     }
00511     private static String toFormattedString(double value)
00512     {
00513         return paddedLeftOf(new Double(truncatedOf(value, 2)).toString(), 5);
00514     }
00515     private static String toTimeString(Timer timer, long totalTime)
00516     {
00517         long time = timer.getTime();
00518         String timeString = paddedLeftOf(new Double(truncatedOf(time / 1000.0, 1)).toString(), 5);
00519         
00520         return (timeString + "s" + paddedLeftOf(" (" + (time * 100 / totalTime) + "%" + ")", 5));   
00521     }
00522     public static double truncatedOf(double d, int numDigits)
00523     {
00524         double multiplier = 1;
00525         
00526         for(int i = 0; i < numDigits; i++)
00527             multiplier *= 10;
00528             
00529         return ((long) (d * multiplier)) / multiplier;
00530     }
00531 }

Generated at Thu Feb 7 06:50:14 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001