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.util.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040
00041 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00042
00043 import java.util.Enumeration;
00044
00045
00046
00047
00048
00049 public class InterClassAnalysis
00050 {
00051
00052
00053
00054 private List classList;
00055
00056
00057
00058
00059
00060
00061
00062
00063 public InterClassAnalysis(List cl) {
00064 classList = cl;
00065 readyDependence();
00066 interferenceDependence();
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 private void checkOneMdForInsFdsNotInCurrentClass(Map interferenceMap, MethodInfo methodInfo, Set interferRefList) {
00079 SootClass currentModClass = methodInfo.sootClass;
00080 List onInterferDefList = new ArrayList();
00081 onInterferDefList.addAll(methodInfo.MOD.instanceFields);
00082 onInterferDefList.addAll(methodInfo.MOD.otherInsFds);
00083 if (onInterferDefList.isEmpty()) return;
00084
00085 for (Iterator interRefIt = interferRefList.iterator(); interRefIt.hasNext();) {
00086 DataBox interRefBox = (DataBox) interRefIt.next();
00087 Stmt interferStmt = (Stmt) interRefBox.getInterferStmt();
00088 Set interferVars = (Set) interRefBox.getInterferVars();
00089 for (Iterator insFdIt = interferVars.iterator(); insFdIt.hasNext();) {
00090 InstanceFieldRef refField = (InstanceFieldRef) insFdIt.next();
00091 SootClass decClass = refField.getField().getDeclaringClass();
00092
00093 for (Iterator onInterDefIt = onInterferDefList.iterator(); onInterDefIt.hasNext();) {
00094 DataBox onInterDefBox = (DataBox) onInterDefIt.next();
00095 Set onInterVars = onInterDefBox.getInterferVars();
00096 Set actualInterVars = containsField(onInterVars, refField.getField());
00097 if (!actualInterVars.isEmpty()) {
00098
00099 Stmt onStmt = (Stmt) onInterDefBox.getInterferStmt();
00100 InterferStmt onInterStmt = new InterferStmt(methodInfo, onStmt, actualInterVars);
00101 List interferList = (List) interferenceMap.get(interferStmt);
00102 interferList.add(onInterStmt);
00103 }
00104 }
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 private void checkOneMethod(Map interferenceMap, MethodInfo methodInfo, Set interferRefList, boolean haveInstanceField) {
00121 Set staticDefList = methodInfo.MOD.staticFields;
00122 List onInterferDefList = new ArrayList();
00123 onInterferDefList.addAll(staticDefList);
00124 if (haveInstanceField)
00125 onInterferDefList.addAll(methodInfo.MOD.instanceFields);
00126 if (onInterferDefList.isEmpty()) return;
00127
00128 for (Iterator interRefIt = interferRefList.iterator(); interRefIt.hasNext();) {
00129 DataBox interRefBox = (DataBox) interRefIt.next();
00130 Stmt interferStmt = (Stmt) interRefBox.getInterferStmt();
00131 Set interferRefs = (Set) interRefBox.getInterferVars();
00132 Set interferVars = BuildPDG.fieldRefToSootField(interferRefs);
00133 for (Iterator onInterDefIt = onInterferDefList.iterator(); onInterDefIt.hasNext();) {
00134 DataBox onInterDefBox = (DataBox) onInterDefIt.next();
00135 Set onInterRefs = onInterDefBox.getInterferVars();
00136 Set onInterVars = BuildPDG.fieldRefToSootField(onInterRefs);
00137 Set actualInterVars = SetUtil.setIntersection(interferVars, onInterVars);
00138 if (!actualInterVars.isEmpty()) {
00139
00140 Stmt onStmt = (Stmt) onInterDefBox.getInterferStmt();
00141 InterferStmt onInterStmt = new InterferStmt(methodInfo, onStmt, actualInterVars);
00142 List interferList = (List) interferenceMap.get(interferStmt);
00143 interferList.add(onInterStmt);
00144 }
00145 }
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 private Set containsField(Set insFdSet, SootField sf) {
00156 Set conSet = new ArraySet();
00157 for (Iterator fdIt = insFdSet.iterator(); fdIt.hasNext();) {
00158 InstanceFieldRef insFd = (InstanceFieldRef) fdIt.next();
00159 SootField fd = insFd.getField();
00160 if (sf.equals(fd)) {
00161 conSet.add(insFd);
00162 return conSet;
00163 }
00164 }
00165 return conSet;
00166 }
00167
00168
00169
00170
00171
00172
00173 private void initInterferenceMap(Set fieldRefList, Map interfMap) {
00174 for (Iterator interStmtIt = fieldRefList.iterator(); interStmtIt.hasNext();) {
00175 DataBox stmtBox = (DataBox) interStmtIt.next();
00176 Stmt stmt = stmtBox.getInterferStmt();
00177 interfMap.put(stmt, new ArrayList());
00178 }
00179 }
00180
00181
00182
00183
00184 private void interferenceDependence() {
00185 Map sootMethodInfoMap = Slicer.sootMethodInfoMap;
00186 for (Iterator mdIt = sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00187 SootMethod sootMethod = (SootMethod) mdIt.next();
00188
00189 MethodInfo methodInfo = (MethodInfo) sootMethodInfoMap.get(sootMethod);
00190 if (methodInfo == null)
00191 continue;
00192 BuildPDG methodPDG = methodInfo.methodPDG;
00193
00194
00195 Map interferenceMap = interferForMethod(methodInfo);
00196 methodPDG.setInterferenceMap(interferenceMap);
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 private Map interferForMethod(MethodInfo currentMethod) {
00214 Set staticFdRefList = currentMethod.REF.staticFields;
00215
00216 Set instanceFdRefList = currentMethod.REF.instanceFields;
00217 Set otherInsFdsRefList = currentMethod.REF.otherInsFds;
00218 Map interferenceMap = new HashMap();
00219
00220
00221
00222
00223
00224
00225 initInterferenceMap(instanceFdRefList, interferenceMap);
00226 initInterferenceMap(staticFdRefList, interferenceMap);
00227
00228 initInterferenceMap(otherInsFdsRefList, interferenceMap);
00229
00230
00231
00232
00233
00234 for (Iterator classIter = classList.iterator(); classIter.hasNext();) {
00235 ClassInfo classInfo = (ClassInfo) classIter.next();
00236 if (!classInfo.sootClass.equals(currentMethod.sootClass)) {
00237 for (Iterator methodIt = classInfo.methodsInfoList.iterator(); methodIt.hasNext();) {
00238 MethodInfo methodInfo = (MethodInfo) methodIt.next();
00239 checkOneMethod(interferenceMap, methodInfo, instanceFdRefList, true);
00240 checkOneMethod(interferenceMap, methodInfo, staticFdRefList, false);
00241
00242 checkOneMdForInsFdsNotInCurrentClass(interferenceMap, methodInfo, otherInsFdsRefList);
00243 }
00244 } else {
00245 lookupInterferDefStmt(classInfo, interferenceMap, currentMethod);
00246 }
00247 }
00248 return interferenceMap;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 private void lookupInterferDefStmt(ClassInfo classInfo, Map interferenceMap, MethodInfo currentMdInfo) {
00259 String className = classInfo.sootClass.getName();
00260 Set staticFdRefList = currentMdInfo.REF.staticFields;
00261 Set instanceFdRefList = currentMdInfo.REF.instanceFields;
00262 Set otherInsFdsRefList = currentMdInfo.REF.otherInsFds;
00263 LockAnalysis lockAnaOfCurrentMd = currentMdInfo.methodPDG.getLockAnalysis();
00264 boolean initiated = false;
00265 boolean haveInstanceFd = false;
00266 for (Iterator methodIt = classInfo.methodsInfoList.iterator(); methodIt.hasNext();) {
00267 MethodInfo methodInfo = (MethodInfo) methodIt.next();
00268 if (methodInfo.equals(currentMdInfo))
00269 continue;
00270 haveInstanceFd = false;
00271 Set interferRefList = new ArraySet();
00272 interferRefList.addAll(staticFdRefList);
00273 LockAnalysis lockAnaOfDefMd = methodInfo.methodPDG.getLockAnalysis();
00274 if (methodInfo.sootMethod.getName().equals("<init>") || methodInfo.sootMethod.getName().equals("<clinit>")) {
00275 interferRefList.addAll(instanceFdRefList);
00276 haveInstanceFd = true;
00277
00278
00279
00280
00281
00282
00283 } else {
00284
00285
00286
00287
00288 interferRefList.addAll(instanceFdRefList);
00289 haveInstanceFd = true;
00290
00291
00292
00293
00294
00295
00296
00297 }
00298 if (!haveInstanceFd)
00299 checkOneMethod(interferenceMap, methodInfo, staticFdRefList, haveInstanceFd);
00300 else {
00301 checkOneMethod(interferenceMap, methodInfo, interferRefList, haveInstanceFd);
00302 }
00303 checkOneMdForInsFdsNotInCurrentClass(interferenceMap, methodInfo, otherInsFdsRefList);
00304 }
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 private void lookupReadyDependStmt(Map readyMap, List methodsList, MethodInfo currentMethodInfo, List lockPairList, List waitStmtList) {
00321 for (Iterator methodIt = methodsList.iterator(); methodIt.hasNext();) {
00322 MethodInfo methodInfo = (MethodInfo) methodIt.next();
00323 if (currentMethodInfo.equals(methodInfo))
00324 continue;
00325 BuildPDG methodPDG = methodInfo.methodPDG;
00326 LockAnalysis lockAnalysis = methodPDG.getLockAnalysis();
00327 if (lockAnalysis == null)
00328 continue;
00329 List onLockPairList = lockAnalysis.getLockPairList();
00330 List notifyStmtList = lockAnalysis.getNotifyStmtList();
00331
00332 for (Iterator lockPairIt = lockPairList.iterator(); lockPairIt.hasNext();) {
00333 MonitorPair monitorPair = (MonitorPair) lockPairIt.next();
00334 Value lockValue = monitorPair.getLock();
00335 Stmt enterStmt = (Stmt) monitorPair.getEnterMonitor();
00336 for (Iterator onLockPairIt = onLockPairList.iterator(); onLockPairIt.hasNext();) {
00337 MonitorPair onMonitorPair = (MonitorPair) onLockPairIt.next();
00338 Value onLockValue = onMonitorPair.getLock();
00339 if (BuildPDG.mayPointToTheSameRef(lockValue, onLockValue, currentMethodInfo.sootMethod, methodInfo.sootMethod)) {
00340
00341 for (Iterator exitIt = onMonitorPair.getExitMonitors().iterator(); exitIt.hasNext();) {
00342 Stmt exitStmt = (Stmt) exitIt.next();
00343 ReadyDependStmt onExitStmt = new ReadyDependStmt(methodInfo, exitStmt);
00344 List readyList = (List) readyMap.get(enterStmt);
00345 readyList.add(onExitStmt);
00346 }
00347 }
00348 }
00349 }
00350
00351
00352
00353 for (Iterator waitIt = waitStmtList.iterator(); waitIt.hasNext();) {
00354 SynchroStmt synStmt = (SynchroStmt) waitIt.next();
00355 Value lockValue = synStmt.getLock();
00356 Stmt waitStmt = synStmt.getWaitNotify();
00357 for (Iterator notifyStmtIt = notifyStmtList.iterator(); notifyStmtIt.hasNext();) {
00358 SynchroStmt onSynStmt = (SynchroStmt) notifyStmtIt.next();
00359 Value onLockValue = onSynStmt.getLock();
00360 if (BuildPDG.mayPointToTheSameRef(lockValue, onLockValue, currentMethodInfo.sootMethod, methodInfo.sootMethod)) {
00361
00362 Stmt notifyStmt = onSynStmt.getWaitNotify();
00363 ReadyDependStmt onNotifyStmt = new ReadyDependStmt(methodInfo, notifyStmt);
00364 List readyList = (List) readyMap.get(waitStmt);
00365 readyList.add(onNotifyStmt);
00366 }
00367 }
00368 }
00369 }
00370 }
00371
00372
00373
00374
00375 private void readyDependence() {
00376 Map sootMethodInfoMap = Slicer.sootMethodInfoMap;
00377 for (Iterator mdIt = sootMethodInfoMap.keySet().iterator(); mdIt.hasNext();) {
00378 SootMethod sootMethod = (SootMethod) mdIt.next();
00379 MethodInfo methodInfo = (MethodInfo) sootMethodInfoMap.get(sootMethod);
00380 if (methodInfo == null) continue;
00381 BuildPDG methodPDG = methodInfo.methodPDG;
00382 LockAnalysis lockAnalysis = methodPDG.getLockAnalysis();
00383 if (lockAnalysis == null) {
00384 methodPDG.setReadyDependMap(null);
00385 continue;
00386 }
00387 List lockPairList = lockAnalysis.getLockPairList();
00388 List waitStmtList = lockAnalysis.getWaitStmtList();
00389 Map readyMap = readyForMethod(methodInfo, lockPairList, waitStmtList);
00390 methodPDG.setReadyDependMap(readyMap);
00391 }
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 private Map readyForMethod(MethodInfo currentMethod, List lockPairList, List waitStmtList) {
00407 Map readyMap = new HashMap();
00408
00409
00410
00411 for (Iterator lockIt = lockPairList.iterator(); lockIt.hasNext();) {
00412 MonitorPair mp = (MonitorPair) lockIt.next();
00413 Stmt mpStmt = (Stmt) mp.getEnterMonitor();
00414 readyMap.put(mpStmt, new ArrayList());
00415 }
00416 for (Iterator waitIt = waitStmtList.iterator(); waitIt.hasNext();) {
00417 SynchroStmt synStmt = (SynchroStmt) waitIt.next();
00418 Stmt waitStmt = synStmt.getWaitNotify();
00419 readyMap.put(waitStmt, new ArrayList());
00420 }
00421 for (Iterator classIter = classList.iterator(); classIter.hasNext();) {
00422 ClassInfo classInfo = (ClassInfo) classIter.next();
00423 lookupReadyDependStmt(readyMap, classInfo.methodsInfoList, currentMethod, lockPairList, waitStmtList);
00424 }
00425 return readyMap;
00426 }
00427 }