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

SlicingMethod.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 
00037 //if (!(nodeStmt instanceof InvokeStmt))
00038 //add this condition on 10/19/99  in slicingMethod() and
00039 //slicingMethodAgain()
00040 
00041 
00042 import ca.mcgill.sable.util.*;
00043 import ca.mcgill.sable.soot.*;
00044 import ca.mcgill.sable.soot.jimple.*;
00045 import edu.ksu.cis.bandera.jjjc.CompilationManager;
00046 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00047 import java.util.BitSet;
00048 import java.util.Hashtable;
00049 //import java.util.HashSet;
00050 /**
00051  * This class is for slicing one method
00052  */
00053 public class SlicingMethod {
00054     private StmtList stmtList;
00055     private int stmtListSize;
00056     private IndexMaps indexMaps;
00057     MethodInfo methodInfo;
00058     static boolean criterionChanged;
00059   /**
00060    * A {@link Set Set} of {@link MethodInfo MethodInfo} such that some 
00061    * statement in other method ready dependent on one statement in the method
00062    */
00063     private Set originalMethodsFromReady = new ArraySet();
00064   /*
00065    * A {@link Set Set} of {@link MethodInfo MethodInfo} such that contains
00066    * <code>wait</code> statement.
00067    */
00068   //static Set originalMdsFromReadyCallSite;
00069   /**
00070    * A {@link Set Set} of {@link CallSite CallSite} which has been generated slice
00071    * criterion because of ready call site.
00072    */
00073     static Set alreadyGenCritByReadyCallSite;
00074     //static Set alreadyGenerateCriterionByWhoCallMe = new ArraySet();
00075   /**
00076    * A {@link Set Set} of {@link MethodInfo MethodInfo} such that has been generated
00077    * slice criterion for exit of the method.
00078    */
00079     static Set alreadyGenerateCriterionForExits;
00080   /**
00081    * @param mdInfo method to be sliced.
00082    */
00083 public SlicingMethod(MethodInfo mdInfo) {
00084     methodInfo = mdInfo;
00085     stmtList = methodInfo.originalStmtList;
00086     stmtListSize = stmtList.size();
00087     indexMaps = methodInfo.indexMaps;
00088 }
00089 private void addCalledMdToWorkList(MethodInfo targetMdInfo, LinkedList workList, Set calculated) {
00090     Map callSiteMap = targetMdInfo.indexMaps.getCallSiteMap();
00091     Set calledMdsInfo = new ArraySet();
00092     for (Iterator calledIt = callSiteMap.values().iterator(); calledIt.hasNext();) {
00093         SootMethod sootMethod = (SootMethod) calledIt.next();
00094         MethodInfo calledMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00095         if (!calculated.contains(calledMdInfo))
00096             calledMdsInfo.add(calledMdInfo);
00097     }
00098     if (!calledMdsInfo.isEmpty())
00099         workList.addAll(workList.size(), calledMdsInfo);
00100 }
00101   /*
00102    * Add all called methods in a given method into a work list.
00103    * <p>
00104    * @param targetMdInfo method to be analysed.
00105    * @param workList a list of {@link MethodInfo MethodInfo} which is called
00106    * in <code>targetMdInfo</code>.
00107    * @param calculated a set of {@link MethodInfo MethodInfo} which is already calculated.
00108    */
00109   /*
00110 private void addCalledMdToWorkList(MethodInfo targetMdInfo, LinkedList workList, Set calculated) {
00111     Map callSiteMap = targetMdInfo.indexMaps.getCallSiteMap();
00112     Set calledMdsInfo = new ArraySet();
00113     for (Iterator calledIt = callSiteMap.values().iterator(); calledIt.hasNext();) {
00114         SootMethod sootMethod = (SootMethod) calledIt.next();
00115         MethodInfo calledMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00116         if (calledMdInfo == null) continue;
00117         if (!calculated.contains(calledMdInfo))
00118             calledMdsInfo.add(calledMdInfo);
00119     }
00120     if (!calledMdsInfo.isEmpty())
00121         workList.addAll(workList.size(), calledMdsInfo);
00122 }
00123   */
00124   /*
00125 private void addCallersMdToWorkList(MethodInfo targetMdInfo, LinkedList workList, Set calculated) {
00126     Set callSites = targetMdInfo.whoCallMe;
00127     if (callSites==null) return;
00128     Set callerMdsInfo = new ArraySet();
00129     for (Iterator callerIt = callSites.iterator(); callerIt.hasNext();) {
00130       CallSite callsite = (CallSite) callerIt.next();
00131         SootMethod sootMethod = callsite.callerSootMethod;
00132         MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00133         if (callerMdInfo == null) continue;
00134         if (!calculated.contains(callerMdInfo))
00135             callerMdsInfo.add(callerMdInfo);
00136     }
00137     if (!callerMdsInfo.isEmpty())
00138         workList.addAll(workList.size(), callerMdsInfo);
00139 }
00140   */
00141 
00142 private void addToSliceTrace(Set stmtSet, Set callSites, Integer kind, MethodInfo mdin) {
00143     Set traceNodeSet = getTraceNodeSetFrom(stmtSet, mdin);
00144     if (traceNodeSet.isEmpty())
00145         addToSliceTrace(Slicer.sliceTraceRoot, callSites, kind, mdin);
00146     else {
00147         for (Iterator nodeIt = traceNodeSet.iterator(); nodeIt.hasNext();) {
00148             SliceTraceNode stn = (SliceTraceNode) nodeIt.next();
00149             addToSliceTrace(stn, callSites, kind, mdin);
00150         }
00151     }
00152 }
00153 private void addToSliceTrace(Set stmtSet, BitSet assgnSet, Integer kind, MethodInfo mdin) {
00154     Set traceNodeSet = getTraceNodeSetFrom(stmtSet, mdin);
00155     if (traceNodeSet.isEmpty())
00156         addToSliceTrace(Slicer.sliceTraceRoot, assgnSet, kind, mdin);
00157     else {
00158         for (Iterator nodeIt = traceNodeSet.iterator(); nodeIt.hasNext();) {
00159             SliceTraceNode stn = (SliceTraceNode) nodeIt.next();
00160             addToSliceTrace(stn, assgnSet, kind, mdin);
00161         }
00162     }
00163 }
00164 private void addToSliceTrace(SliceTraceNode stn, Stmt stmt, Integer kind, MethodInfo mdin) {
00165     SliceTraceNode traceNode = new SliceTraceNode(mdin, stmt);
00166     /*
00167     if (traceNode.stmtAnnotation.toString().equals("")) {
00168         System.out.println("stmt: " + stmt +" 's annotation hashcode : " + traceNode.stmtAnnotation.hashCode());
00169         return;
00170         }
00171         */
00172     SliceTraceNode containNode = sliceTraceContains(traceNode);
00173     if (containNode == null) {
00174         stn.add(traceNode, kind);
00175         Slicer.allSliceTraceNodes.add(traceNode);
00176         return;
00177     }
00178     if (stn.equals(containNode) || stn.isChild(containNode))
00179         return;
00180     stn.add(containNode, kind);
00181 }
00182 private void addToSliceTrace(SliceTraceNode stn, LinkedList stmts, Integer kind, MethodInfo mdin) {
00183     for (Iterator stmtIt = stmts.iterator(); stmtIt.hasNext();) {
00184         Stmt stmt = (Stmt) stmtIt.next();
00185         addToSliceTrace(stn, stmt, kind, mdin);
00186     }
00187 }
00188 private void addToSliceTrace(SliceTraceNode stn, Set stmtSet, Integer kind, MethodInfo mdin) {
00189     for (Iterator stmtIt = stmtSet.iterator(); stmtIt.hasNext();) {
00190         Stmt stmt = (Stmt) stmtIt.next();
00191         addToSliceTrace(stn, stmt, kind, mdin);
00192     }
00193 }
00194 private void addToSliceTrace(SliceTraceNode stn, BitSet stmtBitSet, Integer kind, MethodInfo mdin) {
00195     Set stmtSet = SetUtil.bitSetToStmtSet(stmtBitSet, stmtList);
00196     addToSliceTrace(stn, stmtSet, kind, mdin);
00197 }
00198   /**
00199    * Add a set of statements into a work list.
00200    * <p>
00201    * @param wkList work list.
00202    * @param nodes a set of statements.
00203    * @param calculatedNodes a set of statements which should not be added into the 
00204    * work list.
00205    */
00206 private void addToWorkList(LinkedList wkList, BitSet nodes, Set calculatedNodes) {
00207     for (int i = 0; i < nodes.size(); i++) {
00208         if (nodes.get(i)) {
00209             Stmt nodeStmt = (Stmt) stmtList.get(i);
00210             if (!wkList.contains(nodeStmt) && !calculatedNodes.contains(nodeStmt))
00211                 wkList.addLast(nodeStmt);
00212         }
00213     }
00214 }
00215   /**
00216    * Get all local variables in one statement.
00217    * <p>
00218    * @param stmt query statement.
00219    * @return a set of {@link Value Value}.
00220    */
00221 static Set allLocalVarsOf(Stmt stmt) {
00222     Set buff = refVarsOf(stmt);
00223     buff.addAll(defVarsOf(stmt));
00224     return buff;
00225 }
00226   /**
00227    * Get all MOD and REF fields from given sets.
00228    * <p>
00229    * @param modField a set of {@link Value Value} which is in MOD set.
00230    * @param refField a set of {@link Value Value} which is in REF set.
00231    * @return a set of {@link Value Value}.
00232    */
00233 static Set allMODREFFields(Set modFields, Set refFields) {
00234     Set fields = new ArraySet();
00235     for (Iterator fdIt = modFields.iterator(); fdIt.hasNext();) {
00236         DataBox dbx = (DataBox) fdIt.next();
00237         fields.addAll(dbx.getInterferVars());
00238     }
00239     for (Iterator fdIt = refFields.iterator(); fdIt.hasNext();) {
00240         DataBox dbx = (DataBox) fdIt.next();
00241         fields.addAll(dbx.getInterferVars());
00242     }
00243     return fields;
00244 }
00245   /**
00246    * Get all assignments to a list of varibles.
00247    * <p>
00248    * @param varList a list variables.
00249    * @param locAssMap a map from local to assignment, 
00250    * see {@link IndexMaps#locAssIndex IndexMaps.locAssIndex}.
00251    * @param relVarMap relevant variable map, 
00252    * see {@link SliceCriterion#relVarMap SliceCriterion.relVarMap}.
00253    * @return a set of assignments.
00254    */
00255 private BitSet assToRelVars(Set varList, Map locAssMap, Map relVarMap) {
00256     BitSet initSet = new BitSet(stmtListSize);
00257     for (Iterator varIt = varList.iterator(); varIt.hasNext();) {
00258         Object var =  varIt.next();
00259         if (locAssMap.containsKey(var)) {
00260             BitSet assToVar = (BitSet) locAssMap.get(var);
00261             initSet.or(assToVar);
00262             putToRelVarMap(var, assToVar, relVarMap);
00263         }
00264     }
00265     return initSet;
00266 }
00267   /**
00268    * Get all assignments to a list of varibles without considering 
00269    * relevant variables.
00270    * <p>
00271    * @param varList a list variables.
00272    * @param locAssMap a map from local to assignment, 
00273    * see {@link IndexMaps#locAssIndex IndexMaps.locAssIndex}.
00274    * @return a set of assignments.
00275    */
00276 private  BitSet assToVarsNoRelVars(int stmtListSize, List varList, Map locAssMap) {
00277     BitSet initSet = new BitSet(stmtListSize);
00278     for (Iterator varIt = varList.iterator(); varIt.hasNext();) {
00279         Object var =  varIt.next();
00280         if (locAssMap.containsKey(var)) {
00281             BitSet assToVar = (BitSet) locAssMap.get(var);
00282             initSet.or(assToVar);
00283         }
00284     }
00285     return initSet;
00286 }
00287 /**
00288  * Insert the method's description here.
00289  * Creation date: (00-10-20 19:24:31)
00290  */
00291 private boolean callerIsRelevant(CallSite callSite) {
00292     Map methodInfoMap = Slicer.sootMethodInfoMap;
00293     for (Iterator mdIt = methodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00294         SootMethod sm = (SootMethod) mdIt.next();
00295         MethodInfo callerMdInfo = (MethodInfo) methodInfoMap.get(sm);
00296         if (callerMdInfo == null)
00297             continue;
00298         BitSet callerSliceSet = callerMdInfo.sliceSet;
00299         if (callerSliceSet == null)
00300             continue;
00301         StmtList callerStmtList = callerMdInfo.originalStmtList;
00302         //Map callerRelevantMap = callerMdInfo.sCriterion.relVarMap();
00303         Value callerBaseValue = callSite.baseValue;
00304         if (callerBaseValue != null) {
00305             Set relVarsInCaller = PostProcess.getAllVarsOf(callerStmtList, callerSliceSet);
00306             if (relVarsInCaller.contains(callerBaseValue))
00307                 return true;
00308             else
00309                 continue;
00310         }
00311     }
00312     return false;
00313 }
00314   /*
00315 private boolean callerIsRelevant(CallSite callSite, MethodInfo callerMdInfo)
00316     {
00317       BitSet callerSliceSet = callerMdInfo.sliceSet;
00318       if (callerSliceSet == null) return false;
00319       StmtList callerStmtList = callerMdInfo.originalStmtList;
00320       Map callerRelevantMap = callerMdInfo.sCriterion.relVarMap();
00321 
00322       Value callerBaseValue = callSite.baseValue;
00323       if (callerBaseValue!=null)
00324     {
00325       Set relVarsInCaller = PostProcess.getRelevantLocals(callerStmtList,callerSliceSet, callerRelevantMap);
00326       if (relVarsInCaller.contains(callerBaseValue)) return true;
00327       else return false;
00328     }
00329       return false;
00330     }
00331   */
00332   /**
00333    * Get call sites indexed by call statements.
00334    * <p>
00335    * @param callSiteMap call site map,
00336    * see {@link IndexMaps#callSiteMap IndexMaps.callSiteMap}.
00337    * @return a map from {@link Stmt Stmt} to {@link CallSite CallSite}.
00338    */
00339 static Map callSiteIndex(Map callSiteMap) {
00340     Map indexMap = new HashMap();
00341     for (Iterator keyIt = callSiteMap.keySet().iterator(); keyIt.hasNext();) {
00342     CallSite callSite = (CallSite) keyIt.next();
00343         indexMap.put(callSite.callStmt, callSite);
00344     }
00345     return indexMap;
00346 }
00347   /**
00348    * Get all call site in a set of statements.
00349    * <p>
00350    * @param callSiteIndexMap a map from {@link Stmt Stmt} to {@link CallSite CallSite}.
00351    * @param sliceSet a set of statement.
00352    * @return a list of {@link CallSite CallSite}.
00353    */
00354 private List callSiteInSlice(Map callSiteIndexMap, BitSet sliceSet) {
00355     List calls = new ArrayList();
00356     Set callSiteStmtSet = callSiteIndexMap.keySet();
00357     for (int i = 0; i < sliceSet.size(); i++) {
00358         if (!sliceSet.get(i))
00359             continue;
00360         Stmt stmt = (Stmt) stmtList.get(i);
00361         if (callSiteStmtSet.contains(stmt)) {
00362             CallSite callSite = (CallSite) callSiteIndexMap.get(stmt);
00363             calls.add(callSite);
00364         }
00365     }
00366     return calls;
00367 }
00368   /**
00369    * Collect call site statement from a set of {@link CallSite CallSite}.
00370    * <p>
00371    * @param readyCallSites a set of {@link CallSite CallSite}.
00372    * @return a set of statement corresponding to those call site.
00373    */
00374 private Set collectCallSitesFrom(Set readyCallSites)
00375     {
00376       Set callSites = new ArraySet();
00377 for (Iterator siteIt = readyCallSites.iterator(); siteIt.hasNext();)
00378   {
00379     CallSite site = (CallSite) siteIt.next();
00380     callSites.add(site.callStmt);
00381   }
00382 return callSites;
00383     }
00384   /**
00385    * Collect all methods where call sites are.
00386    * <p>
00387    * @param readyCallSites a set of {@link CallSite CallSite}.
00388    * @return a set of {@link MethodInfo MethodInfo}.
00389    */
00390 private Set collectCallSitesMdInfoFrom(Set readyCallSites)
00391     {      Set callSitesMd = new ArraySet();
00392 for (Iterator siteIt = readyCallSites.iterator(); siteIt.hasNext();)
00393   {
00394     CallSite site = (CallSite) siteIt.next();
00395     MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(site.callerSootMethod);
00396     if (callerMdInfo == null) continue;
00397     callSitesMd.add(callerMdInfo);
00398   }
00399 return callSitesMd;
00400     }
00401   /**
00402    * Compute relevant variables for control dependence. 
00403    * <br> Put all used variables of control statement into relevant variables.
00404    * <p>
00405    * @param relVars relevant variables map.
00406    * @param nodeControled statement that is controlled by <code>cdNodes</code>.
00407    * @param cdNodes a set of control statement.
00408    */
00409 private void ctrlRelVarCompute(Map relVars, Stmt nodeControled, BitSet cdNodes) {
00410     for (int i = 0; i < cdNodes.size(); i++) {
00411         if (!cdNodes.get(i))
00412             continue;
00413         Set relVarsOfNodeCd = (Set) relVars.get(nodeControled);
00414 
00415         //get reference variables of controlNode
00416         Stmt controlNode = (Stmt) stmtList.get(i);
00417         Set refsOfNode = refVarsOf(controlNode);
00418         CallSite site = isCallSite(indexMaps.getCallSiteMap(), controlNode);
00419         if (site != null) {
00420             //add the base of the invokation to the relevant variable set
00421             refsOfNode = new ArraySet();
00422             Value base = getBaseFrom(site);
00423             if (base != null)
00424                 refsOfNode.add(base);
00425         }
00426         //get relevant variables of controlNdoe --- set union
00427         refsOfNode.addAll(relVarsOfNodeCd);
00428 
00429         //put relevant set of control node to the relevant varible map
00430         relVars.put(controlNode, refsOfNode);
00431     }
00432 }
00433   /**
00434    * Compute relevant variables for data dependence.
00435    * <p>
00436    * @param relVars relevant variables map.
00437    * @param refNode statement that is data dependent on <code>dd</code>.
00438    * @param dd a set of {@link DataBox DataBox} on which <code>refNode</code>
00439    * is data dependent.
00440    * @return a set of {@link DataBox DataBox} on which <code>refNode</code>
00441    * is data dependent with considering relevant variables.
00442    */
00443 private Set dataRelVarCompute(Map relVars, Stmt refNode, Set dd) {
00444     Set workSet = new ArraySet();
00445     Set defVarsOfRefNode = defVarsOf(refNode);
00446     Set refVarsInRefNode = refVarsOf(refNode);
00447     //varsInRefNode.addAll(defVarsOfRefNode);
00448     Set relVarsOfRefNode = (Set) relVars.get(refNode);
00449     CallSite callsite = isCallSite(indexMaps.getCallSiteMap(), refNode);
00450     if (callsite == null) {
00451         if (!relVarsOfRefNode.containsAll(refVarsInRefNode))
00452             return workSet;
00453         for (Iterator i = dd.iterator(); i.hasNext();) {
00454             DataBox defNode = (DataBox) i.next();
00455             Set dataDependVars = defNode.getDependVar();
00456             Stmt defNodeStmt = defNode.getStmt();
00457             workSet.add(defNode);
00458 
00459             //get reference variables of definition Node
00460             Set refsOfNode = refVarsOf(defNodeStmt);
00461 
00462             //get relevant variables of def Ndoe --- set union
00463             refsOfNode.addAll(relVarsOfRefNode);
00464 
00465             //put relevant set of control node to the relevant varible map
00466             relVars.put(defNodeStmt, refsOfNode);
00467             Set refVars = refVarsOf(refNode);
00468             refVars.addAll(relVarsOfRefNode);
00469             relVars.put(refNode, refVars);
00470         }
00471     } else {
00472         for (Iterator i = dd.iterator(); i.hasNext();) {
00473             DataBox defNode = (DataBox) i.next();
00474             Set dataDependVars = defNode.getDependVar();
00475             Stmt defNodeStmt = defNode.getStmt();
00476             if (varsContainArg(dataDependVars, callsite)){
00477             }
00478             else{
00479             
00480             dataDependVars.addAll(defVarsOfRefNode);
00481             //dataDependVars.addAll(refVarsInRefNode); //added on 8/3/2000
00482             Set interVars = SetUtil.setIntersection(dataDependVars, relVarsOfRefNode);
00483             if (interVars.size() == 0)
00484                 continue;
00485             }
00486             workSet.add(defNode);
00487 
00488             //get reference variables of definition Node
00489             Set refsOfNode = refVarsOf(defNodeStmt);
00490             CallSite site = isCallSite(indexMaps.getCallSiteMap(),defNodeStmt);
00491             if (site != null) {
00492                 //add the base of the invokation to the relevant variable set
00493                 refsOfNode = new ArraySet();
00494                 Value base = getBaseFrom(site);
00495                 if (base != null)
00496                     refsOfNode.add(base);
00497             }
00498             //get relevant variables of def Ndoe --- set union
00499             refsOfNode.addAll(relVarsOfRefNode);
00500 
00501             //put relevant set of control node to the relevant varible map
00502             relVars.put(defNodeStmt, refsOfNode);
00503             Set refVars = new ArraySet();
00504             Value base = getBaseFrom(callsite);
00505             if (base != null)
00506                 refVars.add(base);
00507             refVars.addAll(relVarsOfRefNode);
00508             relVars.put(refNode, refVars);
00509         }
00510     }
00511     return workSet;
00512 }
00513   /**
00514    * Get all variables defined in a given statement.
00515    * <p>
00516    * @param stmt query statement.
00517    * @return a set of {@link Value Value} which is 
00518    * defined in <code>stmt</code>.
00519    */
00520 static Set defVarsOf(Stmt stmt) {
00521     Set buff = new ArraySet();
00522     for (Iterator defBoxIt = stmt.getDefBoxes().iterator(); defBoxIt.hasNext();) {
00523         ValueBox defBox = (ValueBox) defBoxIt.next();
00524         Value value = defBox.getValue();
00525         if ((value instanceof Local) || (value instanceof StaticFieldRef) || (value instanceof InstanceFieldRef))
00526             buff.add(value);
00527     }
00528     return buff;
00529 }
00530 private boolean existCallPathFromOriginalMd(MethodInfo toMd) {
00531     //if (fromMd.sootMethod.getName().equals("<init>"))
00532     //return true;
00533     boolean existCallPath = false;
00534     Set calculatedMds = new ArraySet();
00535     LinkedList workList = new LinkedList();
00536     //workList.addFirst(fromMd);
00537     workList.addAll(Slicer.originalMethods);
00538     boolean finished = false;
00539     while (!finished) {
00540         if (workList.isEmpty())
00541             finished = true;
00542         else {
00543             MethodInfo targetMdInfo = (MethodInfo) workList.removeFirst();
00544             calculatedMds.add(targetMdInfo);
00545             LinkedList calledMethods = new LinkedList();
00546             addCalledMdToWorkList(targetMdInfo, calledMethods, calculatedMds);
00547             /*
00548             if (Slicer.originalMethods.contains(targetMdInfo) 
00549             || existMutualLockWithOriginalMd(targetMdInfo) 
00550             || originalMdsFromReadyContains(targetMdInfo)
00551             || originalMdsFromReadyCallSite.contains(targetMdInfo)) {
00552             */
00553             if (calledMethods.contains(toMd)) {
00554                 existCallPath = true;
00555                 finished = true;
00556             } else
00557 
00558 
00559 
00560                 
00561                 //add call methods at all callsite of targetMd to workList
00562                 workList.addAll(workList.size(), calledMethods);
00563         //addCalledMdToWorkList(targetMdInfo, workList, calculatedMds);
00564 
00565     }
00566 }
00567 return existCallPath;
00568 }
00569   /*
00570 private boolean existCallPathFromOriginalMd(MethodInfo callerMd) {
00571     //if (fromMd.sootMethod.getName().equals("<init>"))
00572     //return true;
00573     boolean existCallPath = false;
00574     Set calculatedMds = new ArraySet();
00575     LinkedList workList = new LinkedList();
00576     workList.addFirst(callerMd);
00577     boolean finished = false;
00578     while (!finished) {
00579         if (workList.isEmpty())
00580             finished = true;
00581         else {
00582             MethodInfo targetMdInfo = (MethodInfo) workList.removeFirst();
00583             calculatedMds.add(targetMdInfo);
00584             if (Slicer.originalMethods.contains(targetMdInfo)){
00585                 existCallPath = true;
00586                 finished = true;
00587             } else
00588                 //add call methods at all callers of targetMd to workList
00589                 addCallersMdToWorkList(targetMdInfo, workList, calculatedMds);
00590     }
00591 }
00592 return existCallPath;
00593 }
00594   */
00595   /*
00596 private boolean existCallPathToOriginalMd(MethodInfo fromMd) {
00597     //if (fromMd.sootMethod.getName().equals("<init>"))
00598     //return true;
00599     boolean existCallPath = false;
00600     Set calculatedMds = new ArraySet();
00601     LinkedList workList = new LinkedList();
00602     workList.addFirst(fromMd);
00603     boolean finished = false;
00604     while (!finished) {
00605         if (workList.isEmpty())
00606             finished = true;
00607         else {
00608             MethodInfo targetMdInfo = (MethodInfo) workList.removeFirst();
00609             calculatedMds.add(targetMdInfo);
00610             if (Slicer.originalMethods.contains(targetMdInfo) 
00611                 || existMutualLockWithOriginalMd(targetMdInfo) 
00612                 || originalMdsFromReadyContains(targetMdInfo)
00613                 || originalMdsFromReadyCallSite.contains(targetMdInfo)) {
00614                 existCallPath = true;
00615                 finished = true;
00616             } else
00617                 //add call methods at all callsite of targetMd to workList
00618                 addCalledMdToWorkList(targetMdInfo, workList, calculatedMds);
00619     }
00620 }
00621 return existCallPath;
00622 }
00623   */
00624 //exist mutual lock with original method means current method can possibly
00625 //be executed concurrently with the original method
00626   /*
00627 private boolean existMutualLockWithOriginalMd(MethodInfo currentMd) {
00628     boolean existing = false;
00629     LockAnalysis lockOfCurrentMd = currentMd.methodPDG.getLockAnalysis();
00630     if (lockOfCurrentMd == null) {
00631     } else {
00632         for (Iterator i = Slicer.originalMethods.iterator(); i.hasNext();) {
00633             MethodInfo originalMdInfo = (MethodInfo) i.next();
00634             LockAnalysis lockOfOriginalMd = originalMdInfo.methodPDG.getLockAnalysis();
00635             if (lockOfOriginalMd == null)
00636                 continue;
00637             existing = (existing || lockOfCurrentMd.mutualLock(lockOfOriginalMd));
00638         }
00639     }
00640     return existing;
00641 }
00642   */
00643   /**
00644    * Extract the line like <code>Bandera.assert</code> from all slice points.
00645    * <p>
00646    * @param lineList a set of {@link Stmt Stmt} which is slice point.
00647    * @return a list of statement which is like <code>Bandera.assert</code>.
00648    */
00649 private  List extractingAssertLine(Set lineList) {
00650     List assertStmtList = new ArrayList();
00651     for (Iterator lineIt = lineList.iterator(); lineIt.hasNext();) {
00652         Stmt lineStmt = (Stmt) lineIt.next();
00653         if (isBanderaInvoke(lineStmt))
00654             assertStmtList.add(lineStmt);
00655     }
00656     return assertStmtList;
00657 }
00658   /**
00659    * Extract variables used in all <code>Bandera.assert</code> statements.
00660    * <p>
00661    * @param assertList a list of <code>Bandera.assert</code> statements.
00662    * @return a list of {@link Value Value} used in the set of statements.
00663    */
00664 private  List extractingVarsInAssert(List assertList) {
00665     List varList = new ArrayList();
00666     for (Iterator assertIt = assertList.iterator(); assertIt.hasNext();) {
00667         Stmt assertStmt = (Stmt) assertIt.next();
00668         List useAndDefBoxes = assertStmt.getUseAndDefBoxes();
00669         for (Iterator boxIt = useAndDefBoxes.iterator(); boxIt.hasNext();) {
00670             Value value = ((ValueBox) boxIt.next()).getValue();
00671             if (value instanceof Local) {
00672                 varList.add(value);
00673             }
00674         }
00675     }
00676     return varList;
00677 }
00678   /**
00679    * Generate new slice criterion for given method from given statement and 
00680    * a set of relevant variables.
00681    * <p>
00682    * @param methodInfo method to be generated new slice criterion.
00683    * @param interStmt slice point in the new slice criterion.
00684    * @param newRelVars slice variables in the new slice criterion.
00685    */
00686 private void generateNewCriterion(MethodInfo methodInfo, Stmt interStmt, Set newRelVars) {
00687 
00688     IndexMaps ims = methodInfo.indexMaps;
00689     StmtList targetStmtList = methodInfo.originalStmtList;
00690 
00691     int interStmtIndex = targetStmtList.indexOf(interStmt);
00692     BitSet exitNodesNoThrow = ims.exitNodesWithoutThrow(ims.exitNodes());
00693     BitSet sliceSet = methodInfo.sliceSet;
00694     //to avoid null pointer of sliceSet
00695     if (sliceSet == null)
00696         sliceSet = new BitSet(targetStmtList.size());
00697     SliceCriterion increCriterion = methodInfo.increCriterion;
00698     if (increCriterion != null) {
00699         //to see if the interClassStmt is in the increCriterion
00700 
00701         //if it is in the increCriterion, then return
00702         // (because variable set 
00703         //is the same: used variables set of the interClassStmt)
00704 
00705         if (increCriterion.getSlicePoints().contains(interStmt))
00706             return;
00707     }
00708 
00709     //to see if the interClassStmt is in the slice set of that method
00710     Set relVarsAtInterStmt = new ArraySet();
00711     relVarsAtInterStmt.addAll(newRelVars);
00712     if (!sliceSet.get(interStmtIndex)) {
00713         //if not in it, then creat new criterion, and assign or add 
00714         //it to increCrit
00715         Set pointSet = new ArraySet();
00716         pointSet.add(interStmt);
00717         if (increCriterion == null)
00718             increCriterion = new SliceCriterion(pointSet, relVarsAtInterStmt, new ArraySet());
00719         else {
00720             increCriterion.getSlicePoints().addAll(pointSet);
00721             increCriterion.getSliceVars().addAll(relVarsAtInterStmt);
00722         }
00723     } else {
00724         //if it is in the slice set then to see if the used variables set
00725         //is the same as the relevant variables set of the interClassStmt
00726 
00727         Set relevantVars = getAllVariables(sliceSet,targetStmtList);
00728         if (relevantVars.containsAll(relVarsAtInterStmt))
00729             return;
00730         relVarsAtInterStmt.removeAll(relevantVars);
00731         if (relVarsAtInterStmt.isEmpty())
00732             return;
00733         BitSet newPointsSet = new BitSet(targetStmtList.size());
00734         Set newRelVarSet = rmAssInSlice(relVarsAtInterStmt, newPointsSet, sliceSet, ims.localAssMap());
00735         if (newRelVarSet.isEmpty() && SetUtil.emptyBitSet(newPointsSet))
00736             return;
00737         Set newPointStmtSet = SetUtil.bitSetToStmtSet(newPointsSet, targetStmtList);
00738         newPointStmtSet.add(interStmt);
00739         if (increCriterion == null)
00740             increCriterion = new SliceCriterion(newPointStmtSet, newRelVarSet, new ArraySet());
00741         else {
00742             increCriterion.getSlicePoints().addAll(newPointStmtSet);
00743             increCriterion.getSliceVars().addAll(newRelVarSet);
00744         }
00745     }
00746     if (!criterionChanged)
00747         criterionChanged = true;
00748     Map relVarMapOfNewCriterion = PreProcess.extractRelVarMapFromCriterion(increCriterion);
00749     increCriterion.setRelVarMap(relVarMapOfNewCriterion);
00750     methodInfo.increCriterion = increCriterion;
00751     return;
00752 }
00753   /**
00754    * Generate new slice criterion for a caller in terms of a call site.
00755    * <br> The main work in this method is to calculate relevant variables in
00756    * the call site according to relevant variables at entry point of callee, and 
00757    * parameter binding.
00758    * <p>
00759    * @param callSite call site which will be the new slice point.
00760    * @param calleeMdInfo method which is called by the call site.
00761    * @param relVarmapOfCallee relevant variable map of callee, 
00762    * see {@link SliceCriterion#relVarMap SliceCriterion.relVarMap}.
00763    */
00764 private void generateNewCriterionForCaller(CallSite callSite, MethodInfo calleeMdInfo, Map relVarMapOfCallee) {
00765   MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
00766   if (callerMdInfo==null) return;
00767 
00768     //get relevant variables for first statement of callee
00769     /*  Set relVarsOfCallee = new ArraySet();
00770     Stmt startStmt = startNodeAfterSlicing(calleeMdInfo);
00771     Set startStmtRelVar = (Set) relVarMapOfCallee.get(startStmt);
00772     relVarsOfCallee.addAll(startStmtRelVar);
00773     */
00774     Set relVarsOfCallee = PostProcess.getRelevantLocals(calleeMdInfo.originalStmtList, calleeMdInfo.sliceSet, relVarMapOfCallee);
00775     //get relevant instance field in callee
00776     Set instanceFdInCallee = allMODREFFields(calleeMdInfo.MOD.instanceFields, calleeMdInfo.REF.instanceFields);
00777     Set relInstanceFdInCallee = new ArraySet();
00778     for (Iterator i = instanceFdInCallee.iterator(); i.hasNext();) {
00779         Value field = (Value) i.next();
00780         if (relVarsOfCallee.contains(field))
00781             relInstanceFdInCallee.add(field);
00782     }
00783 
00784     //get relevant variables in caller at callsite
00785     //including parameter fields and static variables
00786     Set relVarsInCaller = new ArraySet();
00787     InvokeExpr invokeExpr = callSite.invokeExpr;
00788 
00789     //add the base of invokeExpr to relVarsInCaller
00790     if (invokeExpr instanceof NonStaticInvokeExpr) {
00791         NonStaticInvokeExpr nonStaticInvokeExpr = (NonStaticInvokeExpr) invokeExpr;
00792         Value callerBase = nonStaticInvokeExpr.getBase();
00793         relVarsInCaller.add(callerBase);
00794 
00795         //change base to caller base for every relevant 
00796         //instance field in callee
00797         Set relInstanceFdInCaller = BuildPDG.cloneAndChangeBase(relInstanceFdInCallee, callerBase);
00798 
00799         //add instance fields to relVarsInCaller
00800         for (Iterator i = relInstanceFdInCaller.iterator(); i.hasNext();)
00801             relVarsInCaller.add((Value) i.next());
00802     }
00803 
00804     //static variables in caller which are in relVarsOfCallee
00805     
00806     Fields MODInCaller = callerMdInfo.MOD;
00807     Fields REFInCaller = callerMdInfo.REF;
00808     Set allStaticFieldsInCaller = allMODREFFields(MODInCaller.staticFields, REFInCaller.staticFields);
00809     for (Iterator i = allStaticFieldsInCaller.iterator(); i.hasNext();) {
00810         Value staticField = (Value) i.next();
00811         if (relVarsOfCallee.contains(staticField))
00812             relVarsInCaller.add(staticField);
00813     }
00814 
00815     //parameters in callee which are in caller with binding function
00816 
00817     Local paraLocalsOfCallee[] = calleeMdInfo.indexMaps.getParaLocalSet();
00818     SimpleLocalCopies simpleLocalCopiesInCallee = new SimpleLocalCopies((CompleteStmtGraph) calleeMdInfo.indexMaps.getStmtGraph());
00819     Fields MODInCallee = calleeMdInfo.MOD;
00820     Fields REFInCallee = calleeMdInfo.REF;
00821     Set paraFieldsInCallee = null;
00822     for (int j = 0; j < 2; j++) {
00823         if (j == 0)
00824             paraFieldsInCallee = MODInCallee.paraFields;
00825         else
00826             paraFieldsInCallee = REFInCallee.paraFields;
00827         for (Iterator k = paraFieldsInCallee.iterator(); k.hasNext();) {
00828             DataBox dbx = (DataBox) k.next();
00829             Set paraFields = dbx.getInterferVars();
00830             for (Iterator i = paraFields.iterator(); i.hasNext();) {
00831                 InstanceFieldRef insFieldRef = (InstanceFieldRef) i.next();
00832                 //should also consider the local copy of base
00833                 if (relVarsOfCallee.contains(insFieldRef)) {
00834                     int paraIndex = Fields.getParaIndex(insFieldRef, paraLocalsOfCallee, simpleLocalCopiesInCallee, dbx.getInterferStmt());
00835                     InstanceFieldRef newInsFieldRef = Jimple.v().newInstanceFieldRef(invokeExpr.getArg(paraIndex), insFieldRef.getField());
00836                     relVarsInCaller.add(newInsFieldRef);
00837 
00838                     //add the base of paraField ot relVarsInCaller
00839                     relVarsInCaller.add(newInsFieldRef.getBase());
00840                 }
00841             }
00842         }
00843     }
00844     InvokeExpr callSiteInvoke = callSite.invokeExpr;
00845     for (int i=0; i<paraLocalsOfCallee.length; i++)
00846     {
00847         if (relVarsOfCallee.contains(paraLocalsOfCallee[i]))
00848         relVarsInCaller.add(callSiteInvoke.getArg(i));
00849     }
00850     generateNewCriterion(callerMdInfo, callSite.callStmt, relVarsInCaller);
00851 }
00852 /**
00853    * Generate new slice criterion for a callee in terms of a call site.
00854    * <br> The main work in this method is to calculate relevant variables in
00855    * the exit point of callee according to relevant variables at the call site
00856    *  of the caller, and parameter binding.
00857    * <p>
00858    * @param callSite call site.
00859    * @param relvarsInCaller relevant variables in the call site.
00860    * @param callerMdInfo the method of caller.
00861    * @param targetMdInfo method which is called by the call site.
00862    * @param relevantVarMap relevant variable map of callee, 
00863    * see {@link SliceCriterion#relVarMap SliceCriterion.relVarMap}.
00864    * @param exitStmtSet a set of {@link Stmt Stmt} which is exit point of callee.
00865    * @param localCopiesInCaller a set of {@link Local Local}. 
00866    */
00867 private void genNewCritForExit(CallSite callSite, Map relevantVarMap, Set relVarsInCaller, MethodInfo callerMdInfo, MethodInfo targetMdInfo, Set exitStmtSet, Set localCopiesInCaller) {
00868     //determine the relevant variables at callSite
00869     //including static, instance(global), and parameters
00870 
00871     //get index of call site and invoke expression
00872 
00873     Stmt callSiteStmt = callSite.callStmt;
00874     SliceTraceNode stn = new SliceTraceNode(callerMdInfo, callSiteStmt);
00875     SliceTraceNode stnInTrace = sliceTraceContains(stn);
00876     if (stnInTrace == null) {
00877         System.out.println("slice trace node of " + stn + " should not be null");
00878         System.exit(0);
00879     }
00880 
00881     //Map stmtToIndexOfCaller = callerMdInfo.indexMaps.stmtToIndex();
00882     //Index callSiteIndex = (Index) stmtToIndexOfCaller.get(callsiteStmt);
00883 
00884     //get relevant variable set of the call site
00885     Set relVarsAtCallSite = (Set) relevantVarMap.get(callSiteStmt);
00886 
00887 
00888     //determine relevant variable set in target method in terms of relevant
00889     //variable set of the call site and MOD/REF of target method
00890     Set relVarsInTargetMd = new ArraySet();
00891     Fields MODFields = targetMdInfo.MOD;
00892     Fields REFFields = targetMdInfo.REF;
00893 
00894     //get all static fields use/def in target method
00895     Set staticFields = allMODREFFields(MODFields.staticFields, REFFields.staticFields);
00896     //filter out the relevant static variables in target method
00897     staticFdInTargetMd(relVarsAtCallSite, staticFields, relVarsInTargetMd);
00898     InvokeExpr invokeExpr = callSite.invokeExpr;
00899     //static invoke can only handle static fields
00900     if (invokeExpr instanceof NonStaticInvokeExpr) {
00901         //get all instance fields use/def in target method
00902         Set instanceFields = allMODREFFields(MODFields.instanceFields, REFFields.instanceFields);
00903 
00904         //fileter out the relevant instance variables in target md
00905 
00906         instanceFdInTargetMd(relVarsAtCallSite, instanceFields, relVarsInTargetMd, invokeExpr, localCopiesInCaller);
00907     }
00908 
00909     //begin to process the parameter fields
00910     Local paraLocals[] = targetMdInfo.indexMaps.getParaLocalSet();
00911     SimpleLocalCopies simpleLocalCopiesInTargetMd = new SimpleLocalCopies((CompleteStmtGraph) targetMdInfo.indexMaps.getStmtGraph());
00912     Set paraFieldsInTargetMd = MODFields.paraFields;
00913 
00914     //filter out which one of paraFieldsInTargetMd is relevant in caller md
00915     paraFdInTargetMd(paraFieldsInTargetMd, relVarsAtCallSite, relVarsInTargetMd, invokeExpr, paraLocals, simpleLocalCopiesInTargetMd);
00916     paraFieldsInTargetMd = REFFields.paraFields;
00917     paraFdInTargetMd(paraFieldsInTargetMd, relVarsAtCallSite, relVarsInTargetMd, invokeExpr, paraLocals, simpleLocalCopiesInTargetMd);
00918     IndexMaps targetMdIndexMaps = targetMdInfo.indexMaps;
00919     if (targetMdInfo.sootMethod.getName().equals("<init>")) {
00920         Local thisRef = targetMdIndexMaps.getThisRefLocal();
00921         relVarsInTargetMd.add(thisRef);
00922 
00923         //includs specialinvoke of thisRef into criterion
00924         List specialInvokes = targetMdIndexMaps.getSpecialInvokeList();
00925         for (Iterator i = specialInvokes.iterator(); i.hasNext();) {
00926             InvokeStmt invoke = (InvokeStmt) i.next();
00927             if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
00928                 SpecialInvokeExpr specInvoke = (SpecialInvokeExpr) invoke.getInvokeExpr();
00929                 String specSignature = specInvoke.getMethod().getSignature();
00930                 if (!specSignature.startsWith("java.lang"))
00931                     continue;
00932                 Value specBase = specInvoke.getBase();
00933                 if (specBase instanceof Local) {
00934                     if (simpleLocalCopiesInTargetMd.isLocalCopyOfBefore((Local) specBase, thisRef, invoke)) {
00935                         generateNewCriterion(targetMdInfo, invoke, relVarsInTargetMd);
00936                         addToSliceTrace(stnInTrace, invoke, Kind.CALLSITE, targetMdInfo);
00937                     } else
00938                         if (specBase.equals(thisRef)) {
00939                             generateNewCriterion(targetMdInfo, invoke, relVarsInTargetMd);
00940                             addToSliceTrace(stnInTrace, invoke, Kind.CALLSITE, targetMdInfo);
00941                         }
00942                 } else
00943                     throw new NonLocalBaseSpecialInvokeException("we don't know yet how to process non local base of special invoke: " + invoke);
00944             }
00945         }
00946     }
00947 
00948 
00949 
00950     //Finally, we get relVarsInTargetMd for cirterion generation
00951 
00952     for (Iterator i = exitStmtSet.iterator(); i.hasNext();) {
00953         Stmt exitStmt = (Stmt) i.next();
00954         if (callSiteStmt instanceof DefinitionStmt) {
00955             Value leftValue = ((DefinitionStmt) callSiteStmt).getLeftOp();
00956             if (relVarsInCaller.contains(leftValue))
00957                 putUsedVarIntoRelSet(exitStmt, relVarsInTargetMd);
00958         }
00959         if (exitStmt instanceof ThrowStmt) {
00960             Set relVarsInTargetMdPlusThrowVar = new ArraySet();
00961             relVarsInTargetMdPlusThrowVar.addAll(relVarsInTargetMd);
00962             List useBoxes = exitStmt.getUseBoxes();
00963             for (Iterator boxIt = useBoxes.iterator(); boxIt.hasNext();) {
00964                 ValueBox useBox = (ValueBox) boxIt.next();
00965                 relVarsInTargetMdPlusThrowVar.add(useBox.getValue());
00966             }
00967             generateNewCriterion(targetMdInfo, exitStmt, relVarsInTargetMdPlusThrowVar);
00968         } else
00969             generateNewCriterion(targetMdInfo, exitStmt, relVarsInTargetMd);
00970         addToSliceTrace(stnInTrace, exitStmt, Kind.CALLSITE, targetMdInfo);
00971     }
00972 }
00973   /**
00974    * Get all variables appeared in a set statement..
00975    * <p>
00976    * @param stmtIndexSet a set of statement.
00977    * @param localStmtList statement list for indexing.
00978    */
00979 private Set getAllVariables(BitSet stmtIndexSet, StmtList localStmtList) {
00980     Set variableSet = new ArraySet();
00981     for (int i = 0; i < stmtIndexSet.size(); i++) {
00982         if (!stmtIndexSet.get(i))
00983             continue;
00984         Stmt stmt = (Stmt) localStmtList.get(i);
00985         variableSet.addAll(allLocalVarsOf(stmt));
00986     }
00987     return variableSet;
00988 }
00989 /**
00990  * Get base value for a call site.
00991  * <p>
00992  * @return base value of the call site.
00993  * @param site call site.
00994  */
00995 private Value getBaseFrom(CallSite site) {
00996     Value base = null;
00997     InvokeExpr invoke = site.invokeExpr;
00998     if (invoke instanceof NonStaticInvokeExpr)
00999         base = ((NonStaticInvokeExpr) invoke).getBase();
01000     return base;
01001 }
01002   /**
01003    * Get all the local copies before all the slice points, using the work list algorithm.
01004    * <p>
01005    * @param mdInfo method to be analysed.
01006    * @param linePropList a list of {@link Stmt  Stmt} which is slice point.
01007    * @return a set of {@link LocalCopy LocalCopy}.
01008    */
01009 private Set getCompleteLocalCopiesList(MethodInfo mdInfo, Set linePropList) {
01010     Set copiesList = new ArraySet();
01011     StmtGraph stmtGraph = mdInfo.indexMaps.getStmtGraph();
01012     SimpleLocalCopies simpleLocalCopies = new SimpleLocalCopies((CompleteStmtGraph) stmtGraph);
01013 
01014     //initializing the workList
01015     LinkedList workList = new LinkedList();
01016     List visitedStmts = new ArrayList();
01017     for (Iterator lineIt = linePropList.iterator(); lineIt.hasNext();)
01018         workList.addLast((Stmt) lineIt.next());
01019 
01020     //begin to traverse the stmtGraph be predecessors
01021     while (!workList.isEmpty()) {
01022         Stmt stmt = (Stmt) workList.removeFirst();
01023         if (visitedStmts.contains(stmt))
01024             continue;
01025         visitedStmts.add(stmt);
01026         List copiesListBefore = simpleLocalCopies.getCopiesBefore(stmt);
01027         //add elements in copiesListBefore into copiesList
01028         for (Iterator copyIt = copiesListBefore.iterator(); copyIt.hasNext();)
01029             copiesList.add((LocalCopy) copyIt.next());
01030 
01031         //add all the predecessor of stmt into workList
01032         if (stmtList.indexOf(stmt) != 0) {
01033             List predList = stmtGraph.getPredsOf(stmt);
01034             for (Iterator predIt = predList.iterator(); predIt.hasNext();)
01035                 workList.addLast((Stmt) predIt.next());
01036         }
01037     }
01038     return copiesList;
01039 }
01040   /**
01041    * Get all local copies of a value.
01042    * <p>
01043    * @param base query value.
01044    * @param localCopies a set of {@link LocalCopy LocalCopy}.
01045    * @return a set {@link Local Local} which is local copy of <code>base</code>.
01046    */
01047 private Set getCopiesOfTheBase(Value base, Set localCopies) {
01048     if (!(base instanceof Local))
01049         throw new BaseValueNonLocalException("base should be a local: Slicing.InstanceFdIntargetMd(...)");
01050     Set baseCopiesList = new ArraySet();
01051 
01052     //at lease the baseLocal is the one in the copiesList
01053     baseCopiesList.add((Local) base);
01054 
01055     //filter out the copies of the baseLocal from the localCopies
01056     for (Iterator copiesIt = localCopies.iterator(); copiesIt.hasNext();) {
01057         LocalCopy localCopy = (LocalCopy) copiesIt.next();
01058         Local leftLocal = localCopy.getLeftLocal();
01059         Local rightLocal = localCopy.getRightLocal();
01060         if (baseCopiesList.contains(leftLocal))
01061             
01062             //add right local into copiesList
01063             baseCopiesList.add(rightLocal);
01064         else
01065             if (baseCopiesList.contains(rightLocal))
01066                 
01067                 //add left local into copiesList
01068                 baseCopiesList.add(leftLocal);
01069     }
01070     return baseCopiesList;
01071 }
01072   /**
01073    * Change the base of given instance field reference into a set of give locals.
01074    * <p>
01075    * @param insField instance field reference need to be changed.
01076    * @param copiesOfBase a set of {@link Local Local} which will be new base of 
01077    * <code>insField</code>.
01078    * @return a set of {@link InstanceFieldRef InstanceFieldRef} with new base.
01079    */
01080 private Set getNewInsFieldRefSet(InstanceFieldRef insField, Set copiesOfBase) {
01081     Set newInsFieldRefSet = new ArraySet();
01082     for (Iterator localIt = copiesOfBase.iterator(); localIt.hasNext();) {
01083         Local baseCopy = (Local) localIt.next();
01084         InstanceFieldRef newInsFieldRef = Jimple.v().newInstanceFieldRef(baseCopy, insField.getField());
01085         newInsFieldRefSet.add(newInsFieldRef);
01086     }
01087     return newInsFieldRefSet;
01088 }
01089 private Set getTraceNodeSetFrom(Set stmtSet,MethodInfo mdin)
01090     {
01091       Set traceNodeSet = new ArraySet();
01092       for (Iterator stmtIt = stmtSet.iterator(); stmtIt.hasNext();)
01093     {
01094       Stmt stmt = (Stmt) stmtIt.next();
01095       SliceTraceNode stn = new SliceTraceNode(mdin, stmt);
01096       SliceTraceNode containStn = sliceTraceContains(stn);
01097       traceNodeSet.add(containStn);
01098     }
01099       return traceNodeSet;
01100     }
01101   /**
01102    * Get string representation of a value.
01103    * <p>
01104    * @param value a value.
01105    * @return the string representation of <code>value</code>.
01106    */
01107   private String getValueString(Value value)
01108     {
01109       String valueString = "";
01110 
01111       if (value instanceof Local)
01112     valueString = ((Local) value).toBriefString();
01113 
01114       else if (value instanceof StaticFieldRef)
01115     valueString = ((StaticFieldRef) value).getField().toString();
01116 
01117       else if (value instanceof InstanceFieldRef)
01118     valueString = ((InstanceFieldRef) value).toBriefString();
01119 
01120       else
01121     throw new CantProcessException("We can not process other type of value, except Local, StaticFieldRef, InstanceFieldRef in PreProcess");
01122        
01123       return valueString;
01124     }
01125   /**
01126    * Get statement index set of a given data box set.
01127    * <p>
01128    * @param dataBoxSet a set of {@link DataBox DataBox}.
01129    * @return a set of statement indexed by statement list.
01130    */
01131 private  BitSet indexSetOf(Set dataBoxSet) {
01132     BitSet workSet = new BitSet(stmtListSize);
01133     for (Iterator i = dataBoxSet.iterator(); i.hasNext();) {
01134         DataBox db = (DataBox) i.next();
01135         workSet.set(stmtList.indexOf(db.getStmt()));
01136     }
01137     return workSet;
01138 }
01139   /**
01140    * Get all relevant instance field from a given instance field set.
01141    * <p>
01142    * @param relVarsAtCallSite a set of {@link Value Value} which is relevant variable.
01143    * @param instanceFields a set of {@link InstanceFieldRef InstanceFieldRef}.
01144    * @param relVarsInTargetMd relevant variables in target method.
01145    * @param invokeExpr invoke expression of the call site.
01146    * @param localCopiesInCaller local copies in caller.
01147    */
01148 private void instanceFdInTargetMd(Set relVarsAtCallSite, Set instanceFields, Set relVarsInTargetMd, InvokeExpr invokeExpr, Set localCopiesInCaller) {
01149     Value base = ((NonStaticInvokeExpr) invokeExpr).getBase();
01150     Set copiesOfTheBase = getCopiesOfTheBase(base, localCopiesInCaller);
01151 
01152 
01153     /*********************************************
01154       //should get all the local copy of base in caller method
01155       **********************************************/
01156 
01157     for (Iterator i = instanceFields.iterator(); i.hasNext();) {
01158         InstanceFieldRef insField = (InstanceFieldRef) i.next();
01159         Set insFieldSet = getNewInsFieldRefSet(insField, copiesOfTheBase);
01160         Set interSet = SetUtil.setIntersection(relVarsAtCallSite,insFieldSet);
01161         if (!interSet.isEmpty()) {
01162             relVarsInTargetMd.add(insField);
01163             //add the base of instance fields to relVarsInTargetMd
01164             base =  insField.getBase();
01165             relVarsInTargetMd.add(base);
01166         }
01167     }
01168 }
01169   /**
01170    * See if a statement is <code>Bandera.assert</code>.
01171    * <p>
01172    * @return boolean.
01173    */
01174 public static  boolean isBanderaInvoke(Stmt nodeStmt) {
01175     if (nodeStmt instanceof InvokeStmt) {
01176         Value invokeExprValue = ((InvokeStmt) nodeStmt).getInvokeExpr();
01177         InvokeExpr invokeExpr = (InvokeExpr) invokeExprValue;
01178         if (invokeExpr instanceof StaticInvokeExpr) {
01179             SootMethod invokedMethod = invokeExpr.getMethod();
01180             String methodName = invokedMethod.getName();
01181             String className = invokedMethod.getDeclaringClass().getName();
01182             if ((methodName.equals("assert") || methodName.equals("available"))&& className.equals("Bandera"))
01183                 return true;
01184         }
01185     }
01186     return false;
01187 }
01188   /**
01189    * See if a statement is a call site.
01190    * <p>
01191    * @param callSiteMap call site map.
01192    * @param node a statement.
01193    * @return call site if  <code>node</code> is call site, <code>null</code> otherwise.
01194    */
01195  public static CallSite isCallSite(Map callSiteMap, Stmt node) {
01196     Map callSiteIndexMap = callSiteIndex(callSiteMap);
01197     if (callSiteIndexMap.containsKey(node))
01198         return ((CallSite) callSiteIndexMap.get(node));
01199     else
01200         return null;
01201 }
01202   /**
01203    * Analyse method calls in slice.
01204    * <br>Generate new criterion for exit node of every method call in slice.
01205    * <p>
01206    * @param methodInfo current method.
01207    * @param sliceSet slice set.
01208    * @param relVarMap relevant variables map.
01209    * @param localCopiesInCaller local copies in caller.
01210    */
01211 private void mdCallsInSlice(MethodInfo methodInfo, BitSet sliceSet, Map relVarMap, Set localCopiesInCaller) {
01212     Set relVarsInCaller = PostProcess.getRelevantLocals(methodInfo.originalStmtList, sliceSet, relVarMap);
01213     Map callSiteMap = methodInfo.indexMaps.getCallSiteMap();
01214     if (callSiteMap.size() == 0 || callSiteMap == null)
01215         return;
01216     Map callSiteIndexMap = callSiteIndex(callSiteMap);
01217     List callSiteList = callSiteInSlice(callSiteIndexMap, sliceSet);
01218     if (callSiteList.isEmpty())
01219         return;
01220     for (Iterator siteIt = callSiteList.iterator(); siteIt.hasNext();) {
01221         CallSite site = (CallSite) siteIt.next();
01222         MethodInfo targetMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get((SootMethod) callSiteMap.get(site));
01223         if (targetMdInfo == null) continue;
01224         if (alreadyGenerateCriterionForExits.contains(targetMdInfo))
01225             continue;
01226         else
01227             alreadyGenerateCriterionForExits.add(targetMdInfo);
01228         IndexMaps ims = targetMdInfo.indexMaps;
01229         //BitSet exitNodes = ims.exitNodes();
01230         BitSet exitNodesNoThrow = ims.exitNodesWithoutThrow(ims.exitNodes());
01231         if (SetUtil.emptyBitSet(exitNodesNoThrow)) {
01232             Integer indefiniteNode = BuildPDG.indefiniteFrom(CompilationManager.getAnnotationManager(), targetMdInfo);
01233             if (indefiniteNode.equals(IndexMaps.specialExitNode))
01234                 throw new NoExitNodeException("Can not find out the exit node or the infinite loop in method " + targetMdInfo.sootMethod);
01235             exitNodesNoThrow.set(indefiniteNode.intValue());
01236         }
01237         //added on 11/12/2000 for keep throw statement
01238         exitNodesNoThrow.or(ims.exitNodes());
01239         //
01240         Set exitStmtSet = SetUtil.bitSetToStmtSet(exitNodesNoThrow, targetMdInfo.originalStmtList);
01241         genNewCritForExit(site, relVarMap, relVarsInCaller, methodInfo, targetMdInfo, exitStmtSet, localCopiesInCaller);
01242     }
01243 }
01244 /**
01245  * See if there is one parameter field is relevant.
01246  * <p>
01247  * @return boolean
01248  * @param mdInfo current method.
01249  * @param relMap relevant variables map.
01250  * @param sSet slice set.
01251  */
01252 private  boolean oneParaFdIsRelevant(MethodInfo mdInfo, Map relMap, BitSet sSet) {
01253     Set valueSet = PostProcess.getRelevantLocals(stmtList, sSet, relMap);
01254     Set paraRefFields = mdInfo.REF.paraFields;
01255     for (Iterator fdIt = paraRefFields.iterator(); fdIt.hasNext();)
01256     {
01257         DataBox paraBox = (DataBox) fdIt.next();
01258         Set paraFds = paraBox.getDependVar();
01259         Set interFds = SetUtil.setIntersection(paraFds,valueSet);
01260         if (!interFds.isEmpty()) return true;
01261     }
01262     Local[] paraLocals = indexMaps.getParaLocalSet();
01263     for (int i=0; i<paraLocals.length; i++)
01264     {
01265         if (valueSet.contains(paraLocals[i])) return true;
01266     }
01267     return false;
01268 }
01269   /*
01270 private boolean originalMdsFromReadyContains(MethodInfo targetMdInfo) {
01271     if ((targetMdInfo.sCriterion != null) || (targetMdInfo.increCriterion != null) || (targetMdInfo.sliceSet != null))
01272         return originalMethodsFromReady.contains(targetMdInfo);
01273     return false;
01274 }
01275   */
01276 
01277 private void paraFdInTargetMd(Set paraFieldsInTargetMd, Set relVarsAtCallSite, Set relVarsInTargetMd, InvokeExpr invokeExpr, Local[] paraLocals, SimpleLocalCopies simpleLocalCopiesInTargetMd) {
01278     for (Iterator i = paraFieldsInTargetMd.iterator(); i.hasNext();) {
01279         DataBox dbx = (DataBox) i.next();
01280         Set insFieldRefs = dbx.getInterferVars();
01281         for (Iterator k = insFieldRefs.iterator(); k.hasNext();) {
01282             InstanceFieldRef insFieldRef = (InstanceFieldRef) k.next();
01283             int paraIndex = Fields.getParaIndex(insFieldRef, paraLocals, simpleLocalCopiesInTargetMd, dbx.getInterferStmt());
01284             InstanceFieldRef newInsFieldRef = Jimple.v().newInstanceFieldRef(invokeExpr.getArg(paraIndex), insFieldRef.getField());
01285             if (relVarsAtCallSite.contains(newInsFieldRef)) {
01286                 relVarsInTargetMd.add(insFieldRef);
01287                 //add the base of paraFields to relVarsInTargetmd
01288                 Local baseLocal = (Local) insFieldRef.getBase();
01289                 relVarsInTargetMd.add(baseLocal);
01290             }
01291         }
01292     }
01293 }
01294   /**
01295    * Put a given variable into relevant variable map.
01296    * <p>
01297    * @param var varible
01298    * @param assToVar all assignment to <code>var</code>.
01299    * @param relVarMap relevant variable map.
01300    */
01301 private  void putToRelVarMap(Object var, BitSet assToVar, Map relVarMap) {
01302     Set varSet = new ArraySet();
01303     varSet.add(var);
01304     for (int i = 0; i < assToVar.size(); i++) {
01305         if (!assToVar.get(i)) continue;
01306         Stmt assStmt = (Stmt) stmtList.get(i);
01307         if (relVarMap.containsKey(assStmt)) {
01308             Set prevVarSet = (Set) relVarMap.get(assStmt);
01309             varSet.addAll(prevVarSet);
01310         }
01311         relVarMap.put(assStmt, varSet);
01312     }
01313 }
01314   /**
01315    * Add all used variables in a statement into a set.
01316    * <p>
01317    * @param stmt Stmt
01318    * @param varSet a set of variables.
01319    */
01320 private void putUsedVarIntoRelSet(Stmt stmt, Set varSet) {
01321     for (Iterator useBoxIt = stmt.getUseBoxes().iterator(); useBoxIt.hasNext();) {
01322         ValueBox useBox = (ValueBox) useBoxIt.next();
01323         Value useValue = useBox.getValue();
01324         varSet.add(useValue);
01325     }
01326 }
01327   /**
01328    * Calculate all reachable statements from a given statement.
01329    * <p>
01330    * @param stmt Stmt
01331    * @param stmtGraphAsPara statement graph.
01332    * @return a list of {@link Stmt Stmt}.
01333    */
01334 public static List reachableStmtFrom(Stmt stmt, StmtGraph stmtGraphAsPara) {
01335     List reachableStmt = new ArrayList();
01336     //StmtGraph stmtGraph = indexMaps.getStmtGraph();
01337     reachableStmt.add(stmt);
01338     LinkedList stack = new LinkedList();
01339     stack.addFirst(stmt);
01340     while (!stack.isEmpty()) {
01341         Stmt currentStmt = (Stmt) stack.removeFirst();
01342         List succsList = stmtGraphAsPara.getSuccsOf(currentStmt);
01343         for (Iterator succsIt = succsList.iterator(); succsIt.hasNext();) {
01344             Stmt succStmt = (Stmt) succsIt.next();
01345             if (!reachableStmt.contains(succStmt)) {
01346                 reachableStmt.add(succStmt);
01347                 stack.addLast(succStmt);
01348             }
01349         }
01350     }
01351     return reachableStmt;
01352 }
01353 /**
01354    * Calculate all reachable statements from a given statement.
01355    * <p>
01356    * @param stmt Stmt
01357    * @param stmtGraphAsPara statement graph.
01358    * @return a set of {@link Stmt Stmt}.
01359    */
01360 static Set reachableStmtSetFrom(Stmt stmt, StmtGraph stmtGraphAsPara) {
01361     Set reachableStmtSet = new ArraySet();
01362     //StmtGraph stmtGraph = indexMaps.getStmtGraph();
01363     List reachableStmtList = reachableStmtFrom(stmt, stmtGraphAsPara);
01364     for (Iterator sIt = reachableStmtList.iterator(); sIt.hasNext();) {
01365         reachableStmtSet.add(sIt.next());
01366     }
01367     return reachableStmtSet;
01368 }
01369   /*
01370 private BitSet readyDependOnCallSite(Set callSites, Stmt stmt) {
01371     Map callSiteMap = indexMaps.getCallSiteMap();
01372     BitSet readyCallSet = new BitSet(stmtListSize);
01373     for (Iterator i = callSites.iterator(); i.hasNext();) {
01374         CallSite callSite = (CallSite) i.next();
01375         List reachableStmt = reachableStmtFrom(callSite.callStmt,indexMaps.getStmtGraph());
01376         SootMethod targetMd = (SootMethod) callSiteMap.get(callSite);
01377         MethodInfo calleeMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(targetMd);
01378         if (calleeMdInfo==null) continue;
01379         if (((calleeMdInfo.sCriterion != null) 
01380             || (calleeMdInfo.increCriterion != null) 
01381             || (calleeMdInfo.sliceSet != null)) 
01382           && reachableStmt.contains(stmt))
01383             readyCallSet.set(stmtList.indexOf(callSite.callStmt));
01384         //return readyCallSet;
01385     }
01386     if (!SetUtil.emptyBitSet(readyCallSet)) return readyCallSet;
01387     
01388     for (Iterator i = callSites.iterator(); i.hasNext();) {
01389         CallSite callSite = (CallSite) i.next();
01390         List reachableStmt = reachableStmtFrom(callSite.callStmt,indexMaps.getStmtGraph());
01391         if (reachableStmt.contains(stmt))
01392             readyCallSet.set(stmtList.indexOf(callSite.callStmt));
01393     }
01394     return readyCallSet;
01395 }
01396   */
01397   /**
01398    * Get all variables used in one statement.
01399    * <p>
01400    * @return a set of {@link Value Value}.
01401    */
01402 static Set refVarsOf(Stmt stmt) {
01403     Set buff = new ArraySet();
01404     for (Iterator useBoxIt = stmt.getUseBoxes().iterator(); useBoxIt.hasNext();) {
01405         ValueBox useBox = (ValueBox) useBoxIt.next();
01406         Value value = useBox.getValue();
01407         if ((value instanceof Local) || (value instanceof StaticFieldRef) || (value instanceof InstanceFieldRef) || (value instanceof ParameterRef))
01408             buff.add(value);
01409     }
01410     return buff;
01411 }
01412 private Set rmAssInSlice(Set relVarSet, BitSet keepedPoints, BitSet sliceSet, Map localAssMap) {
01413     Set keepedVars = new ArraySet();
01414     for (Iterator i = relVarSet.iterator(); i.hasNext();) {
01415         Object var =  i.next();
01416         BitSet assignmentSet = (BitSet) localAssMap.get(var);
01417         if (assignmentSet == null || assignmentSet.size() == 0)
01418             continue;
01419         BitSet diffIndexSet = SetUtil.bitSetAndNot(assignmentSet, sliceSet);
01420         if (!SetUtil.emptyBitSet(diffIndexSet)) {
01421             keepedVars.add(var);
01422             keepedPoints.or(diffIndexSet);
01423         }
01424     }
01425     return keepedVars;
01426 }
01427 public static SliceTraceNode sliceTraceContains(SliceTraceNode traceNode) {
01428     for (Iterator nodeIt = Slicer.allSliceTraceNodes.iterator(); nodeIt.hasNext();) {
01429         SliceTraceNode stn = (SliceTraceNode) nodeIt.next();
01430         if (stn.equals(traceNode)) {
01431             //if (!stn.stmts.contains(stmt)) stn.stmts.addElement(stmt);
01432             return stn;
01433         }
01434     }
01435     return null;
01436 }
01437 /**
01438    * Slice one method.
01439    */
01440 void slicingMethod(boolean goingup) {
01441     // get slicing criterion from methodInfo
01442     // slice this method 
01443     // put the slice set into methodInfo
01444     SliceCriterion slCri = methodInfo.sCriterion;
01445     if (slCri == null)
01446         return;
01447     Set calculatedNodes = new ArraySet();
01448     BuildPDG methodPDG = methodInfo.methodPDG;
01449     LockAnalysis lockAnalysis = methodPDG.getLockAnalysis();
01450     Set varList = slCri.getSliceVars();
01451     Set linePropList = slCri.getSlicePoints();
01452     List assertLinePropList = extractingAssertLine(linePropList);
01453     List varsUsedInAssert = extractingVarsInAssert(assertLinePropList);
01454     BitSet assToVarsInAssert = assToVarsNoRelVars(stmtListSize, varsUsedInAssert, indexMaps.localAssMap());
01455     Map relVarMap = slCri.relVarMap();
01456 
01457     //initialize the slice set with assignments to the relevant variables
01458     BitSet sliceSet = new BitSet(stmtListSize);
01459     BitSet initSliceSet = assToRelVars(varList, indexMaps.localAssMap(), relVarMap);
01460     sliceSet.or(initSliceSet);
01461     LinkedList workList = new LinkedList();
01462     sliceSet.or(SetUtil.stmtSetToBitSet(linePropList, stmtList));
01463     //add this on 12/4/2000
01464     sliceSet.or(SetUtil.stmtSetToBitSet(slCri.getSliceStatements(), stmtList));
01465     //
01466     Set readyCallSites = collectCallSitesFrom(methodInfo.possibleReadyDependCallSite);
01467     sliceSet.or(SetUtil.stmtSetToBitSet(readyCallSites, stmtList));
01468     Set readyCallSitesMdInfo = collectCallSitesMdInfoFrom(methodInfo.possibleReadyDependCallSite);
01469     //originalMdsFromReadyCallSite.addAll(readyCallSitesMdInfo);
01470     addToWorkList(workList, sliceSet, calculatedNodes);
01471     addToSliceTrace(Slicer.sliceTraceRoot, slCri.getSliceStatements(), Kind.CRITERION, methodInfo);
01472     addToSliceTrace(Slicer.sliceTraceRoot, linePropList, Kind.CRITERION, methodInfo);
01473     addToSliceTrace(linePropList, initSliceSet, Kind.ASSIGN, methodInfo);
01474     addToSliceTrace(linePropList, readyCallSites, Kind.READY, methodInfo);
01475 
01476     // put use variables of the node into relevant variable map
01477     // this if part may should be put out of the iteration as an
01478     // initialization of relVarMap
01479 
01480 
01481     for (ListIterator workListIt = workList.listIterator(); workListIt.hasNext();) {
01482         Stmt node = (Stmt) workListIt.next();
01483         if (!linePropList.contains(node)) {
01484             //Because node is from workList, all nodes in workList has
01485             //an image in relevant variable map
01486             Set relVarsOfNode = refVarsOf(node);
01487             CallSite site = isCallSite(methodInfo.indexMaps.getCallSiteMap(), node);
01488             if (site != null) {
01489                 //add the base of the invokation to the relevant variable set
01490                 relVarsOfNode = new ArraySet();
01491                 Value base = getBaseFrom(site);
01492                 if (base != null)
01493                     relVarsOfNode.add(base);
01494             }
01495             if (relVarMap.containsKey(node)) {
01496                 Set temp = (Set) relVarMap.get(node);
01497                 relVarsOfNode.addAll(temp);
01498             }
01499             relVarMap.put(node, relVarsOfNode);
01500         }
01501     }
01502     while (!workList.isEmpty()) {
01503         Stmt node = (Stmt) workList.removeFirst();
01504         SliceTraceNode traceNode = sliceTraceContains(new SliceTraceNode(methodInfo, node));
01505         if (traceNode == null) {
01506             System.out.println("traceNode for " + node + " is null!");
01507             // SliceTraceNode sss = new SliceTraceNode(methodInfo, node);
01508             //SliceTraceNode ppp = sliceTraceContains(sss);
01509             //System.exit(0);
01510         }
01511         calculatedNodes.add(node);
01512 
01513         //field (static and nonstatic) analysis and new criterion generation.
01514         //at current state:
01515         //check the use variable of the node from workList, all (static)
01516         //field used in the node, look out all the definition of those field
01517         //in other method of this class, and make it as a slicing point.
01518 
01519         //this method invoke may be copied to slicing method again 
01520         //staticFieldAnalysis(node, methodInfo, methodsList);
01521 
01522         Set ddNodes = methodPDG.dataNodesOf(node);
01523 
01524 
01525         //add computation of relevant variables
01526         //after data relevant varibal comp, ddNodes set may be changed
01527 
01528         // put use variables of the node into relevant variable map
01529         // this if part may should be put out of the iteration as an
01530         // initialization of relVarMap
01531         ddNodes = dataRelVarCompute(relVarMap, node, ddNodes);
01532         BitSet ddIndexSet = indexSetOf(ddNodes);
01533         sliceSet.or(ddIndexSet);
01534         addToWorkList(workList, ddIndexSet, calculatedNodes);
01535         addToSliceTrace(traceNode, ddIndexSet, Kind.DATA, methodInfo);
01536         //if cdNodes == null then it means the node stmt control depend on the special entry node
01537         BitSet cdNodes = methodPDG.controlNodesOf(node);
01538         if (cdNodes != null) {
01539             ctrlRelVarCompute(relVarMap, node, cdNodes);
01540             sliceSet.or(cdNodes);
01541             addToWorkList(workList, cdNodes, calculatedNodes);
01542             addToSliceTrace(traceNode, cdNodes, Kind.CONTROL, methodInfo);
01543         }
01544         BitSet preDivergenceNodes = methodPDG.preDivergencePointsOf(node);
01545         if (preDivergenceNodes != null) {
01546             ctrlRelVarCompute(relVarMap, node, preDivergenceNodes);
01547             sliceSet.or(preDivergenceNodes);
01548             addToWorkList(workList, preDivergenceNodes, calculatedNodes);
01549             addToSliceTrace(traceNode, preDivergenceNodes, Kind.DIVERGENCE, methodInfo);
01550         }
01551         //compute ready dependcy on call site
01552 
01553         //is the current node reachible from any possible ... call site?
01554         //why need to avoid isBanderaInvoke, and avoid assToVarsInAssert
01555         /*      if (isBanderaInvoke(node) || assToVarsInAssert.get(stmtList.indexOf(node))) {
01556         assToVarsInAssert.or(ddIndexSet);
01557         if (cdNodes != null)
01558         assToVarsInAssert.or(cdNodes);
01559         } else {*/
01560         /*      BitSet readyCallSites = readyDependOnCallSite(methodInfo.possibleReadyDependCallSite, node);
01561         if (!SetUtil.emptyBitSet(readyCallSites)) {
01562         ctrlRelVarCompute(relVarMap, node, readyCallSites);
01563         sliceSet.or(readyCallSites);
01564         addToWorkList(workList, readyCallSites, calculatedNodes);
01565         }*/
01566         //}
01567 
01568         /*if there is no lock (lockAnanlysis will be assigned to null if lockPairList.size() = 0 in the class LockAnalysis), there will be no synchronization and ready dependence within class*/
01569 
01570         if (lockAnalysis != null) {
01571 
01572             //compute synchronization dependence
01573 
01574             BitSet monitorSet = lockAnalysis.dependOnMonitorSet(node);
01575             if (!SetUtil.emptyBitSet(monitorSet)) {
01576                 ctrlRelVarCompute(relVarMap, node, monitorSet);
01577                 sliceSet.or(monitorSet);
01578                 addToWorkList(workList, monitorSet, calculatedNodes);
01579                 addToSliceTrace(traceNode, monitorSet, Kind.SYNCH, methodInfo);
01580             }
01581 
01582             //compute ready dependence on entermonitor statement
01583             //if the lock is not safe (determined in lockAnalysis)
01584 
01585             //ready dependence within class
01586             //compute ready dependence on wait statement
01587             //within class
01588             BitSet waitSet = lockAnalysis.readyDependOnWaits(node);
01589             if (!SetUtil.emptyBitSet(waitSet)) {
01590                 ctrlRelVarCompute(relVarMap, node, waitSet);
01591                 sliceSet.or(waitSet);
01592                 addToWorkList(workList, waitSet, calculatedNodes);
01593                 addToSliceTrace(traceNode, waitSet, Kind.READY, methodInfo);
01594                 //lookup the notify stmt corresponding to those wait stmt in waitSet within the method, that means wait/notify ready dependence within method
01595                 /*
01596                 BitSet notifySet = waitNotifyWithinMd(waitSet, lockAnalysis.getWaitStmtList(), lockAnalysis.getNotifyStmtList());
01597                 if (!SetUtil.emptyBitSet(notifySet)) {
01598                 ctrlRelVarCompute(relVarMap, node, notifySet);
01599                 sliceSet.or(notifySet);
01600                 addToWorkList(workList, notifySet, calculatedNodes);
01601                 addToSliceTrace(traceNode, notifySet, Kind.READY, methodInfo);
01602                 }
01603                 */
01604             }
01605         }
01606         methodInfo.sliceSet = sliceSet;
01607 
01608         //if classList.size() == 1 then there will be no ready depend
01609         //and interference depend
01610         if (Slicer.classNum > 1) {
01611             //compute ready dependence
01612 
01613             //suppose all the lock is safe
01614             Map readyDependMap = methodPDG.getReadyDependMap();
01615             if (readyDependMap != null) {
01616                 if (readyDependMap.containsKey(node)) {
01617                     List readyDependStmt = (List) readyDependMap.get(node);
01618                     for (Iterator readyIt = readyDependStmt.iterator(); readyIt.hasNext();) {
01619                         ReadyDependStmt readyStmt = (ReadyDependStmt) readyIt.next();
01620                         MethodInfo readyStmtMdInfo = readyStmt.methodInfo;
01621                         originalMethodsFromReady.add(readyStmtMdInfo);
01622                         generateNewCriterion(readyStmtMdInfo, readyStmt.readyOnStmt, refVarsOf(readyStmt.readyOnStmt));
01623                         addToSliceTrace(traceNode, readyStmt.readyOnStmt, Kind.READY, readyStmtMdInfo);
01624                     }
01625                 }
01626             }
01627 
01628             //end of compute ready dependence interclassed
01629 
01630             //compute interference dependence
01631             //interclass
01632             //add this condition on 10/19/99  in slicingMethod() and            
01633             //slicingMethodAgain()
01634             if (!(node instanceof InvokeStmt) && (!linePropList.contains(node))) {
01635                 Map interferDependMap = methodPDG.getInterferenceMap();
01636                 if (interferDependMap.containsKey(node)) {
01637                     Set relVarsOfNode = (Set) relVarMap.get(node);
01638                     List interferDependStmt = (List) interferDependMap.get(node);
01639                     for (Iterator interferIt = interferDependStmt.iterator(); interferIt.hasNext();) {
01640                         InterferStmt interferStmt = (InterferStmt) interferIt.next();
01641                         Set interferVars = interferStmt.interferVars;
01642                         Set relVars = refVarsOf(interferStmt.interferStmt);
01643                         CallSite site = isCallSite(interferStmt.methodInfo.indexMaps.getCallSiteMap(), interferStmt.interferStmt);
01644                         if (site != null) {
01645                             //add the base of the invokation to the relevant variable set
01646                             relVars = new ArraySet();
01647                             Value base = getBaseFrom(site);
01648                             if (base != null)
01649                                 relVars.add(base);
01650                         }
01651                         relVars.addAll(interferVars);
01652                         if (!interferVars.isEmpty()) {
01653                             generateNewCriterion(interferStmt.methodInfo, interferStmt.interferStmt, relVars);
01654                             addToSliceTrace(traceNode, interferStmt.interferStmt, Kind.INTERFER, interferStmt.methodInfo);
01655                             //Slicer.originalMethods.add(interferStmt.methodInfo);
01656                         }
01657                     }
01658                 }
01659             }
01660             //end of compute interference dependence interclassed
01661         }
01662     }
01663     if (goingup) {
01664         if (methodInfo.whoCallMe != null) {
01665             //if (Slicer.originalMethods.contains(methodInfo)) {
01666             for (Iterator callMeIt = methodInfo.whoCallMe.iterator(); callMeIt.hasNext();) {
01667                 CallSite callSite = (CallSite) callMeIt.next();
01668                 MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
01669                 if (callerMdInfo == null)
01670                     continue;
01671                 //if (existCallPathFromOriginalMd(callerMdInfo))
01672 
01673                 {
01674                     generateNewCriterionForCaller(callSite, methodInfo, relVarMap);
01675                     addToSliceTrace(Slicer.sliceTraceRoot, callSite.callStmt, Kind.WHOCALLME, callerMdInfo);
01676                     Slicer.originalMethods.add(callerMdInfo);
01677                 }
01678             }
01679             /*
01680             } else
01681             if (oneParaFdIsRelevant(methodInfo, relVarMap, sliceSet)) {
01682             if (methodInfo.whoCallMe.size() == 1) {
01683             for (Iterator callMeIt = methodInfo.whoCallMe.iterator(); callMeIt.hasNext();) {
01684             CallSite callSite = (CallSite) callMeIt.next();
01685             MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
01686             if (callerMdInfo == null)
01687             continue;
01688             generateNewCriterionForCaller(callSite, methodInfo, relVarMap);
01689             addToSliceTrace(Slicer.sliceTraceRoot, callSite.callStmt, Kind.WHOCALLME, callerMdInfo);
01690             }
01691             } else {
01692             for (Iterator callMeIt = methodInfo.whoCallMe.iterator(); callMeIt.hasNext();) {
01693             CallSite callSite = (CallSite) callMeIt.next();
01694             MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
01695             if (callerMdInfo == null)
01696             continue;
01697             if (callerIsRelevant(callSite)) {
01698             generateNewCriterionForCaller(callSite, methodInfo, relVarMap);
01699             addToSliceTrace(Slicer.sliceTraceRoot, callSite.callStmt, Kind.WHOCALLME, callerMdInfo);
01700             }
01701             }
01702             }
01703             }
01704             */
01705             /*
01706             if (!alreadyGenerateCriterionByWhoCallMe.contains(methodInfo))
01707             alreadyGenerateCriterionByWhoCallMe.add(methodInfo);
01708             */
01709         }
01710     }
01711 
01712 
01713     //generate criterion for method call
01714     //this also should be included in the slicing again method
01715     /* check the if the slice set contains some method call 
01716      for every method call genreate new criteria  */
01717     // make it as another method
01718 
01719     Set localCopiesList = getCompleteLocalCopiesList(methodInfo, linePropList);
01720     mdCallsInSlice(methodInfo, sliceSet, relVarMap, localCopiesList);
01721 
01722     //deal with ready call site
01723     for (Iterator siteIt = MethodCallAnalysis.directReadyForWaitCallSites.iterator(); siteIt.hasNext();) {
01724         CallSite callSite = (CallSite) siteIt.next();
01725         if (alreadyGenCritByReadyCallSite.contains(callSite))
01726             continue;
01727         Set relVarsOfCurrentMd = PostProcess.getRelevantLocals(stmtList, sliceSet, relVarMap);
01728         if (relVarsOfCurrentMd.contains(callSite.baseValue)) {
01729             //add the base of the invokation to the relevant variable set
01730             Set relVars = new ArraySet();
01731             Value base = getBaseFrom(callSite);
01732             if (base != null)
01733                 relVars.add(base);
01734             relVars.add(callSite.baseValue);
01735             MethodInfo callSiteMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
01736             if (callSiteMdInfo == null)
01737                 continue;
01738             generateNewCriterion(callSiteMdInfo, callSite.callStmt, relVars);
01739             addToSliceTrace(Slicer.sliceTraceRoot, callSite.callStmt, Kind.READY, callSiteMdInfo);
01740             alreadyGenCritByReadyCallSite.add(callSite);
01741             //originalMdsFromReadyCallSite.add(callSiteMdInfo);
01742         }
01743     }
01744 }
01745 /**
01746    * Slice one method again because of new generated slice criterion.
01747    */
01748 void slicingMethodAgain() {
01749     if (methodInfo.sCriterion == null) {
01750         methodInfo.sCriterion = methodInfo.increCriterion;
01751         methodInfo.increCriterion = null;
01752         /*
01753         if (Slicer.originalMethods.contains(methodInfo))
01754         slicingMethod(true);
01755         else
01756         */
01757         slicingMethod(true);
01758         return;
01759     }
01760     Set calculatedNodes = new ArraySet();
01761     BuildPDG methodPDG = methodInfo.methodPDG;
01762     LockAnalysis lockAnalysis = methodPDG.getLockAnalysis();
01763     SliceCriterion slCri = methodInfo.increCriterion;
01764     Set varList = slCri.getSliceVars();
01765     Set linePropList = slCri.getSlicePoints();
01766     Map newRelVarMap = slCri.relVarMap();
01767     Map relVarMap = methodInfo.sCriterion.relVarMap();
01768 
01769 
01770     //initialize the slice set with assignments to the relevant variables
01771     BitSet sliceSet = new BitSet(stmtListSize);
01772     BitSet originalSliceSet = methodInfo.sliceSet;
01773     if (originalSliceSet == null)
01774         originalSliceSet = new BitSet(stmtListSize);
01775     Set originalSliceStmtSet = SetUtil.bitSetToStmtSet(originalSliceSet, stmtList);
01776     LinkedList workList = new LinkedList(linePropList);
01777     addToWorkList(workList, sliceSet, calculatedNodes);
01778     sliceSet.or(SetUtil.stmtSetToBitSet(linePropList, stmtList));
01779 
01780     // put use variables of the node into relevant variable map
01781     // this if part may should be put out of the iteration as an
01782     // initialization of relVarMap
01783 
01784 
01785     Set removableNode = new ArraySet();
01786     for (Iterator workListIt = workList.iterator(); workListIt.hasNext();) {
01787         Stmt node = (Stmt) workListIt.next();
01788         if (!linePropList.contains(node)) {
01789             if (originalSliceStmtSet.contains(node)) {
01790                 removableNode.add(node);
01791                 sliceSet.clear(stmtList.indexOf(node));
01792             } else {
01793                 Set relVarsOfNode = refVarsOf(node);
01794                 Set temp = new ArraySet();
01795                 if (relVarMap.containsKey(node))
01796                     temp = (Set) relVarMap.get(node);
01797                 relVarsOfNode.addAll(temp);
01798                 relVarMap.put(node, relVarsOfNode);
01799             }
01800         } else {
01801             Set relVarsOfNode = (Set) newRelVarMap.get(node);
01802             if (originalSliceStmtSet.contains(node)) {
01803                 Set temp = (Set) relVarMap.get(node);
01804                 if (!temp.equals(relVarsOfNode)) {
01805                     Set relVars = new ArraySet();
01806                     relVars.addAll(relVarsOfNode);
01807                     relVars.addAll(temp);
01808                     relVarMap.put(node, relVars);
01809                 } else {
01810                     removableNode.add(node);
01811                     sliceSet.clear(stmtList.indexOf(node));
01812                 }
01813             } else
01814                 relVarMap.put(node, relVarsOfNode);
01815     }
01816 }
01817 
01818 //remove all removable nodes from workList
01819 
01820 workList.removeAll(removableNode);
01821 if (workList.isEmpty())
01822     return;
01823 addToSliceTrace(Slicer.sliceTraceRoot, workList, Kind.CRITERION, methodInfo);
01824 while (!workList.isEmpty()) {
01825     Stmt node = (Stmt) workList.removeFirst();
01826     SliceTraceNode traceNode = sliceTraceContains(new SliceTraceNode(methodInfo, node));
01827     if (traceNode == null) {
01828         System.out.println("traceNode for " + node + " is null! in SliceAgain");
01829     }
01830     calculatedNodes.add(node);
01831     Set ddNodes = methodPDG.dataNodesOf(node);
01832 
01833     //add computation of relevant variables
01834     //after data relevant varibal comp, ddNodes set may be changed
01835 
01836 
01837     // put use variables of the node into relevant variable map
01838     // this if part may should be put out of the iteration as an
01839     // initialization of relVarMap
01840 
01841     ddNodes = dataRelVarCompute(relVarMap, node, ddNodes);
01842     BitSet ddIndexSet = indexSetOf(ddNodes);
01843     sliceSet.or(ddIndexSet);
01844     addToWorkList(workList, ddIndexSet, calculatedNodes);
01845     addToSliceTrace(traceNode, ddIndexSet, Kind.DATA, methodInfo);
01846     BitSet cdNodes = methodPDG.controlNodesOf(node);
01847     if (cdNodes != null) {
01848         ctrlRelVarCompute(relVarMap, node, cdNodes);
01849         sliceSet.or(cdNodes);
01850         addToWorkList(workList, cdNodes, calculatedNodes);
01851         addToSliceTrace(traceNode, cdNodes, Kind.CONTROL, methodInfo);
01852     }
01853     BitSet preDivergenceNodes = methodPDG.preDivergencePointsOf(node);
01854     if (preDivergenceNodes != null) {
01855         ctrlRelVarCompute(relVarMap, node, preDivergenceNodes);
01856         sliceSet.or(preDivergenceNodes);
01857         addToWorkList(workList, preDivergenceNodes, calculatedNodes);
01858         addToSliceTrace(traceNode, preDivergenceNodes, Kind.DIVERGENCE, methodInfo);
01859     }
01860     //compute ready dependcy on call site
01861 
01862     //is the current node reachible from any possible ... call site?
01863     /*
01864     BitSet readyCallSites = readyDependOnCallSite(methodInfo.possibleReadyDependCallSite, node);
01865     if (!SetUtil.emptyBitSet(readyCallSites)) {
01866     ctrlRelVarCompute(relVarMap, node, readyCallSites);
01867     sliceSet.or(readyCallSites);
01868     addToWorkList(workList, readyCallSites, calculatedNodes);
01869     addToSliceTrace(traceNode, readyCallSites, Kind.READY, methodInfo);
01870     }
01871     */
01872 
01873     if (lockAnalysis != null) {
01874         //compute synchronization dependence
01875         BitSet monitorSet = lockAnalysis.dependOnMonitorSet(node);
01876         if (!SetUtil.emptyBitSet(monitorSet)) {
01877             ctrlRelVarCompute(relVarMap, node, monitorSet);
01878             sliceSet.or(monitorSet);
01879             addToWorkList(workList, monitorSet, calculatedNodes);
01880             addToSliceTrace(traceNode, monitorSet, Kind.SYNCH, methodInfo);
01881         }
01882 
01883         //compute ready dependence on entermonitor statement
01884         //within one method
01885         //if the lock is not safe (determined in lockAnalysis)
01886         //ready dependence within class
01887 
01888         //compute ready dependence on wait statement
01889         //within class
01890         BitSet waitSet = lockAnalysis.readyDependOnWaits(node);
01891         if (!SetUtil.emptyBitSet(waitSet)) {
01892             ctrlRelVarCompute(relVarMap, node, waitSet);
01893             sliceSet.or(waitSet);
01894             addToWorkList(workList, waitSet, calculatedNodes);
01895             addToSliceTrace(traceNode, waitSet, Kind.READY, methodInfo);
01896             //lookup the notify stmt corresponding to those wait stmt in waitSet within the method, that means wait/notify ready dependence within method
01897             /*
01898             BitSet notifySet = waitNotifyWithinMd(waitSet, lockAnalysis.getWaitStmtList(), lockAnalysis.getNotifyStmtList());
01899             if (!SetUtil.emptyBitSet(notifySet)) {
01900             ctrlRelVarCompute(relVarMap, node, notifySet);
01901             sliceSet.or(notifySet);
01902             addToWorkList(workList, notifySet, calculatedNodes);
01903             addToSliceTrace(traceNode, notifySet, Kind.READY, methodInfo);
01904             }
01905             */
01906         }
01907     }
01908     if (Slicer.classNum > 1) {
01909         //compute ready dependence
01910         //interclass
01911         if (node instanceof EnterMonitorStmt) {
01912 
01913             // *****************************************************
01914             //     this is different from the slicing method
01915             // *****************************************************
01916         } else {
01917             Map readyDependMap = methodPDG.getReadyDependMap();
01918             if (readyDependMap != null) {
01919                 if (readyDependMap.containsKey(node)) {
01920                     List readyDependStmt = (List) readyDependMap.get(node);
01921                     for (Iterator readyIt = readyDependStmt.iterator(); readyIt.hasNext();) {
01922                         ReadyDependStmt readyStmt = (ReadyDependStmt) readyIt.next();
01923                         generateNewCriterion(readyStmt.methodInfo, readyStmt.readyOnStmt, refVarsOf(readyStmt.readyOnStmt));
01924                         addToSliceTrace(traceNode, readyStmt.readyOnStmt, Kind.READY, readyStmt.methodInfo);
01925                     }
01926                 }
01927             }
01928         }
01929 
01930         //compute interference dependence
01931         //interclass
01932 
01933         if (!(node instanceof InvokeStmt) && (!linePropList.contains(node)))
01934 
01935 
01936 
01937 
01938 
01939 
01940 
01941 
01942             
01943             //add this condition on 10/19/99 in slicingMethod()
01944             //and slicingMethodAgain()
01945             {
01946             Map interferDependMap = methodPDG.getInterferenceMap();
01947             if (interferDependMap.containsKey(node)) {
01948                 Set relVarsOfNode = (Set) relVarMap.get(node);
01949                 List interferDependStmt = (List) interferDependMap.get(node);
01950                 for (Iterator interferIt = interferDependStmt.iterator(); interferIt.hasNext();) {
01951                     InterferStmt interferStmt = (InterferStmt) interferIt.next();
01952                     Set interferVars = interferStmt.interferVars;
01953                     Set relVars = refVarsOf(interferStmt.interferStmt);
01954                     CallSite site = isCallSite(interferStmt.methodInfo.indexMaps.getCallSiteMap(), interferStmt.interferStmt);
01955                     if (site != null) {
01956                         //add the base of the invokation to the relevant variable set
01957                         relVars = new ArraySet();
01958                         Value base = getBaseFrom(site);
01959                         if (base != null)
01960                             relVars.add(base);
01961                     }
01962                     relVars.addAll(interferVars);
01963                     if (!interferVars.isEmpty()) {
01964                         generateNewCriterion(interferStmt.methodInfo, interferStmt.interferStmt, relVars);
01965                         addToSliceTrace(traceNode, interferStmt.interferStmt, Kind.INTERFER, interferStmt.methodInfo);
01966                     }
01967                 }
01968             }
01969         }
01970     }
01971 }
01972 Set localCopiesList = getCompleteLocalCopiesList(methodInfo, linePropList);
01973 mdCallsInSlice(methodInfo, sliceSet, relVarMap, localCopiesList);
01974 sliceSet.or(originalSliceSet);
01975 methodInfo.sliceSet = sliceSet;
01976 //Set localCopiesList = getCompleteLocalCopiesList(methodInfo, linePropList);
01977 //mdCallsInSlice(methodInfo, sliceSet, relVarMap, localCopiesList);
01978 
01979 //chage the incremental criterion to null after using it.
01980 methodInfo.increCriterion = null;
01981 
01982 
01983 //deal with ready call site
01984 for (Iterator siteIt = MethodCallAnalysis.directReadyForWaitCallSites.iterator(); siteIt.hasNext();) {
01985     CallSite callSite = (CallSite) siteIt.next();
01986     if (alreadyGenCritByReadyCallSite.contains(callSite))
01987         continue;
01988     Set relVarsOfCurrentMd = PostProcess.getRelevantLocals(stmtList, sliceSet, relVarMap);
01989     if (relVarsOfCurrentMd.contains(callSite.baseValue)) {
01990         //add the base of the invokation to the relevant variable set
01991         Set relVars = new ArraySet();
01992         Value base = getBaseFrom(callSite);
01993         if (base != null)
01994             relVars.add(base);
01995         relVars.add(callSite.baseValue);
01996         MethodInfo callSiteMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
01997         if (callSiteMdInfo == null)
01998             continue;
01999         generateNewCriterion(callSiteMdInfo, callSite.callStmt, relVars);
02000         addToSliceTrace(Slicer.sliceTraceRoot, callSite.callStmt, Kind.READY, callSiteMdInfo);
02001         alreadyGenCritByReadyCallSite.add(callSite);
02002         //originalMdsFromReadyCallSite.add(callSiteMdInfo);
02003     }
02004 }
02005 //System.out.println("slicing method again: " + methodInfo.sootMethod);
02006 //System.out.println("slice set: " + sliceSet);
02007 }
02008 private Stmt startNodeAfterSlicing(MethodInfo methodInfo) {
02009     BuildPDG methodPDG = methodInfo.methodPDG;
02010     if (methodInfo.sliceSet == null)
02011         return ((Stmt) stmtList.get(0));
02012     int startStmtIndex = 0;
02013     while (!methodInfo.sliceSet.get(startStmtIndex))
02014         startStmtIndex = methodPDG.immediatePostdominatorOf(startStmtIndex);
02015     return ((Stmt) stmtList.get(startStmtIndex));
02016 }
02017 private void staticFdInTargetMd(Set relVarsAtCallSite, Set fdsInTargetMd, Set relVarsInTargetMd) {
02018     for (Iterator i =  fdsInTargetMd.iterator(); i.hasNext();) {
02019         Value field = (Value) i.next();
02020         if (relVarsAtCallSite.contains(field))
02021             relVarsInTargetMd.add(field);
02022     }
02023 }
02024 /**
02025  * Insert the method's description here.
02026  * Creation date: (00-8-3 7:22:29)
02027  * @return boolean
02028  * @param vars ca.mcgill.sable.util.Set
02029  * @param cs edu.ksu.cis.bandera.pdgslicer.CallSite
02030  */
02031 private boolean varsContainArg(Set vars, CallSite cs) {
02032     InvokeExpr iepr = cs.invokeExpr;
02033     for (int i=0; i<iepr.getArgCount(); i++)
02034     {
02035         if (vars.contains(iepr.getArg(i))) return true;
02036     }
02037     return false;
02038 }
02039 }

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