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 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00041 import edu.ksu.cis.bandera.annotation.*;
00042 import java.io.*;
00043 import java.util.Enumeration;
00044 import java.util.Vector;
00045 import java.util.BitSet;
00046 import edu.ksu.cis.bandera.jjjc.symboltable.Name;
00047 import edu.ksu.cis.bandera.jjjc.symboltable.Package;
00048
00049
00050
00051
00052 public class PostProcessOnAnnotation {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 private Map modifiedSootMethodToRemovableLocals = new HashMap();
00065 private Set removableSootMethods = new ArraySet();
00066 private Set unreachableSootMethods = new ArraySet();
00067 private Set unreachableSootClasses = Slicer.unreachableClasses;
00068 private Set removableSootFields = new ArraySet();
00069 private Set parameterModifiedSootMethods = new ArraySet();
00070
00071
00072
00073 private List classList;
00074
00075
00076
00077 private Set removableSootClasses = new ArraySet();
00078
00079
00080
00081
00082
00083 private List changeReturnTypeToVoidMds = new ArrayList();
00084
00085
00086
00087
00088 private Set relevantFields = new ArraySet();
00089 private Set relevantExceptionClassNames = new ArraySet();
00090 private AnnotationManager cfanns = null;
00091
00092
00093
00094
00095 public PostProcessOnAnnotation(List ct, AnnotationManager cfs) {
00096 classList = ct;
00097 cfanns = cfs;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 private void addCatchesToRemovedSet(Set removedSet, Vector catches, StmtList stmtList, Set linePropList, BitSet slcSet) {
00114 for (Enumeration e2 = catches.elements(); e2.hasMoreElements();) {
00115 Annotation catchClauseCFANN = (Annotation) e2.nextElement();
00116 Stmt trapStmts[] = catchClauseCFANN.getStatements();
00117 for (int i = 0; i < trapStmts.length; i++) {
00118 Stmt stmt = trapStmts[i];
00119 int stmtIndex = stmtList.indexOf(trapStmts[i]);
00120 if (linePropList.contains(stmt))
00121 continue;
00122 removedSet.add(stmt);
00123 if (slcSet.get(stmtIndex))
00124 slcSet.set(stmtIndex);
00125 }
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 private void addCatchesToSliceSet(BitSet slcSet, Vector catches, StmtList stmtList) {
00136 for (Enumeration e2 = catches.elements(); e2.hasMoreElements();) {
00137 Annotation catchClauseCFANN = (Annotation) e2.nextElement();
00138 Stmt trapStmts[] = catchClauseCFANN.getStatements();
00139 for (int i = 0; i < trapStmts.length; i++) {
00140 slcSet.set(stmtList.indexOf(trapStmts[i]));
00141 if (i == 0) {
00142 Stmt caughtStmt = trapStmts[0];
00143 if (caughtStmt instanceof IdentityStmt) {
00144 IdentityStmt idCaughtStmt = (IdentityStmt) caughtStmt;
00145 Value leftOp = idCaughtStmt.getLeftOp();
00146 Value rightOp = idCaughtStmt.getRightOp();
00147 if (leftOp instanceof Local) {
00148 Local leftOpValue = (Local) leftOp;
00149 Type valueType = leftOpValue.getType();
00150 String exceptionName = valueType.toString();
00151 if (!exceptionName.startsWith("java.lang."))
00152 this.relevantExceptionClassNames.add(exceptionName);
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 }
00163 }
00164 }
00165 }
00166 }
00167 private boolean buildNewInvokeExpr(InvokeExpr invokeExpr) {
00168 SootMethod invokedMethod = invokeExpr.getMethod();
00169 if (parameterModifiedSootMethods.contains(invokedMethod))
00170 return true;
00171 return false;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 private void callSiteInSlice(Map callSiteIndexMap, Map callSiteMap, Stmt stmt) {
00184 CallSite callSite = (CallSite) callSiteIndexMap.get(stmt);
00185 SootMethod callee = (SootMethod) callSiteMap.get(callSite);
00186 MethodInfo calleeMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callee);
00187 if (calleeMdInfo == null) return;
00188 if (calleeMdInfo.sCriterion == null) {
00189 } else {
00190 LinkedList keepedParaOriginalIndex = getKeepedParaOriginalIndex(calleeMdInfo);
00191 InvokeExpr invokeExpr = callSite.invokeExpr;
00192 int argCount = invokeExpr.getArgCount();
00193 LinkedList keepedParameters = new LinkedList();
00194 for (int i = 0; i < argCount; i++) {
00195 Value arg = invokeExpr.getArg(i);
00196 if (keepedParaOriginalIndex.contains(new Integer(i)))
00197 keepedParameters.addLast(arg);
00198 }
00199
00200
00201
00202
00203
00204
00205 }
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 private boolean emptyBody(Stmt[] bodyStmts, BitSet sliceSet, StmtList stmtList) {
00217 for (int i = 0; i < bodyStmts.length; i++) {
00218 if (sliceSet.get(stmtList.indexOf(bodyStmts[i])))
00219 return false;
00220 }
00221 return true;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 private boolean emptyBody(Set bodyStmts, BitSet sliceSet, StmtList stmtList) {
00233 for (Iterator i = bodyStmts.iterator(); i.hasNext();) {
00234 Stmt stmt = (Stmt) i.next();
00235 if (sliceSet.get(stmtList.indexOf(stmt)))
00236 return false;
00237 }
00238 return true;
00239 }
00240
00241
00242
00243
00244
00245
00246 private Set fieldRefToField(Set fieldRefSet) {
00247 Set fieldSet = new ArraySet();
00248 for (Iterator refIt = fieldRefSet.iterator(); refIt.hasNext();)
00249 fieldSet.add(((FieldRef) refIt.next()).getField());
00250 return fieldSet;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 private void filterOutFields(Set variableSet) {
00260 for (Iterator kk = variableSet.iterator(); kk.hasNext();) {
00261 Value loc = (Value) kk.next();
00262 if (loc instanceof FieldRef)
00263 relevantFields.add(loc);
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272 private Set getAllClassesFor(Package pckg) {
00273 Set classes = new ArraySet();
00274 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00275 SootClass sootClass = ((ClassInfo) classIt.next()).sootClass;
00276 Name cName = new Name(sootClass.getName());
00277 if (cName.getSuperName().equals(pckg.getName()))
00278 classes.add(sootClass);
00279 }
00280 return classes;
00281 }
00282
00283
00284
00285
00286
00287 private Set getAllPackages() {
00288 Set packages = new ArraySet();
00289 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00290 SootClass sootClass = ((ClassInfo) classIt.next()).sootClass;
00291 Name pn = new Name(sootClass.getName()).getSuperName();
00292 Package pk = null;
00293 try {
00294 pk = Package.getPackage(pn);
00295 } catch (Exception e) {
00296 }
00297 if (pk != null)
00298 packages.add(pk);
00299 }
00300 return packages;
00301 }
00302
00303
00304
00305
00306
00307
00308 private Set getAllVarsOf(MethodInfo mdInfo) {
00309 StmtList originalStmtList = mdInfo.originalStmtList;
00310 Set allVars = new ArraySet();
00311 for (int i = 0; i < originalStmtList.size(); i++) {
00312 Stmt stmt = (Stmt) originalStmtList.get(i);
00313 allVars.addAll(PostProcess.allVarsOf(stmt));
00314 }
00315 return allVars;
00316 }
00317
00318
00319
00320
00321
00322 private Set getCurrentResidualClasses() {
00323 Set classSet = new ArraySet();
00324 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00325 SootClass sootClass = ((ClassInfo) classIt.next()).sootClass;
00326 if (!removableSootClasses.contains(sootClass))
00327 classSet.add(sootClass);
00328 }
00329 return classSet;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 private LinkedList getKeepedParaOriginalIndex(MethodInfo mdInfo) {
00339 Local paraLocals[] = mdInfo.indexMaps.getParaLocalSet();
00340 Map relevantVars = mdInfo.sCriterion.relVarMap();
00341 Set relLocs = PostProcess.getRelevantLocals(mdInfo.originalStmtList, mdInfo.sliceSet, relevantVars);
00342 LinkedList keepedParaOriginalIndex = new LinkedList();
00343 for (int i = 0; i < paraLocals.length; i++) {
00344 Local paraLocal = paraLocals[i];
00345 if (relLocs.contains(paraLocal)) {
00346 keepedParaOriginalIndex.addLast(new Integer(i));
00347 }
00348 }
00349 return keepedParaOriginalIndex;
00350 }
00351
00352
00353
00354
00355
00356 public Set getModifiedPackages() {
00357 Set packages = new ArraySet();
00358 Set removablePackages = getRemovablePackages();
00359 Set modifiedSootClasses = getModifiedSootClasses();
00360 for (Iterator pIt = getAllPackages().iterator(); pIt.hasNext();) {
00361 Package pck = (Package) pIt.next();
00362 if (removablePackages.contains(pck))
00363 continue;
00364 for (Iterator classIt = getAllClassesFor(pck).iterator(); classIt.hasNext();) {
00365 SootClass sootClass = (SootClass) classIt.next();
00366 if (this.removableSootClasses.contains(sootClass) || modifiedSootClasses.contains(sootClass)) {
00367 packages.add(pck);
00368 break;
00369 }
00370 }
00371 }
00372 return packages;
00373 }
00374
00375
00376
00377
00378
00379 public Set getModifiedSootClasses() {
00380 Set modifiedClasses = new ArraySet();
00381 Set modifiedSootMethods = this.getModifiedSootMethods();
00382 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00383 SootClass sootClass = ((ClassInfo) classIt.next()).sootClass;
00384 if (this.removableSootClasses.contains(sootClass))
00385 continue;
00386 for (Iterator mdIt = sootClass.getMethods().iterator(); mdIt.hasNext();) {
00387 SootMethod sm = (SootMethod) mdIt.next();
00388 if (this.removableSootMethods.contains(sm) || this.unreachableSootMethods.contains(sm) || modifiedSootMethods.contains(sm))
00389 modifiedClasses.add(sootClass);
00390 }
00391 }
00392 return modifiedClasses;
00393 }
00394
00395
00396
00397
00398
00399 public Set getModifiedSootMethods() {
00400 return modifiedSootMethodToRemovableLocals.keySet();
00401 }
00402
00403
00404
00405
00406
00407 public Set getParameterModifiedMethods() {
00408 return parameterModifiedSootMethods;
00409 }
00410
00411
00412
00413
00414
00415
00416 public Set getRemovableLocals(SootMethod sm) {
00417 return (ArraySet) modifiedSootMethodToRemovableLocals.get(sm);
00418 }
00419
00420
00421
00422
00423
00424 public Set getRemovablePackages() {
00425 Set packages = new ArraySet();
00426 for (Iterator pIt = getAllPackages().iterator(); pIt.hasNext();) {
00427 Package pck = (Package) pIt.next();
00428 boolean removable = true;
00429 for (Iterator classIt = getAllClassesFor(pck).iterator(); classIt.hasNext();) {
00430 SootClass sootClass = (SootClass) classIt.next();
00431 if (!this.removableSootClasses.contains(sootClass)) {
00432 removable = false;
00433 break;
00434 }
00435 }
00436 if (removable)
00437 packages.add(pck);
00438 }
00439 return packages;
00440 }
00441
00442
00443
00444
00445
00446 public Set getRemovableSootClasses() {
00447 return removableSootClasses;
00448 }
00449
00450
00451
00452
00453
00454 public Set getRemovableSootFields() {
00455 return removableSootFields;
00456 }
00457
00458
00459
00460
00461
00462 public Set getRemovableSootMethods() {
00463 return removableSootMethods;
00464 }
00465
00466
00467
00468
00469
00470
00471 private Set getTrapHandlers(JimpleBody jimpBody) {
00472 Set trapsHandlerSet = new ArraySet();
00473 Iterator trapIt = jimpBody.getTraps().iterator();
00474 while (trapIt.hasNext()) {
00475 Trap trap = (Trap) trapIt.next();
00476 Stmt handler = (Stmt) trap.getHandlerUnit();
00477 trapsHandlerSet.add(handler);
00478 }
00479 return trapsHandlerSet;
00480 }
00481
00482
00483
00484
00485
00486 public Set getUnreachableSootClasses() {
00487 return unreachableSootClasses;
00488 }
00489
00490
00491
00492
00493
00494 public Set getUnreachableSootMethods() {
00495 return unreachableSootMethods;
00496 }
00497
00498
00499
00500
00501
00502
00503 private Set getUnusedLocals(MethodInfo mdInfo) {
00504 StmtList stmtList = mdInfo.stmtList;
00505 Set removedStmt = mdInfo.removedStmt;
00506 JimpleBody listBody = (JimpleBody) mdInfo.sootMethod.getBody(Jimple.v());
00507 Set unusedLocals = new ArraySet();
00508
00509 unusedLocals.addAll(listBody.getLocals());
00510
00511
00512 {
00513 Iterator stmtIt = stmtList.iterator();
00514 while (stmtIt.hasNext()) {
00515 Stmt s = (Stmt) stmtIt.next();
00516 if (removedStmt.contains(s))
00517 continue;
00518
00519 {
00520 Iterator boxIt = s.getDefBoxes().iterator();
00521 while (boxIt.hasNext()) {
00522 Value value = ((ValueBox) boxIt.next()).getValue();
00523 if (value instanceof Local && unusedLocals.contains(value))
00524 unusedLocals.remove(value);
00525 }
00526 }
00527
00528
00529 {
00530 Iterator boxIt = s.getUseBoxes().iterator();
00531 while (boxIt.hasNext()) {
00532 Value value = ((ValueBox) boxIt.next()).getValue();
00533 if (value instanceof Local && unusedLocals.contains(value))
00534 unusedLocals.remove(value);
00535 }
00536 }
00537 }
00538 }
00539 return unusedLocals;
00540 }
00541
00542
00543
00544
00545 private void initializeMdInfoAndAnnotation() {
00546 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00547 ClassInfo classInfo = (ClassInfo) classIt.next();
00548 if (Slicer.unreachableClasses.contains(classInfo.sootClass))
00549 continue;
00550 if (Slicer.isObjectClass(classInfo.sootClass))
00551 continue;
00552 List mdList = classInfo.methodsInfoList;
00553 for (Iterator mdIt = mdList.iterator(); mdIt.hasNext();) {
00554 MethodInfo mdInfo = (MethodInfo) mdIt.next();
00555 mdInfo.removedStmt = new ArraySet();
00556 Annotation annForSm = cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod);
00557 Vector currentCFANNs = annForSm.getAllAnnotations(true);
00558 for (Enumeration annEnum = currentCFANNs.elements(); annEnum.hasMoreElements();) {
00559 Annotation cfann = (Annotation) annEnum.nextElement();
00560 cfann.initializeState();
00561 }
00562 }
00563 }
00564 }
00565
00566
00567
00568
00569
00570
00571
00572 private boolean isImplementingOneAbstractMd(SootClass superClass, SootMethod sm) {
00573 int modifiers = superClass.getModifiers();
00574 if (!Modifier.isAbstract(modifiers))
00575 return false;
00576 SootMethod abstractMd = null;
00577 try {
00578 abstractMd = superClass.getMethod(sm.getName(), sm.getParameterTypes(), sm.getReturnType());
00579 } catch (ca.mcgill.sable.soot.NoSuchMethodException nse) {
00580 return false;
00581 }
00582 modifiers = abstractMd.getModifiers();
00583 if (Modifier.isAbstract(modifiers))
00584 return true;
00585 return false;
00586 }
00587
00588
00589
00590
00591
00592
00593 private boolean isImplementingOneAbstractMd(SootMethod sm) {
00594 boolean isImplementingMd = false;
00595 SootClass declaringClass = sm.getDeclaringClass();
00596 while (declaringClass.hasSuperClass()) {
00597 SootClass superClass = declaringClass.getSuperClass();
00598 isImplementingMd = isImplementingOneAbstractMd(superClass, sm);
00599 if (isImplementingMd)
00600 return isImplementingMd;
00601 declaringClass = superClass;
00602 }
00603 for (Iterator interfaceIt = declaringClass.getInterfaces().iterator(); interfaceIt.hasNext();) {
00604 SootClass interfaceClass = (SootClass) interfaceIt.next();
00605 isImplementingMd = isImplementingOneInterfaceMd(interfaceClass, sm);
00606 if (isImplementingMd)
00607 return isImplementingMd;
00608 while (interfaceClass.hasSuperClass()) {
00609 SootClass superClass = interfaceClass.getSuperClass();
00610 isImplementingMd = isImplementingOneInterfaceMd(interfaceClass, sm);
00611 if (isImplementingMd)
00612 return isImplementingMd;
00613 }
00614 }
00615 return isImplementingMd;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624 private boolean isImplementingOneInterfaceMd(SootClass interfaceClass, SootMethod sm) {
00625 int modifiers = interfaceClass.getModifiers();
00626 if (!Modifier.isInterface(modifiers))
00627 return false;
00628 try {
00629 SootMethod abstractMd = interfaceClass.getMethod(sm.getName(), sm.getParameterTypes(), sm.getReturnType());
00630 } catch (ca.mcgill.sable.soot.NoSuchMethodException nse) {
00631 return false;
00632 }
00633 return true;
00634 }
00635
00636
00637
00638
00639
00640
00641 private boolean isPublicAndStatic(int modifier)
00642 {
00643 if (Modifier.isPublic(modifier) &&
00644 Modifier.isStatic(modifier))
00645 return true;
00646 else return false;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656 private void keepParasOfMainMd(MethodInfo mdInfo, Map relevantVars, StmtList stmtList, BitSet sliceSet) {
00657
00658
00659 if (mdInfo.sootMethod.getName().equals("main") && isPublicAndStatic(mdInfo.sootMethod.getModifiers())) {
00660 Stmt[] paraIds = mdInfo.indexMaps.getParaIdentityStmts();
00661
00662
00663 for (int ids = 0; ids < paraIds.length; ids++) {
00664 int idIndex = stmtList.indexOf(paraIds[ids]);
00665 sliceSet.set(idIndex);
00666 relevantVars.put(paraIds[ids], SlicingMethod.allLocalVarsOf(paraIds[ids]));
00667 }
00668 }
00669 }
00670
00671
00672
00673
00674
00675 private void makeMethodEmpty(MethodInfo methodInfo, Annotation annForSm) {
00676 if (methodInfo == null)
00677 return;
00678 IndexMaps indexMaps = methodInfo.indexMaps;
00679 Set removableStmts = new ArraySet();
00680 Set keepStmts = new ArraySet();
00681 int thisRefStmtIndex = indexMaps.getThisRefStmtIndex().intValue();
00682 Stmt thisRefStmt = (Stmt) methodInfo.stmtList.get(thisRefStmtIndex);
00683 Stmt[] paraIdentities = indexMaps.getParaIdentityStmts();
00684
00685 Stmt returnStmt = null;
00686 Stmt ret$Stmt = null;
00687 Object[] returnAnns = indexMaps.getReturnAnnotations().toArray();
00688 if (returnAnns.length > 0) {
00689 Stmt[] returnStmts = ((Annotation) returnAnns[0]).getStatements();
00690 Type returnType = methodInfo.sootMethod.getReturnType();
00691 if (returnType instanceof VoidType) {
00692 for (int i = 0; i < returnStmts.length; i++) {
00693 if (returnStmts[i] instanceof ReturnVoidStmt) {
00694 returnStmt = returnStmts[i];
00695 break;
00696 }
00697 }
00698 } else
00699 for (int i = 0; i < returnStmts.length; i++) {
00700 if (returnStmts[i] instanceof ReturnStmt)
00701 returnStmt = returnStmts[i];
00702 else
00703 if (returnStmts[i] instanceof AssignStmt) {
00704 Value leftOp = ((AssignStmt) returnStmts[i]).getLeftOp();
00705 if (leftOp instanceof Local)
00706 if (((Local) leftOp).getName().equals("$ret"))
00707 ret$Stmt = returnStmts[i];
00708 }
00709 }
00710 }
00711
00712 keepStmts.add(thisRefStmt);
00713 if (returnStmt != null)
00714 keepStmts.add(returnStmt);
00715 if (ret$Stmt != null)
00716 keepStmts.add(ret$Stmt);
00717 for (int i = 0; i < paraIdentities.length; i++)
00718 keepStmts.add(paraIdentities[i]);
00719
00720 for (Iterator stmtIt = methodInfo.stmtList.iterator(); stmtIt.hasNext();) {
00721 Stmt stmt = (Stmt) stmtIt.next();
00722 if (!keepStmts.contains(stmt))
00723 removableStmts.add(stmt);
00724 }
00725
00726 for (Iterator stmtIt = removableStmts.iterator(); stmtIt.hasNext();) {
00727 try {
00728 Stmt sss = (Stmt) stmtIt.next();
00729 annForSm.removeStmtByMark(sss);
00730 methodInfo.removedStmt.add(sss);
00731 } catch (Exception e) {
00732 }
00733 }
00734
00735
00736
00737
00738
00739
00740
00741 if (ret$Stmt != null) {
00742 NullConstant nullCons = NullConstant.v();
00743 Value leftOp = ((AssignStmt) ret$Stmt).getLeftOp();
00744 AssignStmt newRetAssign = Jimple.v().newAssignStmt(leftOp, nullCons);
00745
00746
00747 try {
00748
00749 annForSm.replaceStmtByMark(ret$Stmt, newRetAssign);
00750 } catch (Exception e) {
00751 }
00752
00753 }
00754 }
00755
00756
00757
00758
00759
00760 private boolean modifyMethod(MethodInfo mdInfo) {
00761 boolean modified = false;
00762 JimpleBody jimpBody = (JimpleBody) mdInfo.sootMethod.getBody(Jimple.v());
00763 StmtList stmtList = mdInfo.stmtList;
00764 StmtList stmtListClone = mdInfo.originalStmtList;
00765 BitSet sliceSet = mdInfo.sliceSet;
00766 int stmtListSize = stmtListClone.size();
00767 Integer thisRefIndex = mdInfo.indexMaps.getThisRefStmtIndex();
00768 Integer specialInvokeIndex = null;
00769
00770
00771
00772 if (thisRefIndex != null)
00773 sliceSet.set(thisRefIndex.intValue());
00774 BuildPDG pdg = mdInfo.methodPDG;
00775 Map relevantVars = mdInfo.sCriterion.relVarMap();
00776 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00777 Map callSiteIndexMap = SlicingMethod.callSiteIndex(callSiteMap);
00778 BitSet stmtIndexToNop = new BitSet(stmtListSize);
00779 BitSet removedStmtIndexSet = new BitSet(stmtListSize);
00780 StmtGraph sg = mdInfo.indexMaps.getStmtGraph();
00781 Set trapsHandlerSet = getTrapHandlers(jimpBody);
00782 SootMethod sm = mdInfo.sootMethod;
00783 SootClass sootClass = mdInfo.sootClass;
00784 Annotation annForSm = cfanns.getAnnotation(sootClass, sm);
00785 Vector currentCFANNs = annForSm.getAllAnnotations(true);
00786 keepParasOfMainMd(mdInfo, relevantVars, stmtList, sliceSet);
00787 Set removedStmtByEmptyBlock = new ArraySet();
00788 removeEmptyBlock(mdInfo, removedStmtByEmptyBlock, currentCFANNs, stmtList, jimpBody);
00789
00790
00791 Set relLocs = PostProcess.getRelevantLocals(stmtList, sliceSet, relevantVars);
00792 boolean changedReturnToVoid = false;
00793
00794 for (int k = 0; k < stmtList.size(); k++) {
00795 Stmt stmt = (Stmt) stmtList.get(k);
00796 int stmtIndex = stmtListClone.indexOf(stmt);
00797 if (sliceSet.get(stmtIndex)) {
00798 if (thisRefIndex != null) {
00799 if (stmtIndex == thisRefIndex.intValue())
00800 continue;
00801 }
00802 if (specialInvokeIndex != null) {
00803 if (stmtIndex == specialInvokeIndex.intValue())
00804 continue;
00805 }
00806 if (stmt instanceof ReturnStmt) {
00807
00808
00809
00810 Value retVal = ((ReturnStmt) stmt).getReturnValue();
00811 if (!(retVal instanceof Local)) {
00812 if (changedReturnToVoid) {
00813
00814
00815 Stmt s = (Stmt) stmtList.get(k);
00816 ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00817 try {
00818 annForSm.replaceStmtByMark(s, rtvs);
00819 modified = true;
00820 } catch (Exception e) {
00821 }
00822
00823
00824
00825 changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00826 }
00827 } else
00828 if (retVal instanceof Local) {
00829 if (relLocs.contains(retVal)) {
00830 } else {
00831
00832
00833 Stmt s = (Stmt) stmtList.get(k);
00834 ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00835 try {
00836 annForSm.replaceStmtByMark(s, rtvs);
00837 modified = true;
00838 } catch (Exception e) {
00839 }
00840
00841
00842
00843 changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00844 changedReturnToVoid = true;
00845 }
00846 }
00847
00848 } else
00849 if (trapsHandlerSet.contains(stmt)) {
00850 } else
00851 if (callSiteIndexMap.containsKey(stmt)) {
00852 callSiteInSlice(callSiteIndexMap, callSiteMap, stmt);
00853 } else {
00854 Set allRefVariablesInStmt = SlicingMethod.refVarsOf(stmt);
00855
00856
00857 if (relLocs.containsAll(allRefVariablesInStmt) || (stmt instanceof ThrowStmt) || (stmt instanceof ReturnVoidStmt)) {
00858 } else {
00859
00860
00861
00862
00863
00864
00865
00866 stmtIndexToNop.set(stmtIndex);
00867 Stmt nopStmt = Jimple.v().newNopStmt();
00868
00869 Stmt s = (Stmt) stmtList.get(k);
00870 try {
00871 annForSm.replaceStmtByMark(s, nopStmt);
00872 modified = true;
00873 } catch (Exception e) {
00874 }
00875 }
00876 }
00877 } else {
00878
00879 if ((stmt instanceof GotoStmt) && !removedStmtByEmptyBlock.contains(stmt)) {
00880 } else
00881 if (stmt instanceof ReturnStmt) {
00882
00883
00884
00885 Value retVal = ((ReturnStmt) stmt).getReturnValue();
00886 if (retVal instanceof Local) {
00887 if (!relLocs.contains(retVal)) {
00888
00889
00890
00891 Stmt s = (Stmt) stmtList.get(k);
00892 ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00893 try {
00894 annForSm.replaceStmtByMark(s, rtvs);
00895 modified = true;
00896 } catch (Exception e) {
00897 }
00898
00899
00900 changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00901 }
00902 }
00903 } else
00904 if ((stmt instanceof ReturnVoidStmt) || (stmt instanceof RetStmt)) {
00905 } else {
00906
00907
00908 try {
00909 annForSm.removeStmtByMark((Stmt) stmtList.get(k));
00910 mdInfo.removedStmt.add(stmtList.get(k));
00911 modified = true;
00912 } catch (Exception e) {
00913 }
00914 removedStmtIndexSet.set(stmtIndex);
00915 }
00916 }
00917 }
00918 Set useAndDefVarsInSlice = PostProcess.getAllVarsOf(stmtListClone, SetUtil.bitSetAndNot(sliceSet, stmtIndexToNop));
00919
00920
00921 filterOutFields(useAndDefVarsInSlice);
00922 return modified;
00923 }
00924
00925
00926
00927
00928 private void relevantExceptionClasses() {
00929 Set relevantExceptionClassInfo = new ArraySet();
00930 if (relevantExceptionClassNames.isEmpty())
00931 return;
00932 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00933 ClassInfo classInfo = (ClassInfo) classIt.next();
00934 String className = classInfo.sootClass.getName();
00935 if (this.relevantExceptionClassNames.contains(className))
00936 relevantExceptionClassInfo.add(classInfo);
00937 }
00938 for (Iterator classIt = relevantExceptionClassInfo.iterator(); classIt.hasNext();) {
00939 ClassInfo classInfo = (ClassInfo) classIt.next();
00940 if (this.removableSootClasses.contains(classInfo.sootClass))
00941 this.removableSootClasses.remove(classInfo.sootClass);
00942 }
00943 }
00944
00945
00946
00947
00948
00949 private void relevantFDClass() {
00950 Set restoredClasses = new ArraySet();
00951 for (Iterator listIt = removableSootClasses.iterator(); listIt.hasNext();) {
00952 SootClass sootClass = (SootClass) listIt.next();
00953 if (Slicer.isObjectClass(sootClass))
00954 continue;
00955 for (Iterator i = relevantFields.iterator(); i.hasNext();) {
00956 FieldRef oneField = (FieldRef) i.next();
00957 SootClass declareClass = oneField.getField().getDeclaringClass();
00958 if (sootClass.equals(declareClass))
00959 restoredClasses.add(sootClass);
00960 }
00961 }
00962 removableSootClasses.removeAll(restoredClasses);
00963 }
00964
00965
00966
00967
00968 private void relevantInterfaceAndSuperClasses() {
00969 Set currentResidualClasses = getCurrentResidualClasses();
00970 Set unremovableClasses = new ArraySet();
00971 for (Iterator classIt = removableSootClasses.iterator(); classIt.hasNext();) {
00972 SootClass sootClass = (SootClass) classIt.next();
00973 if (!Slicer.isRemovableClass(sootClass, currentResidualClasses))
00974 unremovableClasses.add(sootClass);
00975 }
00976 if (!unremovableClasses.isEmpty())
00977 removableSootClasses.removeAll(unremovableClasses);
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 private void removeEmptyBlock(MethodInfo mdInfo, Set rmedStmtByEmptBlck, Vector currentCFANNs, StmtList stmtList, JimpleBody jimpleBody) {
00990
00991 BitSet sliceSet = mdInfo.sliceSet;
00992 {
00993 LockAnalysis lockAna = mdInfo.methodPDG.getLockAnalysis();
00994 if (lockAna != null)
00995 removeEmptyLock(lockAna.getLockPairList(), sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList);
00996 }
00997 removeEmptyTry(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck,stmtList, jimpleBody);
00998 removeEmptyTryFinally(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList, jimpleBody);
00999 removeEmptyConditionalBlock(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList);
01000
01001
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 private void removeEmptyConditionalBlock(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList) {
01013 for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
01014 Annotation cfann = (Annotation) e.nextElement();
01015 if (cfann instanceof ConditionalAnnotation) {
01016 ConditionalAnnotation conditionalStmtAnn = (ConditionalAnnotation) cfann;
01017 Set condStmts = new ArraySet(conditionalStmtAnn.getStatements());
01018 Set bodyStmts = new ArraySet();
01019 bodyStmts.addAll(condStmts);
01020 Set testStmts = new ArraySet(conditionalStmtAnn.getTestStatements());
01021 bodyStmts.removeAll(testStmts);
01022 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01023 for (Iterator i = condStmts.iterator(); i.hasNext();) {
01024 Stmt stmt = (Stmt) i.next();
01025 if (linePropList.contains(stmt))
01026 continue;
01027 removedStmtByEmptyB.add(stmt);
01028 }
01029 }
01030 }
01031 else
01032 if (cfann instanceof ControlFlowAnnotation) {
01033 ControlFlowAnnotation controlFlowStmtAnn = (ControlFlowAnnotation) cfann;
01034 Stmt bodyStmts[] = controlFlowStmtAnn.getBlockAnnotation().getStatements();
01035 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01036 bodyStmts = controlFlowStmtAnn.getStatements();
01037 for (int i = 0; i < bodyStmts.length; i++) {
01038 Stmt stmt = bodyStmts[i];
01039 if (linePropList.contains(stmt))
01040 continue;
01041 removedStmtByEmptyB.add(stmt);
01042 }
01043 }
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 }
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 private void removeEmptyLock(List lockPairList, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList) {
01095 for (Iterator lockPairIt = lockPairList.iterator(); lockPairIt.hasNext();) {
01096 MonitorPair lockPair = (MonitorPair) lockPairIt.next();
01097 Stmt monitorStmt = (Stmt) lockPair.getEnterMonitor();
01098 Annotation synchroBodyAnn = lockPair.getSynchroBodyAnn();
01099 Stmt bodyStmts[] = synchroBodyAnn.getStatements();
01100 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01101
01102 monitorStmt = lockPair.getEndSynchroStmt();
01103 int exitIndex = stmtList.indexOf(monitorStmt);
01104 monitorStmt = lockPair.getBeginSynchroStmt();
01105 int enterIndex = stmtList.indexOf(monitorStmt);
01106 for (int i = enterIndex; i <= exitIndex; i++) {
01107 Stmt stmt = (Stmt) stmtList.get(i);
01108 if (linePropList.contains(stmt))
01109 continue;
01110 removedStmtByEmptyB.add(stmt);
01111 if (slcSet.get(i)) {
01112 slcSet.clear(i);
01113 }
01114 }
01115 } else
01116
01117
01118 {
01119 Annotation catchCFANN = lockPair.getCatchAnn();
01120 Stmt catchStmts[] = catchCFANN.getStatements();
01121 for (int i = 0; i < catchStmts.length; i++) {
01122 slcSet.set(stmtList.indexOf(catchStmts[i]));
01123 }
01124 }
01125 }
01126 }
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 private void removeEmptyTry(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList, JimpleBody jimpleBody) {
01137 for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
01138 Annotation cfann = (Annotation) e.nextElement();
01139 if (cfann instanceof TryStmtAnnotation) {
01140 TryStmtAnnotation tryCFANN = (TryStmtAnnotation) cfann;
01141 Annotation tryBody = tryCFANN.getBlockAnnotation();
01142 Stmt bodyStmts[] = tryBody.getStatements();
01143
01144
01145
01146 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01147 Stmt allBodyStmts[] = tryCFANN.getStatements();
01148 for (int i = 0; i < allBodyStmts.length; i++) {
01149 Stmt stmt = allBodyStmts[i];
01150 int stmtIndex = stmtList.indexOf(stmt);
01151 if (linePropList.contains(stmt))
01152 continue;
01153 removedStmtByEmptyB.add(stmt);
01154 if (slcSet.get(stmtIndex))
01155 slcSet.clear(stmtIndex);
01156 }
01157 addCatchesToRemovedSet(removedStmtByEmptyB, tryCFANN.getCatchClauses(), stmtList, linePropList, slcSet);
01158
01159
01160 } else {
01161
01162
01163
01164 Vector catches = tryCFANN.getCatchClauses();
01165 addCatchesToSliceSet(slcSet, catches, stmtList);
01166 }
01167 }
01168 }
01169 }
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179 private void removeEmptyTryFinally(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList, JimpleBody jimpleBody) {
01180 for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
01181 Annotation cfann = (Annotation) e.nextElement();
01182
01183
01184 if (cfann instanceof TryFinallyStmtAnnotation) {
01185
01186 TryFinallyStmtAnnotation tryFinallyCFANN = (TryFinallyStmtAnnotation) cfann;
01187 Annotation tryBody = tryFinallyCFANN.getBlockAnnotation();
01188 Stmt bodyStmts[] = tryBody.getStatements();
01189
01190
01191
01192 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01193 for (int i = 0; i < bodyStmts.length; i++) {
01194 Stmt stmt = bodyStmts[i];
01195 int stmtIndex = stmtList.indexOf(stmt);
01196 if (linePropList.contains(stmt))
01197 continue;
01198 removedStmtByEmptyB.add(stmt);
01199 if (slcSet.get(stmtIndex))
01200 slcSet.clear(stmtIndex);
01201 }
01202 addCatchesToRemovedSet(removedStmtByEmptyB, tryFinallyCFANN.getCatchClauses(), stmtList, linePropList, slcSet);
01203 } else
01204
01205 {
01206
01207 Vector catches = tryFinallyCFANN.getCatchClauses();
01208 addCatchesToSliceSet(slcSet, catches, stmtList);
01209 }
01210
01211
01212 bodyStmts = tryFinallyCFANN.getFinallyAnnotation().getStatements();
01213 for (int i = 0; i < bodyStmts.length; i++)
01214 slcSet.set(stmtList.indexOf(bodyStmts[i]));
01215 bodyStmts = tryFinallyCFANN.getFinallyExceptionAnnotation().getStatements();
01216 for (int i = 0; i < bodyStmts.length; i++)
01217 slcSet.set(stmtList.indexOf(bodyStmts[i]));
01218 }
01219 }
01220 }
01221
01222
01223
01224
01225
01226
01227 private void removeFieldInClinit(SootClass sootClass, SootField sootField) {
01228 if (!sootClass.declaresMethod("<clinit>"))
01229 return;
01230 SootMethod sootMethod = sootClass.getMethod("<clinit>");
01231 JimpleBody jimpleBody = (JimpleBody) sootMethod.getBody(Jimple.v());
01232 StmtList stmtList = jimpleBody.getStmtList();
01233 Set removableStmts = new ArraySet();
01234 for (Iterator stmtIt = stmtList.iterator(); stmtIt.hasNext();) {
01235 Stmt stmt = (Stmt) stmtIt.next();
01236 if (stmt instanceof AssignStmt) {
01237 Value leftValue = ((AssignStmt) stmt).getLeftOp();
01238 if (leftValue instanceof FieldRef) {
01239 SootField leftField = ((FieldRef) leftValue).getField();
01240 if (leftField.equals(sootField))
01241 removableStmts.add(stmt);
01242 }
01243 }
01244 }
01245 if (removableStmts.isEmpty())
01246 return;
01247 Annotation annForSm = cfanns.getAnnotation(sootClass, sootMethod);
01248 for (Iterator stmtIt = removableStmts.iterator(); stmtIt.hasNext();) {
01249 Stmt stmt = (Stmt) stmtIt.next();
01250 stmtList.remove(stmt);
01251 try {
01252 annForSm.removeStmtByMark(stmt);
01253 } catch (Exception e) {
01254 }
01255 }
01256 }
01257
01258
01259
01260
01261
01262
01263 private void removeIrrelevantFields(ClassInfo classInfo) {
01264 SootClass sootClass = classInfo.sootClass;
01265 List fields = sootClass.getFields();
01266 Set relevantSootFields = fieldRefToField(relevantFields);
01267 removableSootFields = new ArraySet();
01268 for (Iterator fieldsIt = fields.iterator(); fieldsIt.hasNext();) {
01269 SootField sootField = (SootField) fieldsIt.next();
01270 if (!relevantSootFields.contains(sootField)) {
01271 removableSootFields.add(sootField);
01272 removeFieldInClinit(sootClass, sootField);
01273 }
01274 }
01275 }
01276
01277
01278
01279 public void resClassCons() {
01280 initializeMdInfoAndAnnotation();
01281 Map removableMdMap = new HashMap();
01282 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01283 ClassInfo classInfo = (ClassInfo) classIt.next();
01284 if (Slicer.unreachableClasses.contains(classInfo.sootClass)) {
01285 removableSootClasses.add(classInfo.sootClass);
01286 continue;
01287 }
01288 if (Slicer.isObjectClass(classInfo.sootClass))
01289 continue;
01290 List mdList = classInfo.methodsInfoList;
01291 MethodInfo initMethodInfo = null;
01292 List removableMethods = new ArrayList();
01293 boolean containsStartMethod = false;
01294 for (Iterator mdIt = mdList.iterator(); mdIt.hasNext();) {
01295 MethodInfo mdInfo = (MethodInfo) mdIt.next();
01296
01297
01298
01299
01300
01301 if (mdInfo.sliceSet == null) {
01302 if (mdInfo.sootMethod.getName().equals("<init>")) {
01303 SootMethod sm = mdInfo.sootMethod;
01304 if (sm.getParameterCount() == 0) {
01305 initMethodInfo = mdInfo;
01306 }
01307 removableMethods.add(mdInfo);
01308 } else
01309 if (Modifier.isAbstract(mdInfo.sootMethod.getModifiers())) {
01310 }
01311
01312
01313 else
01314 if (mdInfo.sootMethod.getName().equals("start")) {
01315 containsStartMethod = true;
01316 } else
01317 removableMethods.add(mdInfo);
01318 } else {
01319 boolean modified = modifyMethod(mdInfo);
01320 if (modified)
01321 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, new ArraySet());
01322 }
01323 }
01324 if (removableMethods.size() != 0) {
01325 if (removableMethods.size() == mdList.size() || (removableMethods.size() == (mdList.size() - 1) && containsStartMethod)) {
01326 removableSootClasses.add(classInfo.sootClass);
01327 } else {
01328 if (initMethodInfo != null) {
01329 Set varsOfInit = getAllVarsOf(initMethodInfo);
01330 filterOutFields(varsOfInit);
01331 removableMethods.remove(initMethodInfo);
01332 }
01333 Set implementingMethods = new ArraySet();
01334 for (Iterator mdInfoIt = removableMethods.iterator(); mdInfoIt.hasNext();) {
01335 MethodInfo rmvableMdInfo = (MethodInfo) mdInfoIt.next();
01336 SootMethod rmvableMd = rmvableMdInfo.sootMethod;
01337 if (isImplementingOneAbstractMd(rmvableMd)) {
01338 implementingMethods.add(rmvableMdInfo);
01339 Annotation annForSm = cfanns.getAnnotation(rmvableMd.getDeclaringClass(), rmvableMd);
01340 makeMethodEmpty(rmvableMdInfo, annForSm);
01341 modifiedSootMethodToRemovableLocals.put(rmvableMdInfo.sootMethod, new ArraySet());
01342 }
01343 }
01344 if (!implementingMethods.isEmpty())
01345 removableMethods.removeAll(implementingMethods);
01346 }
01347 }
01348
01349
01350 removableMdMap.put(classInfo.sootClass, removableMethods);
01351 }
01352
01353
01354
01355
01356
01357
01358
01359 relevantFDClass();
01360 relevantExceptionClasses();
01361 rmMethodAndClass(removableMdMap);
01362
01363 rmIrrelevantFds();
01364 rmIrrelevantParasForMd();
01365 rmIrrelevantParasForInvoke();
01366 rmUnusedLocals();
01367 relevantInterfaceAndSuperClasses();
01368 }
01369
01370
01371
01372
01373
01374 private void residualParameters(MethodInfo mdInfo) {
01375 SootMethod sootMethod = mdInfo.sootMethod;
01376 StmtList stmtList = mdInfo.originalStmtList;
01377 Annotation annForSm = cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod);
01378 StmtList slicedStmtList = mdInfo.stmtList;
01379 List parameterTypes = sootMethod.getParameterTypes();
01380 Local paraLocals[] = mdInfo.indexMaps.getParaLocalSet();
01381 Stmt paraIdStmt[] = mdInfo.indexMaps.getParaIdentityStmts();
01382 BitSet sliceSet = mdInfo.sliceSet;
01383 Map relevantVars = mdInfo.sCriterion.relVarMap();
01384 Set relLocs = PostProcess.getAllVarsOf(stmtList, sliceSet);
01385 Set removableParas = new ArraySet();
01386 LinkedList keepedParaOriginalIndex = new LinkedList();
01387 for (int i = 0; i < paraLocals.length; i++) {
01388 Local paraLocal = paraLocals[i];
01389 if (!relLocs.contains(paraLocal)) {
01390 removableParas.add(parameterTypes.get(i));
01391 } else {
01392 keepedParaOriginalIndex.addLast(new Integer(i));
01393 }
01394 }
01395 for (Iterator i = removableParas.iterator(); i.hasNext();) {
01396 Object type = (Object) i.next();
01397 }
01398 if (removableParas.size() > 0) {
01399 parameterModifiedSootMethods.add(sootMethod);
01400
01401 for (int i = 0; i < keepedParaOriginalIndex.size(); i++) {
01402 int originalParaIndex = ((Integer) keepedParaOriginalIndex.get(i)).intValue();
01403 if (originalParaIndex == i)
01404 continue;
01405 Stmt stmtForThisPara = paraIdStmt[originalParaIndex];
01406 if (!(stmtForThisPara instanceof IdentityStmt))
01407 throw new NonIdParaAssignmentException("parameter assignment should be identity statement");
01408 IdentityStmt idStmtForThisPara = (IdentityStmt) stmtForThisPara;
01409 ParameterRef newParameterRef = Jimple.v().newParameterRef(sootMethod, i);
01410 IdentityStmt newIdStmt = Jimple.v().newIdentityStmt(idStmtForThisPara.getLeftOp(), newParameterRef);
01411
01412
01413 int indexOfIdStmt = slicedStmtList.indexOf(stmtForThisPara);
01414 try {
01415 annForSm.replaceStmtByMark(idStmtForThisPara, newIdStmt);
01416 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, new ArraySet());
01417 } catch (Exception e) {
01418 }
01419 }
01420 }
01421 }
01422
01423
01424
01425 private void rmIrrelevantFds() {
01426
01427 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01428 ClassInfo classInfo = (ClassInfo) classIt.next();
01429 if (
01430 Slicer.isObjectClass(classInfo.sootClass) || removableSootClasses.contains(classInfo.sootClass)) {
01431 } else
01432 removeIrrelevantFields(classInfo);
01433 }
01434 }
01435
01436
01437
01438 private void rmIrrelevantParasForInvoke() {
01439
01440 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01441 ClassInfo classInfo = (ClassInfo) classIt.next();
01442 if (Slicer.isObjectClass(classInfo.sootClass) || removableSootClasses.contains(classInfo.sootClass))
01443 continue;
01444 for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
01445 MethodInfo mdInfo = (MethodInfo) mdIt.next();
01446 if (mdInfo.sliceSet != null)
01447 rmParasOfInvokeExpr(mdInfo);
01448 }
01449 }
01450 }
01451
01452
01453
01454 private void rmIrrelevantParasForMd() {
01455
01456 Iterator classIt = classList.iterator();
01457 while (classIt.hasNext()) {
01458 ClassInfo classInfo = (ClassInfo) classIt.next();
01459 if (Slicer.isObjectClass(classInfo.sootClass) || removableSootClasses.contains(classInfo.sootClass))
01460 continue;
01461 List mdList = classInfo.methodsInfoList;
01462 Iterator mdIt = mdList.iterator();
01463 while (mdIt.hasNext()) {
01464 MethodInfo mdInfo = (MethodInfo) mdIt.next();
01465 if (mdInfo.sliceSet == null)
01466 continue;
01467 if (mdInfo.sootMethod.getName().equals("main")) {
01468 } else
01469 residualParameters(mdInfo);
01470 }
01471 }
01472 }
01473
01474
01475
01476
01477
01478
01479 private void rmMethodAndClass(Map removableMdMap) {
01480
01481
01482 for (Iterator classIt = removableMdMap.keySet().iterator(); classIt.hasNext();) {
01483 SootClass sootClass = (SootClass) classIt.next();
01484 List removableMethods = (List) removableMdMap.get(sootClass);
01485 for (int i = 0; i < removableMethods.size(); i++) {
01486 MethodInfo rmvableMdInfo = (MethodInfo) removableMethods.get(i);
01487 removableSootMethods.add(rmvableMdInfo.sootMethod);
01488 }
01489 for (Iterator mdIt = sootClass.getMethods().iterator(); mdIt.hasNext();) {
01490 SootMethod md = (SootMethod) mdIt.next();
01491 if (!Slicer.reachableMethods.contains(md))
01492 unreachableSootMethods.add(md);
01493 }
01494 }
01495 }
01496
01497
01498
01499
01500
01501 private void rmParasOfInvokeExpr(MethodInfo mdInfo) {
01502 StmtList originalStmtList = mdInfo.originalStmtList;
01503 StmtList stmtList = mdInfo.stmtList;
01504 Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
01505 Map callSiteIndexMap = SlicingMethod.callSiteIndex(callSiteMap);
01506 BitSet sliceSet = mdInfo.sliceSet;
01507 Annotation annForSm = cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod);
01508 for (Iterator siteIt = callSiteIndexMap.keySet().iterator(); siteIt.hasNext();) {
01509 Stmt callStmt = (Stmt) siteIt.next();
01510 if (!sliceSet.get(originalStmtList.indexOf(callStmt)))
01511 continue;
01512 if (callStmt instanceof InvokeStmt) {
01513 InvokeStmt invokeStmt = (InvokeStmt) callStmt;
01514 InvokeExpr invokeExpr = (InvokeExpr) invokeStmt.getInvokeExpr();
01515 boolean paraChanged = buildNewInvokeExpr(invokeExpr);
01516 if (paraChanged) {
01517 try {
01518 annForSm.replaceStmtByMark(invokeStmt, invokeStmt);
01519 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, new ArraySet());
01520 } catch (Exception e) {
01521 }
01522 }
01523 } else
01524 if (callStmt instanceof AssignStmt) {
01525 AssignStmt assignCallStmt = (AssignStmt) callStmt;
01526 Value rightOp = assignCallStmt.getRightOp();
01527 if (rightOp instanceof InvokeExpr) {
01528 boolean paraChanged = buildNewInvokeExpr((InvokeExpr) rightOp);
01529 SootMethod invokedMd = ((InvokeExpr) rightOp).getMethod();
01530 if (changeReturnTypeToVoidMds.contains(invokedMd)) {
01531 int indexOfCallStmt = stmtList.indexOf(callStmt);
01532
01533 try {
01534 annForSm.replaceStmtByMark(callStmt, callStmt);
01535 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, new ArraySet());
01536 } catch (Exception e) {
01537 }
01538 } else {
01539 if (paraChanged) {
01540 try {
01541 annForSm.replaceStmtByMark(callStmt, callStmt);
01542 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, new ArraySet());
01543 } catch (Exception e) {
01544 }
01545 }
01546 }
01547 } else {
01548 System.out.println("rightOp is not invokeExpr");
01549 }
01550 } else {
01551 System.out.println("callStmt is not invokeStmt nor DefinitionStmt");
01552 }
01553 }
01554 }
01555
01556
01557
01558 private void rmUnusedLocals() {
01559
01560 for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01561 ClassInfo classInfo = (ClassInfo) classIt.next();
01562 if (Slicer.isObjectClass(classInfo.sootClass) || removableSootClasses.contains(classInfo.sootClass))
01563 continue;
01564 for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
01565 MethodInfo mdInfo = (MethodInfo) mdIt.next();
01566 Set unusedLocals = getUnusedLocals(mdInfo);
01567 if (!unusedLocals.isEmpty())
01568 modifiedSootMethodToRemovableLocals.put(mdInfo.sootMethod, unusedLocals);
01569 }
01570 }
01571 }
01572 }