00001 package edu.ksu.cis.bandera.pdgslicer;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 import ca.mcgill.sable.soot.jimple.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.util.*;
00040 import edu.ksu.cis.bandera.annotation.*;
00041 import java.util.BitSet;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 public class MethodCallAnalysis {
00053 static Set directReadyForWaitCallSites;
00054 public MethodCallAnalysis() {
00055
00056 Map callMeSiteMap = buildCallMeSiteMap();
00057 distributeToMdInfo(callMeSiteMap);
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 static boolean allCalculated(SootMethod sm, Map callSiteMap, Set caledMdSet) {
00073 for (Iterator siteIt = callSiteMap.keySet().iterator(); siteIt.hasNext();) {
00074 CallSite site = (CallSite) siteIt.next();
00075 SootMethod calledMd = (SootMethod) callSiteMap.get(site);
00076
00077 if (caledMdSet.contains(calledMd) || calledMd==sm)
00078 continue;
00079 else if (Slicer.sootMethodInfoMap.get(calledMd) == null)
00080 continue;
00081
00082 else
00083 return false;
00084 }
00085 return true;
00086 }
00087
00088
00089
00090
00091
00092
00093 private void assignmentByMdCall(MethodInfo mdInfo)
00094
00095 {
00096 StmtList stmtList = mdInfo.originalStmtList;
00097 IndexMaps indexMaps = mdInfo.indexMaps;
00098 Map localAssMap = indexMaps.localAssMap();
00099
00100
00101 Fields defFields = mdInfo.MOD;
00102 for (Iterator i = defFields.staticFields.iterator(); i.hasNext();) {
00103 DataBox dbx = (DataBox) i.next();
00104 Stmt defStmt = dbx.getInterferStmt();
00105 for (Iterator j = dbx.getInterferVars().iterator(); j.hasNext();) {
00106 Value stcField = (Value) j.next();
00107 BitSet defSet = new BitSet(stmtList.size());
00108 defSet.set(stmtList.indexOf(defStmt));
00109 if (localAssMap.containsKey(stcField))
00110 defSet.or((BitSet) localAssMap.get(stcField));
00111 localAssMap.put(stcField, defSet);
00112 }
00113 }
00114 for (Iterator i = defFields.instanceFields.iterator(); i.hasNext();) {
00115 DataBox dbx = (DataBox) i.next();
00116 Stmt defStmt = dbx.getInterferStmt();
00117 for (Iterator j = dbx.getInterferVars().iterator(); j.hasNext();) {
00118 InstanceFieldRef insField = (InstanceFieldRef) j.next();
00119 BitSet defSet = new BitSet(stmtList.size());
00120 defSet.set(stmtList.indexOf(defStmt));
00121 if (localAssMap.containsKey(insField))
00122 defSet.or((BitSet) localAssMap.get(insField));
00123 localAssMap.put(insField, defSet);
00124 }
00125 }
00126
00127
00128
00129
00130 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00131 for (Iterator siteIt = callSiteMap.keySet().iterator(); siteIt.hasNext();) {
00132 CallSite site = (CallSite) siteIt.next();
00133 InvokeExpr invokeExpr = site.invokeExpr;
00134 SootMethod calledMd = (SootMethod) callSiteMap.get(site);
00135 MethodInfo calledMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(calledMd);
00136 if (calledMdInfo == null)
00137 continue;
00138 defFields = calledMdInfo.MOD;
00139 Stmt callSiteStmt = site.callStmt;
00140 Set defParas = Fields.parametersLocalize(calledMdInfo, defFields, invokeExpr);
00141 Set defInstanceField = new ArraySet();
00142 if (invokeExpr instanceof NonStaticInvokeExpr) {
00143 NonStaticInvokeExpr nsie = (NonStaticInvokeExpr) invokeExpr;
00144
00145
00146 Set modFields = SlicingMethod.allMODREFFields(defFields.instanceFields, new ArraySet());
00147 defInstanceField = BuildPDG.cloneAndChangeBase(modFields, nsie.getBase());
00148 }
00149 Set defFieldsAtCallSite = new ArraySet();
00150 defFieldsAtCallSite.addAll(defParas);
00151 defFieldsAtCallSite.addAll(defInstanceField);
00152 for (Iterator i = defFieldsAtCallSite.iterator(); i.hasNext();) {
00153 InstanceFieldRef field = (InstanceFieldRef) i.next();
00154 BitSet defSet = new BitSet(stmtList.size());
00155 defSet.set(stmtList.indexOf(callSiteStmt));
00156 if (localAssMap.containsKey(field))
00157 defSet.or((BitSet) localAssMap.get(field));
00158 localAssMap.put(field, defSet);
00159 }
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 private Map buildCallMeSiteMap() {
00171 Map callMeSiteMap = new HashMap();
00172 for (Iterator mdIt = Slicer.sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00173 SootMethod sootMethod = (SootMethod) mdIt.next();
00174 MethodInfo mdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00175 if (mdInfo == null) continue;
00176 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00177 for (Iterator siteIt = callSiteMap.keySet().iterator(); siteIt.hasNext();) {
00178 CallSite site = (CallSite) siteIt.next();
00179 SootMethod calledMd = (SootMethod) callSiteMap.get(site);
00180 Set callMeSet = new ArraySet();
00181 callMeSet.add(site);
00182 if (callMeSiteMap.containsKey(calledMd)) {
00183 Set prevCallMeSet = (Set) callMeSiteMap.get(calledMd);
00184 callMeSet.addAll(prevCallMeSet);
00185 }
00186 callMeSiteMap.put(calledMd, callMeSet);
00187 }
00188 }
00189 return callMeSiteMap;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 void buildMethodPDG(AnnotationManager cfanns)
00204
00205
00206 {
00207 for (Iterator mdIt = Slicer.sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00208 SootMethod sootMethod = (SootMethod) mdIt.next();
00209 MethodInfo mdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(sootMethod);
00210 if (mdInfo == null) continue;
00211 assignmentByMdCall(mdInfo);
00212
00213 BuildPDG methodPDG = new BuildPDG(mdInfo, cfanns);
00214 mdInfo.methodPDG = methodPDG;
00215 LockAnalysis lockAnalysis = new LockAnalysis(mdInfo, cfanns);
00216 collectPossibleReadyDependCallSite(mdInfo);
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 private void collectPossibleReadyDependCallSite(MethodInfo mdInfo) {
00230 LockAnalysis lockAnalysis = mdInfo.methodPDG.getLockAnalysis();
00231 if (lockAnalysis == null)
00232 return;
00233 List waitStmtList = lockAnalysis.getWaitStmtList();
00234 if (waitStmtList.size() == 0)
00235 return;
00236 Set whoCallMe = mdInfo.whoCallMe;
00237 if ((whoCallMe == null) || (whoCallMe.size() == 0))
00238 return;
00239 List workSet = new ArrayList();
00240 Set visitedCallSite = new ArraySet();
00241
00242 workSet.addAll(whoCallMe);
00243 while (workSet.size() != 0) {
00244 CallSite callSite = (CallSite) workSet.get(0);
00245 workSet.remove(callSite);
00246 if (visitedCallSite.contains(callSite))
00247 continue;
00248 visitedCallSite.add(callSite);
00249 MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
00250 if (callerMdInfo != null){
00251 callerMdInfo.possibleReadyDependCallSite.add(callSite);
00252 }
00253
00254
00255
00256
00257
00258
00259 }
00260
00261 for (Iterator siteIt = mdInfo.whoCallMe.iterator(); siteIt.hasNext();) {
00262 CallSite callSite = (CallSite) siteIt.next();
00263 callSite.baseValue = getBaseValueFrom(callSite);
00264 if (callSite.baseValue != null)
00265 MethodCallAnalysis.directReadyForWaitCallSites.add(callSite);
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 private void distributeToMdInfo(Map callMeMap) {
00277 for (Iterator calledIt = callMeMap.keySet().iterator(); calledIt.hasNext();) {
00278 SootMethod calledMethod = (SootMethod) calledIt.next();
00279 Set callSites = (Set) callMeMap.get(calledMethod);
00280 MethodInfo mdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(calledMethod);
00281 if (mdInfo != null){
00282 mdInfo.whoCallMe = callSites;
00283 }
00284 }
00285 }
00286
00287
00288
00289
00290
00291
00292 private Value getBaseValueFrom(CallSite callSite) {
00293 Value base = null;
00294 InvokeExpr invoke = callSite.invokeExpr;
00295 if (invoke instanceof NonStaticInvokeExpr)
00296 base = ((NonStaticInvokeExpr) invoke).getBase();
00297 if (base != null) {
00298 MethodInfo callerMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callSite.callerSootMethod);
00299 if (callerMdInfo != null)
00300 return base;
00301 }
00302 return base;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 private void mergeFields(MethodInfo mdInfo, MethodInfo calledMdInfo, CallSite site) {
00312 Fields MOD = mdInfo.MOD;
00313 Fields REF = mdInfo.REF;
00314 Fields MODInCalled = calledMdInfo.MOD;
00315 Fields REFInCalled = calledMdInfo.REF;
00316 MOD.merge(MODInCalled, site, mdInfo, calledMdInfo);
00317 REF.merge(REFInCalled, site, mdInfo, calledMdInfo);
00318 }
00319
00320
00321
00322
00323
00324
00325 void MODREFAnalysis() {
00326 boolean hasNewCalculated = true;
00327 Set calculatedMdSet = new ArraySet();
00328 Map sootMethodInfoMap = Slicer.sootMethodInfoMap;
00329
00330 for (Iterator mdIt = sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00331 SootMethod sootMethod = (SootMethod) mdIt.next();
00332 MethodInfo mdInfo = (MethodInfo) sootMethodInfoMap.get(sootMethod);
00333 if (mdInfo== null) continue;
00334 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00335 if (callSiteMap.size() == 0)
00336 calculatedMdSet.add(sootMethod);
00337 }
00338 while (hasNewCalculated) {
00339 hasNewCalculated = false;
00340 for (Iterator mdIt = sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00341 SootMethod currentMd = (SootMethod) mdIt.next();
00342 MethodInfo mdInfo = (MethodInfo) sootMethodInfoMap.get(currentMd);
00343 if (calculatedMdSet.contains(currentMd))
00344 continue;
00345 else {
00346 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00347 if (allCalculated(mdInfo.sootMethod, callSiteMap, calculatedMdSet)) {
00348 for (Iterator siteIt = callSiteMap.keySet().iterator(); siteIt.hasNext();) {
00349 CallSite site = (CallSite) siteIt.next();
00350 SootMethod calledMd = (SootMethod) callSiteMap.get(site);
00351 MethodInfo calledMdInfo = (MethodInfo) sootMethodInfoMap.get(calledMd);
00352 if (calledMdInfo != null)
00353 mergeFields(mdInfo, calledMdInfo, site);
00354 }
00355 calculatedMdSet.add(currentMd);
00356 } else{
00357
00358 hasNewCalculated = true;
00359 }
00360 }
00361 }
00362 }
00363 }
00364 }