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
00038
00039
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
00050
00051
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
00061
00062
00063 private Set originalMethodsFromReady = new ArraySet();
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static Set alreadyGenCritByReadyCallSite;
00074
00075
00076
00077
00078
00079 static Set alreadyGenerateCriterionForExits;
00080
00081
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
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
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
00168
00169
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
00200
00201
00202
00203
00204
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
00217
00218
00219
00220
00221 static Set allLocalVarsOf(Stmt stmt) {
00222 Set buff = refVarsOf(stmt);
00223 buff.addAll(defVarsOf(stmt));
00224 return buff;
00225 }
00226
00227
00228
00229
00230
00231
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
00247
00248
00249
00250
00251
00252
00253
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
00269
00270
00271
00272
00273
00274
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
00289
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
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
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
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
00349
00350
00351
00352
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
00370
00371
00372
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
00386
00387
00388
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
00403
00404
00405
00406
00407
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
00416 Stmt controlNode = (Stmt) stmtList.get(i);
00417 Set refsOfNode = refVarsOf(controlNode);
00418 CallSite site = isCallSite(indexMaps.getCallSiteMap(), controlNode);
00419 if (site != null) {
00420
00421 refsOfNode = new ArraySet();
00422 Value base = getBaseFrom(site);
00423 if (base != null)
00424 refsOfNode.add(base);
00425 }
00426
00427 refsOfNode.addAll(relVarsOfNodeCd);
00428
00429
00430 relVars.put(controlNode, refsOfNode);
00431 }
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
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
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
00460 Set refsOfNode = refVarsOf(defNodeStmt);
00461
00462
00463 refsOfNode.addAll(relVarsOfRefNode);
00464
00465
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
00482 Set interVars = SetUtil.setIntersection(dataDependVars, relVarsOfRefNode);
00483 if (interVars.size() == 0)
00484 continue;
00485 }
00486 workSet.add(defNode);
00487
00488
00489 Set refsOfNode = refVarsOf(defNodeStmt);
00490 CallSite site = isCallSite(indexMaps.getCallSiteMap(),defNodeStmt);
00491 if (site != null) {
00492
00493 refsOfNode = new ArraySet();
00494 Value base = getBaseFrom(site);
00495 if (base != null)
00496 refsOfNode.add(base);
00497 }
00498
00499 refsOfNode.addAll(relVarsOfRefNode);
00500
00501
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
00515
00516
00517
00518
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
00532
00533 boolean existCallPath = false;
00534 Set calculatedMds = new ArraySet();
00535 LinkedList workList = new LinkedList();
00536
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
00549
00550
00551
00552
00553 if (calledMethods.contains(toMd)) {
00554 existCallPath = true;
00555 finished = true;
00556 } else
00557
00558
00559
00560
00561
00562 workList.addAll(workList.size(), calledMethods);
00563
00564
00565 }
00566 }
00567 return existCallPath;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
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
00660
00661
00662
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
00680
00681
00682
00683
00684
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
00695 if (sliceSet == null)
00696 sliceSet = new BitSet(targetStmtList.size());
00697 SliceCriterion increCriterion = methodInfo.increCriterion;
00698 if (increCriterion != null) {
00699
00700
00701
00702
00703
00704
00705 if (increCriterion.getSlicePoints().contains(interStmt))
00706 return;
00707 }
00708
00709
00710 Set relVarsAtInterStmt = new ArraySet();
00711 relVarsAtInterStmt.addAll(newRelVars);
00712 if (!sliceSet.get(interStmtIndex)) {
00713
00714
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
00725
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
00755
00756
00757
00758
00759
00760
00761
00762
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
00769
00770
00771
00772
00773
00774 Set relVarsOfCallee = PostProcess.getRelevantLocals(calleeMdInfo.originalStmtList, calleeMdInfo.sliceSet, relVarMapOfCallee);
00775
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
00785
00786 Set relVarsInCaller = new ArraySet();
00787 InvokeExpr invokeExpr = callSite.invokeExpr;
00788
00789
00790 if (invokeExpr instanceof NonStaticInvokeExpr) {
00791 NonStaticInvokeExpr nonStaticInvokeExpr = (NonStaticInvokeExpr) invokeExpr;
00792 Value callerBase = nonStaticInvokeExpr.getBase();
00793 relVarsInCaller.add(callerBase);
00794
00795
00796
00797 Set relInstanceFdInCaller = BuildPDG.cloneAndChangeBase(relInstanceFdInCallee, callerBase);
00798
00799
00800 for (Iterator i = relInstanceFdInCaller.iterator(); i.hasNext();)
00801 relVarsInCaller.add((Value) i.next());
00802 }
00803
00804
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
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
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
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
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 private void genNewCritForExit(CallSite callSite, Map relevantVarMap, Set relVarsInCaller, MethodInfo callerMdInfo, MethodInfo targetMdInfo, Set exitStmtSet, Set localCopiesInCaller) {
00868
00869
00870
00871
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
00882
00883
00884
00885 Set relVarsAtCallSite = (Set) relevantVarMap.get(callSiteStmt);
00886
00887
00888
00889
00890 Set relVarsInTargetMd = new ArraySet();
00891 Fields MODFields = targetMdInfo.MOD;
00892 Fields REFFields = targetMdInfo.REF;
00893
00894
00895 Set staticFields = allMODREFFields(MODFields.staticFields, REFFields.staticFields);
00896
00897 staticFdInTargetMd(relVarsAtCallSite, staticFields, relVarsInTargetMd);
00898 InvokeExpr invokeExpr = callSite.invokeExpr;
00899
00900 if (invokeExpr instanceof NonStaticInvokeExpr) {
00901
00902 Set instanceFields = allMODREFFields(MODFields.instanceFields, REFFields.instanceFields);
00903
00904
00905
00906 instanceFdInTargetMd(relVarsAtCallSite, instanceFields, relVarsInTargetMd, invokeExpr, localCopiesInCaller);
00907 }
00908
00909
00910 Local paraLocals[] = targetMdInfo.indexMaps.getParaLocalSet();
00911 SimpleLocalCopies simpleLocalCopiesInTargetMd = new SimpleLocalCopies((CompleteStmtGraph) targetMdInfo.indexMaps.getStmtGraph());
00912 Set paraFieldsInTargetMd = MODFields.paraFields;
00913
00914
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
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
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
00975
00976
00977
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
00991
00992
00993
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
01004
01005
01006
01007
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
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
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
01028 for (Iterator copyIt = copiesListBefore.iterator(); copyIt.hasNext();)
01029 copiesList.add((LocalCopy) copyIt.next());
01030
01031
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
01042
01043
01044
01045
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
01053 baseCopiesList.add((Local) base);
01054
01055
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
01063 baseCopiesList.add(rightLocal);
01064 else
01065 if (baseCopiesList.contains(rightLocal))
01066
01067
01068 baseCopiesList.add(leftLocal);
01069 }
01070 return baseCopiesList;
01071 }
01072
01073
01074
01075
01076
01077
01078
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
01103
01104
01105
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
01127
01128
01129
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
01141
01142
01143
01144
01145
01146
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
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
01164 base = insField.getBase();
01165 relVarsInTargetMd.add(base);
01166 }
01167 }
01168 }
01169
01170
01171
01172
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
01190
01191
01192
01193
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
01204
01205
01206
01207
01208
01209
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
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
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
01246
01247
01248
01249
01250
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
01271
01272
01273
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
01288 Local baseLocal = (Local) insFieldRef.getBase();
01289 relVarsInTargetMd.add(baseLocal);
01290 }
01291 }
01292 }
01293 }
01294
01295
01296
01297
01298
01299
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
01316
01317
01318
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
01329
01330
01331
01332
01333
01334 public static List reachableStmtFrom(Stmt stmt, StmtGraph stmtGraphAsPara) {
01335 List reachableStmt = new ArrayList();
01336
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
01355
01356
01357
01358
01359
01360 static Set reachableStmtSetFrom(Stmt stmt, StmtGraph stmtGraphAsPara) {
01361 Set reachableStmtSet = new ArraySet();
01362
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
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
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
01432 return stn;
01433 }
01434 }
01435 return null;
01436 }
01437
01438
01439
01440 void slicingMethod(boolean goingup) {
01441
01442
01443
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
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
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
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
01477
01478
01479
01480
01481 for (ListIterator workListIt = workList.listIterator(); workListIt.hasNext();) {
01482 Stmt node = (Stmt) workListIt.next();
01483 if (!linePropList.contains(node)) {
01484
01485
01486 Set relVarsOfNode = refVarsOf(node);
01487 CallSite site = isCallSite(methodInfo.indexMaps.getCallSiteMap(), node);
01488 if (site != null) {
01489
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
01508
01509
01510 }
01511 calculatedNodes.add(node);
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 Set ddNodes = methodPDG.dataNodesOf(node);
01523
01524
01525
01526
01527
01528
01529
01530
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
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
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570 if (lockAnalysis != null) {
01571
01572
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
01583
01584
01585
01586
01587
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
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 }
01605 }
01606 methodInfo.sliceSet = sliceSet;
01607
01608
01609
01610 if (Slicer.classNum > 1) {
01611
01612
01613
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
01629
01630
01631
01632
01633
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
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
01656 }
01657 }
01658 }
01659 }
01660
01661 }
01662 }
01663 if (goingup) {
01664 if (methodInfo.whoCallMe != null) {
01665
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
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
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709 }
01710 }
01711
01712
01713
01714
01715
01716
01717
01718
01719 Set localCopiesList = getCompleteLocalCopiesList(methodInfo, linePropList);
01720 mdCallsInSlice(methodInfo, sliceSet, relVarMap, localCopiesList);
01721
01722
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
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
01742 }
01743 }
01744 }
01745
01746
01747
01748 void slicingMethodAgain() {
01749 if (methodInfo.sCriterion == null) {
01750 methodInfo.sCriterion = methodInfo.increCriterion;
01751 methodInfo.increCriterion = null;
01752
01753
01754
01755
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
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
01781
01782
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
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
01834
01835
01836
01837
01838
01839
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
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873 if (lockAnalysis != null) {
01874
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
01884
01885
01886
01887
01888
01889
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
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906 }
01907 }
01908 if (Slicer.classNum > 1) {
01909
01910
01911 if (node instanceof EnterMonitorStmt) {
01912
01913
01914
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
01931
01932
01933 if (!(node instanceof InvokeStmt) && (!linePropList.contains(node)))
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
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
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
01977
01978
01979
01980 methodInfo.increCriterion = null;
01981
01982
01983
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
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
02003 }
02004 }
02005
02006
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
02026
02027
02028
02029
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 }