1 21 package proguard.optimize.info; 22 23 import proguard.classfile.*; 24 import proguard.classfile.util.SimplifiedVisitor; 25 import proguard.classfile.attribute.*; 26 import proguard.classfile.attribute.visitor.AttributeVisitor; 27 import proguard.classfile.instruction.*; 28 import proguard.classfile.visitor.*; 29 30 37 public class SideEffectMethodMarker 38 extends SimplifiedVisitor 39 implements ClassPoolVisitor, 40 ClassVisitor, 41 MemberVisitor, 42 AttributeVisitor 43 { 44 private SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(false); 46 47 private int newSideEffectCount; 49 private boolean hasSideEffects; 50 51 52 54 public void visitClassPool(ClassPool classPool) 55 { 56 do 59 { 60 newSideEffectCount = 0; 61 62 classPool.classesAccept(this); 64 } 65 while (newSideEffectCount > 0); 66 } 67 68 69 71 public void visitProgramClass(ProgramClass programClass) 72 { 73 programClass.methodsAccept(this); 75 } 76 77 78 80 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 81 { 82 if (!hasSideEffects(programMethod) && 83 !NoSideEffectMethodMarker.hasNoSideEffects(programMethod)) 84 { 85 hasSideEffects = (programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_NATIVE) != 0; 88 89 programMethod.attributesAccept(programClass, this); 90 91 if (hasSideEffects) 93 { 94 markSideEffects(programMethod); 95 96 newSideEffectCount++; 97 } 98 } 99 } 100 101 102 104 public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} 105 106 107 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 108 { 109 hasSideEffects = hasSideEffects(clazz, method, codeAttribute); 111 } 112 113 114 116 119 private boolean hasSideEffects(Clazz clazz, 120 Method method, 121 CodeAttribute codeAttribute) 122 { 123 byte[] code = codeAttribute.code; 124 int length = codeAttribute.u4codeLength; 125 126 int offset = 0; 128 do 129 { 130 Instruction instruction = InstructionFactory.create(code, offset); 132 133 if (sideEffectInstructionChecker.hasSideEffects(clazz, 135 method, 136 codeAttribute, 137 offset, 138 instruction)) 139 { 140 return true; 141 } 142 143 offset += instruction.length(offset); 145 } 146 while (offset < length); 147 148 return false; 149 } 150 151 152 private static void markSideEffects(Method method) 153 { 154 MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); 155 if (info != null) 156 { 157 info.setSideEffects(); 158 } 159 } 160 161 162 public static boolean hasSideEffects(Method method) 163 { 164 MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); 165 return info == null || 166 info.hasSideEffects(); 167 } 168 } 169 | Popular Tags |