00001 package ca.mcgill.sable.soot.grimp; 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * Grimp, an aggregated-expression Java(TM) bytecode representation. * 00005 * Copyright (C) 1998 Patrick Lam (plam@sable.mcgill.ca) * 00006 * All rights reserved. * 00007 * * 00008 * Modifications by Raja Vallee-Rai (plam@sable.mcgill.ca) are * 00009 * Copyright (C) 1999 Raja Vallee-Rai. All rights reserved. * 00010 * * 00011 * This work was done as a project of the Sable Research Group, * 00012 * School of Computer Science, McGill University, Canada * 00013 * (http://www.sable.mcgill.ca/). It is understood that any * 00014 * modification not identified as such is not covered by the * 00015 * preceding statement. * 00016 * * 00017 * This work is free software; you can redistribute it and/or * 00018 * modify it under the terms of the GNU Library General Public * 00019 * License as published by the Free Software Foundation; either * 00020 * version 2 of the License, or (at your option) any later version. * 00021 * * 00022 * This work is distributed in the hope that it will be useful, * 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00025 * Library General Public License for more details. * 00026 * * 00027 * You should have received a copy of the GNU Library General Public * 00028 * License along with this library; if not, write to the * 00029 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00030 * Boston, MA 02111-1307, USA. * 00031 * * 00032 * Java is a trademark of Sun Microsystems, Inc. * 00033 * * 00034 * To submit a bug report, send a comment, or get the latest news on * 00035 * this project and other Sable Research Group projects, please * 00036 * visit the web site: http://www.sable.mcgill.ca/ * 00037 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00038 00039 /* 00040 Reference Version 00041 ----------------- 00042 This is the latest official version on which this file is based. 00043 The reference version is: $SootVersion: 1.beta.4 $ 00044 00045 Change History 00046 -------------- 00047 A) Notes: 00048 00049 Please use the following template. Most recent changes should 00050 appear at the top of the list. 00051 00052 - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate] 00053 [description of modification]. 00054 00055 Any Modification flagged with "(*)" was done as a project of the 00056 Sable Research Group, School of Computer Science, 00057 McGill University, Canada (http://www.sable.mcgill.ca/). 00058 00059 You should add your copyright, using the following template, at 00060 the top of this file, along with other copyrights. 00061 00062 * * 00063 * Modifications by [name] are * 00064 * Copyright (C) [year(s)] [your name (or company)]. All rights * 00065 * reserved. * 00066 * * 00067 00068 B) Changes: 00069 00070 - Modified on March 1, 1999 by Raja Vallee-Rai (rvalleerai@sable.mcgill.ca) (*) 00071 Renamed method to foldConstructors. 00072 Renamed ConstructExpr to NewInvokeExpr. 00073 00074 - Modified on February 3, 1999 by Patrick Lam (plam@sable.mcgill.ca). (*) 00075 First release of Grimp. 00076 */ 00077 00078 import ca.mcgill.sable.soot.*; 00079 import ca.mcgill.sable.soot.jimple.*; 00080 import ca.mcgill.sable.util.*; 00081 00082 public class GrimpTransformations 00083 { 00084 00085 /* Change all new Obj/<init>(args) pairs to new Obj(args) construction. */ 00086 public static void foldConstructors(GrimpBody body) 00087 { 00088 if(ca.mcgill.sable.soot.jimple.Main.isVerbose) 00089 System.out.println("[" + body.getMethod().getName() + 00090 "] Folding constructors..."); 00091 00092 StmtList stmtList = body.getStmtList(); 00093 00094 00095 CompleteStmtGraph graph = new CompleteStmtGraph(stmtList); 00096 00097 if(Main.isProfilingOptimization) 00098 Main.defsTimer.start(); 00099 00100 LocalDefs localDefs = new SimpleLocalDefs(graph); 00101 00102 if(Main.isProfilingOptimization) 00103 Main.defsTimer.end(); 00104 00105 if(Main.isProfilingOptimization) 00106 Main.usesTimer.start(); 00107 00108 LocalUses localUses = new SimpleLocalUses(graph, localDefs); 00109 00110 if(Main.isProfilingOptimization) 00111 Main.usesTimer.end(); 00112 00113 Iterator stmtIt = stmtList.iterator(); 00114 00115 /* fold in NewExpr's with specialinvoke's */ 00116 while (stmtIt.hasNext()) 00117 { 00118 Stmt s = (Stmt)(stmtIt.next()); 00119 00120 if (!(s instanceof AssignStmt)) 00121 continue; 00122 00123 /* this should be generalized to ArrayRefs */ 00124 Value lhs = ((AssignStmt)s).getLeftOp(); 00125 if (!(lhs instanceof Local)) 00126 continue; 00127 00128 Value rhs = ((AssignStmt)s).getRightOp(); 00129 if (!(rhs instanceof NewExpr)) 00130 continue; 00131 00132 /* TO BE IMPLEMENTED LATER: move any copy of the object reference 00133 for lhs down beyond the NewInvokeExpr, with the rationale 00134 being that you can't modify the object before the constructor 00135 call in any case. 00136 00137 Also, do note that any new's (object creation) without 00138 corresponding constructors must be dead. */ 00139 00140 List lu = localUses.getUsesOf((DefinitionStmt)s); 00141 Iterator luIter = lu.iterator(); 00142 boolean MadeNewInvokeExpr = false; 00143 00144 while (luIter.hasNext()) 00145 { 00146 Stmt use = ((StmtValueBoxPair)(luIter.next())).stmt; 00147 if (!(use instanceof InvokeStmt)) 00148 break; 00149 InvokeStmt is = (InvokeStmt)use; 00150 if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) || 00151 lhs != ((SpecialInvokeExpr)is.getInvokeExpr()).getBase()) 00152 break; 00153 00154 SpecialInvokeExpr oldInvoke = 00155 ((SpecialInvokeExpr)is.getInvokeExpr()); 00156 LinkedList invokeArgs = new LinkedList(); 00157 for (int i = 0; i < oldInvoke.getArgCount(); i++) 00158 invokeArgs.add(oldInvoke.getArg(i)); 00159 00160 AssignStmt constructStmt = Grimp.v().newAssignStmt 00161 ((AssignStmt)s); 00162 constructStmt.setRightOp 00163 (Grimp.v().newNewInvokeExpr 00164 (((NewExpr)rhs).getBaseType(), oldInvoke.getMethod(), invokeArgs)); 00165 MadeNewInvokeExpr = true; 00166 00167 body.redirectJumps(use, constructStmt); 00168 body.eliminateBackPointersTo(use); 00169 stmtList.add(stmtList.indexOf(use), constructStmt); 00170 stmtList.remove(use); 00171 } 00172 if (MadeNewInvokeExpr) 00173 { 00174 body.eliminateBackPointersTo(s); 00175 stmtIt.remove(); 00176 } 00177 } 00178 } 00179 }