00001 package ca.mcgill.sable.soot.grimp;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 import ca.mcgill.sable.soot.*;
00080 import ca.mcgill.sable.soot.jimple.*;
00081 import ca.mcgill.sable.util.*;
00082 import java.io.*;
00083
00084 public class Main
00085 {
00086 static boolean naiveJimplification;
00087 static boolean onlyJimpleOutput;
00088 public static boolean isVerbose;
00089 static boolean onlyJasminOutput;
00090 static boolean isProfilingOptimization;
00091 static boolean oldTyping;
00092 static boolean isInDebugMode;
00093 static boolean usePackedLive;
00094 static boolean usePackedDefs = true;
00095 static boolean isTestingPerformance;
00096
00097 public static String jimpleClassPath;
00098
00099 static boolean produceJimpleFile,
00100 produceJasminFile,
00101 produceJimpFile,
00102 produceGrimpleFile,
00103 produceGrimpFile = true;
00104
00105 static Timer copiesTimer = new Timer(),
00106 defsTimer = new Timer(),
00107 usesTimer = new Timer(),
00108 liveTimer = new Timer(),
00109 splitTimer = new Timer(),
00110 packTimer = new Timer(),
00111 cleanup1Timer = new Timer(),
00112 cleanup2Timer = new Timer(),
00113 conversionTimer = new Timer(),
00114 cleanupAlgorithmTimer = new Timer(),
00115 graphTimer = new Timer(),
00116 assignTimer = new Timer(),
00117 resolveTimer = new Timer(),
00118 aggregationTimer = new Timer(),
00119 totalTimer = new Timer();
00120
00121 static int conversionLocalCount,
00122 cleanup1LocalCount,
00123 splitLocalCount,
00124 assignLocalCount,
00125 packLocalCount,
00126 cleanup2LocalCount;
00127
00128 static int conversionStmtCount,
00129 cleanup1StmtCount,
00130 splitStmtCount,
00131 assignStmtCount,
00132 packStmtCount,
00133 cleanup2StmtCount;
00134
00135
00136 private static void handleClass(SootClass c, String postFix, PrintWriter writerOut, int buildBodyOptions)
00137 {
00138 if(postFix.equals(".jasmin"))
00139 new JasminClass(c, new BuildBody(Grimp.v(), new StoredBody(ClassFile.v()))).print(writerOut);
00140 else if(postFix.equals(".jimp") || postFix.equals(".grimp"))
00141 {
00142 c.printTo(new BuildBody(Grimp.v(), new StoredBody(ClassFile.v()), buildBodyOptions),
00143 writerOut, PrintGrimpBodyOption.USE_ABBREVIATIONS);
00144 }
00145 else
00146 c.printTo(new BuildBody(Grimp.v(), new StoredBody(ClassFile.v()), buildBodyOptions),
00147 writerOut);
00148 }
00149 public static void main(String[] args) throws RuntimeException
00150 {
00151 int firstNonOption = 0;
00152 long stmtCount = 0;
00153 int buildBodyOptions = 0;
00154
00155 totalTimer.start();
00156
00157 SootClassManager cm = new SootClassManager();
00158
00159 if(args.length == 0)
00160 {
00161
00162 System.out.println("Grimp version 1.beta.4");
00163 System.out.println("Copyright (C) 1999 Patrick Lam (plam@sable.mcgill.ca).");
00164 System.out.println("All rights reserved.");
00165 System.out.println("Portions copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca).");
00166 System.out.println("All rights reserved.");
00167 System.out.println("");
00168 System.out.println("Portions copyright (C) 1997 Clark Verbrugge (clump@sable.mcgill.ca).");
00169 System.out.println("All rights reserved.");
00170 System.out.println("");
00171 System.out.println("Modifications are copyright (C) 1997, 1998 by their respective contributors.");
00172 System.out.println("See individual source files for details.");
00173 System.out.println("");
00174 System.out.println("Grimp comes with ABSOLUTELY NO WARRANTY. This is free software,");
00175 System.out.println("and you are welcome to redistribute it under certain conditions.");
00176 System.out.println("See the accompanying file 'COPYING' for details.");
00177 System.out.println("");
00178 System.out.println("Syntax: java ca.mcgill.sable.soot.grimp.Main [options] class");
00179 System.out.println("");
00180 System.out.println("Classpath Option:");
00181 System.out.println(" -jimpleClassPath <path> uses <path> as classpath for finding classes");
00182 System.out.println("");
00183 System.out.println("Output Options:");
00184 System.out.println(" -grimple produce .grimple code");
00185 System.out.println(" -grimp produce .grimp (short .grimple) code [default]");
00186 System.out.println(" -jasmin produce .jasmin code");
00187 System.out.println("");
00188 System.out.println("Jimplification Options:");
00189 System.out.println(" -nocleanup no constant or copy propagation is performed");
00190 System.out.println(" -nosplitting no splitting of variables is performed");
00191 System.out.println(" -nocleanup no constant or copy propagation is performed");
00192 System.out.println(" -oldtyping use old typing algorithm");
00193 System.out.println(" -typeless do not assign types. Cannot be used with -jasmin");
00194 System.out.println(" or -nolocalpacking ");
00195 System.out.println(" -nolocalpacking do not re-use locals after jimplification");
00196 System.out.println(" -noaggregating do not perform any Jimple-level aggregation");
00197 System.out.println("");
00198 System.out.println("Profiling/Debugging Options:");
00199 System.out.println(" -timetransform perform full transformation and print timings");
00200 System.out.println(" -verbose print out jimplification process");
00201 System.out.println(" -debug avoid catching errors during jimplification");
00202 System.out.println(" does not throw exception if error in typing");
00203 System.exit(0);
00204 }
00205
00206
00207 for(int i = 0; i < args.length; i++)
00208 {
00209 if(args[i].equals("-jimple"))
00210 {
00211 produceJimpleFile = true;
00212 buildBodyOptions|=BuildGrimpBodyOption.NO_AGGREGATING;
00213 }
00214 else if(args[i].equals("-jasmin"))
00215 {
00216 produceJasminFile = true;
00217 buildBodyOptions|=BuildGrimpBodyOption.NO_AGGREGATING;
00218 }
00219 else if(args[i].equals("-jimp"))
00220 {
00221 produceJimpFile = true;
00222 buildBodyOptions|=BuildGrimpBodyOption.NO_AGGREGATING;
00223 }
00224 else if(args[i].equals("-grimple"))
00225 produceGrimpleFile = true;
00226 else if(args[i].equals("-grimp"))
00227 produceGrimpFile = true;
00228 else if(args[i].equals("-nocleanup"))
00229 buildBodyOptions |= BuildGrimpBodyOption.NO_CLEANUP;
00230 else if(args[i].equals("-typeless"))
00231 buildBodyOptions |= BuildGrimpBodyOption.NO_TYPING;
00232 else if(args[i].equals("-nolocalpacking"))
00233 buildBodyOptions |= BuildGrimpBodyOption.NO_PACKING;
00234 else if(args[i].equals("-usepackedlive"))
00235 usePackedLive = true;
00236 else if(args[i].equals("-usepackeddefs"))
00237 usePackedDefs = true;
00238 else if(args[i].equals("-testperf"))
00239 {
00240 isProfilingOptimization = true;
00241 isTestingPerformance = true;
00242 }
00243 else if(args[i].equals("-timetransform"))
00244 isProfilingOptimization = true;
00245 else if(args[i].equals("-verbose"))
00246 isVerbose = true;
00247 else if(args[i].equals("-nosplitting"))
00248 buildBodyOptions |= BuildGrimpBodyOption.NO_SPLITTING;
00249 else if(args[i].equals("-oldtyping"))
00250 oldTyping = true;
00251 else if(args[i].equals("-jimpleClassPath"))
00252 { if(++i < args.length)
00253 jimpleClassPath = args[i];
00254 }
00255 else if(args[i].equals("-debug"))
00256 isInDebugMode = true;
00257 else if(args[i].startsWith("-"))
00258 {
00259 System.out.println("Unrecognized option: " + args[i]);
00260 System.exit(0);
00261 }
00262 else
00263 break;
00264
00265 firstNonOption = i + 1;
00266 }
00267
00268
00269 {
00270 int numFailed = 0;
00271 int numSuccess = 0;
00272
00273 List listBodies = new ArrayList();
00274
00275 for(int i = firstNonOption; i < args.length; i++)
00276 {
00277 SootClass c = cm.getClass(args[i]);
00278 String postFix;
00279 PrintWriter writerOut = null;
00280 FileOutputStream streamOut = null;
00281
00282 System.out.print("Jimplifying " + c.getName() + "... " );
00283 System.out.flush();
00284
00285
00286 {
00287 if(produceJasminFile)
00288 postFix = ".jasmin";
00289 else if(produceJimpleFile)
00290 postFix = ".jimple";
00291 else if(produceJimpFile)
00292 postFix = ".jimp";
00293 else if(produceGrimpleFile)
00294 postFix = ".grimple";
00295 else
00296 postFix = ".grimp";
00297
00298 try {
00299 streamOut = new FileOutputStream(c.getName() + postFix);
00300 writerOut = new PrintWriter(streamOut);
00301 }
00302 catch (IOException e)
00303 {
00304 System.out.println("Cannot output file " + c.getName() + postFix);
00305 }
00306 }
00307
00308 if(isProfilingOptimization)
00309 {
00310 Iterator methodIt = c.getMethods().iterator();
00311 long localStmtCount = 0;
00312
00313 try {
00314 while(methodIt.hasNext())
00315 {
00316 SootMethod m = (SootMethod) methodIt.next();
00317 GrimpBody listBody = new GrimpBody(m);
00318
00319 listBodies.add(listBody);
00320 localStmtCount += listBody.getStmtList().size();
00321 }
00322
00323 stmtCount += localStmtCount;
00324
00325 System.out.println(localStmtCount + " stmts ");
00326 numSuccess++;
00327 }
00328 catch(Exception e)
00329 {
00330 System.out.println("failed due to: " + e);
00331 numFailed++;
00332 }
00333 }
00334
00335
00336 {
00337 if(!isInDebugMode)
00338 {
00339 try {
00340 handleClass(c, postFix, writerOut, buildBodyOptions);
00341 }
00342 catch(Exception e)
00343 {
00344 System.out.println("failed due to: " + e);
00345 }
00346 }
00347 else {
00348 handleClass(c, postFix, writerOut, buildBodyOptions);
00349 }
00350 System.out.println("node count: "+
00351 ca.mcgill.sable.soot.jimple.Transformations.nodeCount);
00352 System.out.println("aggregation count: "+
00353 ca.mcgill.sable.soot.jimple.Transformations.aggrCount);
00354
00355 try {
00356 writerOut.flush();
00357 streamOut.close();
00358 }
00359 catch(IOException e )
00360 {
00361 System.out.println("Cannot close output file " + c.getName() + postFix);
00362 }
00363
00364 System.out.println();
00365 }
00366 }
00367
00368 if(isProfilingOptimization)
00369 {
00370 System.out.println("Successfully jimplified " + numSuccess + " classfiles; failed on " + numFailed + ".");
00371
00372
00373 {
00374 Iterator bodyIt = listBodies.iterator();
00375 long storedStmtCount = 0;
00376
00377 while(bodyIt.hasNext())
00378 {
00379 GrimpBody listBody = (GrimpBody) bodyIt.next();
00380 storedStmtCount += listBody.getStmtList().size();
00381 }
00382
00383 System.out.println("Confirmed " + storedStmtCount + " stored statements.");
00384 System.out.println();
00385 }
00386
00387 System.out.println("graphTimer: " + graphTimer.getTime());
00388 System.out.println("defsTimer: " + defsTimer.getTime());
00389 System.out.println("usesTimer: " + usesTimer.getTime());
00390 System.out.println("cleanupAlgorithmTimer: " + cleanupAlgorithmTimer.getTime());
00391 System.out.println("copiesTimer: " + copiesTimer.getTime());
00392 System.out.println("liveTimer: " + liveTimer.getTime());
00393 System.out.println("resolveTimer: " + resolveTimer.getTime());
00394
00395 System.out.println();
00396
00397
00398 {
00399 long conversionTime = conversionTimer.getTime();
00400 long cleanup1Time = cleanup1Timer.getTime();
00401 long splitTime = splitTimer.getTime();
00402 long assignTime = assignTimer.getTime();
00403 long packTime = packTimer.getTime();
00404 long cleanup2Time = cleanup2Timer.getTime();
00405
00406 totalTimer.end();
00407 long totalTime = totalTimer.getTime();
00408 float timeInSecs;
00409
00410 System.out.println("conversionTimer: " + conversionTime +
00411 "(" + (conversionTime * 100 / totalTime) + "%) " +
00412 conversionLocalCount + " locals " + conversionStmtCount + " stmts");
00413 System.out.println("cleanup1Timer: " + cleanup1Time +
00414 "(" + (cleanup1Time * 100 / totalTime) + "%) " +
00415 cleanup1LocalCount + " locals " + cleanup1StmtCount + " stmts");
00416 System.out.println("splitTimer: " + splitTime +
00417 "(" + (splitTime * 100 / totalTime) + "%) " +
00418 splitLocalCount + " locals " + splitStmtCount + " stmts");
00419 System.out.println("assignTimer: " + assignTime +
00420 "(" + (assignTime * 100 / totalTime) + "%) " +
00421 assignLocalCount + " locals " + assignStmtCount + " stmts");
00422 System.out.println("packTimer: " + packTime +
00423 "(" + (packTime * 100 / totalTime) + "%) " +
00424 packLocalCount + " locals " + packStmtCount + " stmts");
00425 System.out.println("cleanup2Timer: " + cleanup2Time +
00426 "(" + (cleanup2Time * 100 / totalTime) + "%) " +
00427 cleanup2LocalCount + " locals " + cleanup2StmtCount + " stmts");
00428
00429 timeInSecs = (float) totalTime / 1000.0f;
00430 float memoryUsed = (float) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000.0f;
00431
00432 System.out.println("stmts created: " + stmtCount);
00433
00434 System.out.println("totalTime:" + timeInSecs + "s " + (float) stmtCount / timeInSecs + " (stmts/sec)");
00435 System.out.println("totalMemory:" + memoryUsed + "k " + (float) memoryUsed / stmtCount+ " (k/stmt)");
00436
00437 }
00438 }
00439 }
00440
00441 }
00442 }