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

PreProcess.java

00001 package edu.ksu.cis.bandera.pdgslicer;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   Hongjun Zheng (zheng@cis.ksu.edu)      *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 
00036 import ca.mcgill.sable.util.*;
00037 import ca.mcgill.sable.soot.*;
00038 import ca.mcgill.sable.soot.jimple.*;
00039 import edu.ksu.cis.bandera.pdgslicer.datastructure.*;
00040 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00041 import java.io.*;
00042 import java.util.BitSet;
00043 import java.util.Vector;
00044 import java.util.Enumeration;
00045 /**
00046  * This class is for extracting and building up slice
00047  * criterion of each class and method.
00048  */
00049 public class PreProcess {
00050   /**
00051    * A list of {@link ClassInfo ClassInfo}.
00052    */
00053     private List classInfoList;
00054   /**
00055    * A map from {@link SootMethod SootMethod} to {@link SliceCriterion SliceCriterion} 
00056    * for storing slice criterion of each method.
00057    */
00058     private Map methodCritMap = new HashMap();
00059     private boolean emptySliceCriterion = false;
00060   /**
00061    * A set of {@link Local Local}.
00062    */
00063     private Set sliceLocalSet = new ArraySet();
00064 /**
00065  * @param clsList a list of {@link ClassInfo ClassInfo}. 
00066  */
00067 public PreProcess(List clsList) {
00068     classInfoList = clsList;
00069 }
00070 /**
00071  * See if slice criterion is empty.
00072  * <p>
00073  * @return {@link #emptySliceCriterion emptySliceCriterion}.
00074  */
00075 boolean emptySliceCriterion() {
00076     return emptySliceCriterion;
00077 }
00078 /**
00079  * Extract slice criterion from a set of slice interests.
00080  * <br> Put those slice criterion into {@link #methodCritMap methodCritMap}.
00081  * <p>
00082  * @param sliceInterests a set of {@link SliceInterest SliceInterest}.
00083  */
00084 public void extracting(Vector sliceInterests) {
00085     for (Enumeration e = sliceInterests.elements(); e.hasMoreElements();) {
00086         SliceInterest sliceInterest = (SliceInterest) e.nextElement();
00087         if (sliceInterest instanceof SliceLocal) {
00088             SliceLocal sliceLocal = (SliceLocal) sliceInterest;
00089             sliceLocalSet.add(sliceLocal.getLocal());
00090         }
00091     }
00092     for (Enumeration e = sliceInterests.elements(); e.hasMoreElements();) {
00093         SliceInterest sliceInterest = (SliceInterest) e.nextElement();
00094         if (sliceInterest instanceof SliceLocal) {
00095             SliceLocal sliceLocal = (SliceLocal) sliceInterest;
00096             putLocalToCritMap(sliceLocal.getSootMethod(), sliceLocal.getLocal());
00097         } else
00098             if (sliceInterest instanceof SliceStatement) {
00099                 SliceStatement sliceStatement = (SliceStatement) sliceInterest;
00100                 putStatementToCritMap(sliceStatement.getSootMethod(), sliceStatement.getStmt());
00101             } else
00102                 if (sliceInterest instanceof SlicePoint) {
00103                     SlicePoint slicePoint = (SlicePoint) sliceInterest;
00104                     putPointToCritMap(slicePoint.getSootMethod(), slicePoint.getStmt());
00105                 } else
00106                     if (sliceInterest instanceof SliceField) {
00107                         SliceField sliceField = (SliceField) sliceInterest;
00108                         putFieldToCritMap(sliceField.getSootClass(), sliceField.getSootField());
00109                     }
00110     }
00111     putMdCritMapToMdInfo();
00112 }
00113     /**
00114      * Extract slice criterion for deadlock checking.
00115      * <br> First get slice interest for deadlock checking from class
00116      * {@link DeadlockRelatedCriterion DeadlockRelatedCriterion}. 
00117      * Then extract slice criterion from those slice interest by method
00118      * {@link #extracting(Vector) extracting(sliceInterests)}.
00119      */
00120 public void extractingForDL(SootClass[] classes) {
00121     DeadlockRelatedCriterion dlCrit = new DeadlockRelatedCriterion(classes);
00122     Vector sliceInterestForDL = dlCrit.getSliceInterestForDL();
00123     if (sliceInterestForDL.isEmpty())
00124         emptySliceCriterion = true;
00125     else
00126         extracting(sliceInterestForDL);
00127 }
00128 /**
00129  * Extract relevant variable map from slice criterion.
00130  * <p>
00131  * @return relevant variable map from {@link Stmt Stmt}
00132  * to a {@link Set Set} of {@link Value Value}. 
00133  * @param sc slice criterion.
00134  */
00135 static Map extractRelVarMapFromCriterion(SliceCriterion sc) {
00136     Map relVarMap = new HashMap();
00137     Set slicePoints = sc.getSlicePoints();
00138     Set sliceVars = sc.getSliceVars();
00139     Set variables = new ArraySet();
00140     variables.addAll(sliceVars);
00141     Set sliceStatements = sc.getSliceStatements();
00142     for (Iterator stmtIt = sliceStatements.iterator(); stmtIt.hasNext();) {
00143         Stmt stmt = (Stmt) stmtIt.next();
00144         for (Iterator useBoxIt = stmt.getUseBoxes().iterator(); useBoxIt.hasNext();) {
00145             ValueBox valueBox = (ValueBox) useBoxIt.next();
00146             Value value = valueBox.getValue();
00147             if ((value instanceof Local) || (value instanceof FieldRef))
00148                 variables.add(value);
00149         }
00150     }
00151     for (Iterator pointIt = slicePoints.iterator(); pointIt.hasNext();)
00152         relVarMap.put((Stmt) pointIt.next(), variables);
00153     for (Iterator stmtIt = sliceStatements.iterator(); stmtIt.hasNext();) {
00154         Stmt stmt = (Stmt) stmtIt.next();
00155         if (relVarMap.containsKey(stmt))
00156             continue;
00157         relVarMap.put(stmt, variables);
00158     }
00159     return relVarMap;
00160 }
00161 /**
00162  * Get all instance field references for a given field 
00163  * which is assigned value by some assigment statement.
00164  * <p>
00165  * @return a set of {@link FieldRef FieldRef} which is 
00166  * an instance field reference of a given 
00167  * <code>sootField</code>.
00168  * @param localAssMap a map of local to its assignments.
00169  * @param sootField query sootfield.
00170  */
00171 private Set getInstanceFieldRef(Map localAssMap, SootField sootField) {
00172     Set returnSet = new ArraySet();
00173     for (Iterator localIt = localAssMap.keySet().iterator(); localIt.hasNext();) {
00174         Value defVar = (Value) localIt.next();
00175         if (!(defVar instanceof InstanceFieldRef))
00176             continue;
00177         InstanceFieldRef defInsRef = (InstanceFieldRef) defVar;
00178         SootField insFd = defInsRef.getField();
00179         Value baseValue = defInsRef.getBase();
00180         if (baseValue instanceof Local) {
00181             Local baseLocal = (Local) baseValue;
00182             if (insFd.equals(sootField))// && sliceLocalSet.contains(baseLocal))
00183                 //return defInsRef;
00184                 returnSet.add(defInsRef);
00185         }
00186     }
00187     return returnSet;
00188 }
00189 /**
00190  * Get all static field references for a given field 
00191  * which is assigned value by some assigment statement.
00192  * <p>
00193  * @return a set of {@link FieldRef FieldRef} which is 
00194  * a static field reference of a given 
00195  * <code>staticField</code>.
00196  * @param localAssMap a map of local to its assignments.
00197  * @param staticField query sootfield.
00198  */
00199 private Set getStaticFieldRef(Map localAssMap, SootField staticField) {
00200     Set returnSet = new ArraySet();
00201     for (Iterator localIt = localAssMap.keySet().iterator(); localIt.hasNext();) {
00202         Object definedVar = localIt.next();
00203         if (definedVar instanceof StaticFieldRef) {
00204             StaticFieldRef sfr = (StaticFieldRef) definedVar;
00205             SootField definedFd = sfr.getField();
00206             if (staticField.equals(definedFd)) {
00207                 returnSet.add(sfr);
00208             }
00209         }
00210     }
00211     return returnSet;
00212 }
00213 /**
00214  * Put field into {@link #methodCritMap methodCritMap}. It's including:
00215  * <br> (1) {@link #putStaticFieldToCritMap(SootClass, SootField)
00216  * putSTaticfieldToCritMap()}
00217  * <br> (2) {@link #putPrivateInsFdToCritMap(SootClass, SootField)
00218  * putPrivateInsFdToCritMap()}
00219  * <br> (3) {@link #putPubInstanceFdToCritMap(SootClass, SootField)
00220  * putPubInstanceFdToCritMap()}
00221  * <p>
00222  * @param sootClass the class where <code>field</code> is declared.
00223  * @param field the field need to be added into criterion map.
00224  */
00225 private void putFieldToCritMap(SootClass sootClass, SootField field) {
00226     int modifiers = field.getModifiers();
00227     if (Modifier.isStatic(modifiers))
00228         putStaticFieldToCritMap(sootClass, field);
00229     else
00230         if (Modifier.isPrivate(modifiers))
00231             putPrivateInsFdToCritMap(sootClass, field);
00232         else { //if (Modifier.isPublic(modifiers))
00233             System.out.println("now, we treat fields rather than static and private as public simply, need further programming on protected fields");
00234             putPubInstanceFdToCritMap(sootClass, field);
00235         }
00236 
00237         //else if (Modifier.isProtected(modifiers))
00238 
00239 }
00240 /**
00241  * Put field reference into {@link #methodCritMap methodCritMap}.
00242  * <br> A field reference is a variable, so the <code>field</code>
00243  * should be added into the set of slice variable in the slice criterion
00244  * of the given method. Slice criterion
00245  * consists of slice points set and slice variable set.
00246  * <p>
00247  * @param sootMethod the method where the <code>field</code> is referenced.
00248  * @param field the field need to be added.
00249  */
00250 private void putFieldToCritMap(SootMethod sootMethod, FieldRef field) {
00251     if (methodCritMap.containsKey(sootMethod)) {
00252         SliceCriterion criterion = (SliceCriterion) methodCritMap.get(sootMethod);
00253         criterion.getSliceVars().add(field);
00254     } else {
00255         Set varSet = new ArraySet();
00256         varSet.add(field);
00257         methodCritMap.put(sootMethod, new SliceCriterion(new ArraySet(), varSet, new ArraySet()));
00258     }
00259 }
00260 /**
00261  * Put a local variable into {@link #methodCritMap methodCritMap}.
00262  * <br> A local is a variable, so the <code>local</code>
00263  * should be added into the set of slice variable in the slice criterion
00264  * of the given method. Slice criterion
00265  * consists of slice points set and slice variable set.
00266  * <p>
00267  * @param sootMethod the method where the <code>local</code> is referenced.
00268  * @param local the local need to be added.
00269  */
00270 private void putLocalToCritMap(SootMethod sootMethod, Local local) {
00271     if (methodCritMap.containsKey(sootMethod)) {
00272         SliceCriterion criterion = (SliceCriterion) methodCritMap.get(sootMethod);
00273         criterion.getSliceVars().add(local);
00274     } else {
00275         Set varSet = new ArraySet();
00276         varSet.add(local);
00277         methodCritMap.put(sootMethod, new SliceCriterion(new ArraySet(), varSet, new ArraySet()));
00278     }
00279 }
00280 /**
00281  * Set value for the field <code>sCriterion</code> of 
00282  * {@link MethodInfo MethodInfo} of each method by 
00283  * {@link #methodCritMap methodCritMap}.
00284  */
00285 private void putMdCritMapToMdInfo() {
00286     for (Iterator keyIt = methodCritMap.keySet().iterator(); keyIt.hasNext();) {
00287         SootMethod sootMethod = (SootMethod) keyIt.next();
00288         /*
00289         System.out.println("sootMethod hashCode: " + sootMethod+"  " +sootMethod.hashCode());
00290         for (Iterator mdIt = Slicer.sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00291             System.out.println();
00292             System.out.println("sm hashCode: " + mdIt.next()+"  "+ mdIt.next().hashCode());
00293         }*/
00294         MethodInfo mdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00295         if (mdInfo == null) continue;
00296         mdInfo.sCriterion = (SliceCriterion) methodCritMap.get(sootMethod);
00297         Map relVarMap = extractRelVarMapFromCriterion(mdInfo.sCriterion);
00298         mdInfo.sCriterion.setRelVarMap(relVarMap);
00299     }
00300 }
00301 /**
00302  * Put a statement into {@link #methodCritMap methodCritMap}.
00303  * <br> A statement is a slice point, so the <code>point</code>
00304  * should be added into the set of slice points in the slice criterion
00305  * of the given method. Slice criterion
00306  * consists of slice points set and slice variable set.
00307  * <p>
00308  * @param sootMethod the method where the <code>point</code> is.
00309  * @param point the statement need to be added into slice criterion.
00310  */
00311 private void putPointToCritMap(SootMethod sootMethod, Stmt point) {
00312     if (methodCritMap.containsKey(sootMethod)) {
00313         SliceCriterion criterion = (SliceCriterion) methodCritMap.get(sootMethod);
00314         criterion.getSlicePoints().add(point);
00315     } else {
00316         Set pointSet = new ArraySet();
00317         pointSet.add(point);
00318         methodCritMap.put(sootMethod, new SliceCriterion(pointSet, new ArraySet(), new ArraySet()));
00319     }
00320 }
00321 /**
00322  * @param sootClass class where the <code>field</code> is declared.
00323  * @param field the field need to be added into slice criterion.
00324  */
00325 private void putPrivateInsFdToCritMap(SootClass sootClass, SootField field) {
00326     for (Iterator classIt = classInfoList.iterator(); classIt.hasNext();) {
00327         ClassInfo classInfo = (ClassInfo) classIt.next();
00328         if (!classInfo.sootClass.equals(sootClass))
00329             continue;
00330         for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
00331             MethodInfo mdInfo = (MethodInfo) mdIt.next();
00332             Set fieldRefs = getInstanceFieldRef(mdInfo.indexMaps.localAssMap(), field);
00333             for (Iterator refIt = fieldRefs.iterator(); refIt.hasNext();){
00334                 FieldRef fieldRef = (FieldRef) refIt.next();
00335                 putFieldToCritMap(mdInfo.sootMethod, fieldRef);
00336             }
00337         }
00338     }
00339 }
00340 /**
00341  * @param sootClass class where the <code>field</code> is declared.
00342  * @param field the field need to be added into slice criterion.
00343  */
00344 private void putPubInstanceFdToCritMap(SootClass sootClass, SootField field) {
00345     for (Iterator classIt = classInfoList.iterator(); classIt.hasNext();) {
00346         ClassInfo classInfo = (ClassInfo) classIt.next();
00347         for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
00348             MethodInfo mdInfo = (MethodInfo) mdIt.next();
00349             Set fieldRefs = getInstanceFieldRef(mdInfo.indexMaps.localAssMap(), field);
00350             for (Iterator refIt = fieldRefs.iterator(); refIt.hasNext();)
00351                 {
00352                 FieldRef fieldRef = (FieldRef) refIt.next();
00353                 putFieldToCritMap(mdInfo.sootMethod, fieldRef);
00354                 }
00355         }
00356     }
00357 }
00358 /**
00359  * Put a statement into {@link #methodCritMap methodCritMap}.
00360  * <br> A statement is a slice point, so the <code>point</code>
00361  * should be added into the set of slice points in the slice criterion
00362  * of the given method. Slice criterion
00363  * consists of slice points set and slice variable set.
00364  * <p>
00365  * @param sootMethod the method where the <code>point</code> is.
00366  * @param point the statement need to be added into slice criterion.
00367  */
00368 private void putStatementToCritMap(SootMethod sootMethod, Stmt stmt) {
00369     if (methodCritMap.containsKey(sootMethod)) {
00370         SliceCriterion criterion = (SliceCriterion) methodCritMap.get(sootMethod);
00371         criterion.getSliceStatements().add(stmt);
00372     } else {
00373         Set stmtSet = new ArraySet();
00374         stmtSet.add(stmt);
00375         methodCritMap.put(sootMethod, new SliceCriterion(new ArraySet(), new ArraySet(), stmtSet));
00376     }
00377 }
00378 /**
00379  * @param sootClass class where <code>staticField</code> is declared.
00380  * @param field the field need to be added into slice criterion.
00381  */
00382 private void putStaticFieldToCritMap(SootClass sootClass, SootField staticField) {
00383     for (Iterator classIt = classInfoList.iterator(); classIt.hasNext();) {
00384         ClassInfo classInfo = (ClassInfo) classIt.next();
00385         for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
00386             MethodInfo mdInfo = (MethodInfo) mdIt.next();
00387             Set staticFdRefs = getStaticFieldRef(mdInfo.indexMaps.localAssMap(), staticField);
00388             for (Iterator refIt = staticFdRefs.iterator(); refIt.hasNext();){
00389                 FieldRef staticFdRef = (FieldRef) refIt.next();
00390                 putFieldToCritMap(mdInfo.sootMethod, staticFdRef);
00391 }
00392         }
00393     }
00394 }
00395 }

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