1 22 package proguard.optimize; 23 24 import proguard.*; 25 import proguard.evaluation.value.SpecificValueFactory; 26 import proguard.classfile.*; 27 import proguard.classfile.attribute.visitor.*; 28 import proguard.classfile.constant.visitor.AllConstantVisitor; 29 import proguard.classfile.editor.*; 30 import proguard.classfile.instruction.visitor.*; 31 import proguard.classfile.util.MethodLinker; 32 import proguard.classfile.visitor.*; 33 import proguard.optimize.evaluation.*; 34 import proguard.optimize.peephole.*; 35 import proguard.optimize.info.*; 36 37 import java.io.IOException ; 38 39 44 public class Optimizer 45 { 46 private Configuration configuration; 47 48 49 52 public Optimizer(Configuration configuration) 53 { 54 this.configuration = configuration; 55 } 56 57 58 61 public boolean execute(ClassPool programClassPool, 62 ClassPool libraryClassPool) throws IOException 63 { 64 if (configuration.keep == null && 66 configuration.applyMapping == null && 67 configuration.printMapping == null) 68 { 69 throw new IOException ("You have to specify '-keep' options for the optimization step."); 70 } 71 72 ClassCounter singleImplementationCounter = new ClassCounter(); 74 ClassCounter finalClassCounter = new ClassCounter(); 75 MemberCounter finalMethodCounter = new MemberCounter(); 76 MemberCounter privateFieldCounter = new MemberCounter(); 77 MemberCounter privateMethodCounter = new MemberCounter(); 78 MemberCounter staticMethodCounter = new MemberCounter(); 79 MemberCounter writeOnlyFieldCounter = new MemberCounter(); 80 MemberCounter constantFieldCounter = new MemberCounter(); 81 MemberCounter constantMethodCounter = new MemberCounter(); 82 MemberCounter descriptorShrinkCounter = new MemberCounter(); 83 MemberCounter parameterShrinkCounter = new MemberCounter(); 84 MemberCounter variableShrinkCounter = new MemberCounter(); 85 ExceptionCounter exceptionCounter = new ExceptionCounter(); 86 InstructionCounter inliningCounter = new InstructionCounter(); 87 InstructionCounter commonCodeCounter = new InstructionCounter(); 88 InstructionCounter pushCounter = new InstructionCounter(); 89 InstructionCounter branchCounter = new InstructionCounter(); 90 InstructionCounter deletedCounter = new InstructionCounter(); 91 InstructionCounter addedCounter = new InstructionCounter(); 92 InstructionCounter peepholeCounter = new InstructionCounter(); 93 94 programClassPool.classesAccept(new ClassCleaner()); 96 libraryClassPool.classesAccept(new ClassCleaner()); 97 98 programClassPool.classesAccept(new BottomClassFilter( 100 new MethodLinker())); 101 libraryClassPool.classesAccept(new BottomClassFilter( 102 new MethodLinker())); 103 104 KeepMarker keepMarker = new KeepMarker(); 106 ClassPoolVisitor classPoolvisitor = 107 ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, 108 keepMarker, 109 keepMarker, 110 false, 111 true, 112 false); 113 programClassPool.accept(classPoolvisitor); 115 libraryClassPool.accept(classPoolvisitor); 116 117 libraryClassPool.classesAccept(keepMarker); 119 libraryClassPool.classesAccept(new AllMemberVisitor(keepMarker)); 120 121 programClassPool.classesAccept(new AllMethodVisitor( 123 new AllAttributeVisitor( 124 new AllInstructionVisitor( 125 new DotClassClassVisitor(keepMarker))))); 126 127 programClassPool.classesAccept(new AllConstantVisitor( 129 new ClassForNameClassVisitor(keepMarker))); 130 131 programClassPool.classesAccept(new AllMemberVisitor( 134 new MemberOptimizationInfoSetter())); 135 136 if (configuration.assumeNoSideEffects != null) 137 { 138 NoSideEffectMethodMarker noSideEffectMethodMarker = new NoSideEffectMethodMarker(); 140 ClassPoolVisitor noClassPoolvisitor = 141 ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.assumeNoSideEffects, 142 null, 143 noSideEffectMethodMarker); 144 145 programClassPool.accept(noClassPoolvisitor); 147 libraryClassPool.accept(noClassPoolvisitor); 148 } 149 150 programClassPool.classesAccept(new SingleImplementationMarker(configuration.allowAccessModification, singleImplementationCounter)); 152 153 programClassPool.classesAccept(new ClassFinalizer(finalClassCounter, finalMethodCounter)); 155 156 programClassPool.classesAccept(new AllMethodVisitor( 158 new AllAttributeVisitor( 159 new AllInstructionVisitor( 160 new MultiInstructionVisitor( 161 new InstructionVisitor[] 162 { 163 new ReadWriteFieldMarker(), 164 }))))); 165 166 programClassPool.classesAccept(new AllMethodVisitor( 168 new OptimizationInfoMemberFilter( 169 new ParameterUsageMarker()))); 170 171 programClassPool.classesAccept(new AllMethodVisitor( 173 new OptimizationInfoMemberFilter( 174 new MethodDescriptorShrinker(descriptorShrinkCounter)))); 175 176 programClassPool.classesAccept(new AllMethodVisitor( 178 new OptimizationInfoMemberFilter( 179 new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_STATIC, 180 new MethodStaticizer(staticMethodCounter))))); 181 182 programClassPool.classesAccept(new AllMethodVisitor( 185 new AllAttributeVisitor( 186 new ParameterShrinker(parameterShrinkCounter)))); 187 188 programClassPool.classesAccept(new AllMethodVisitor( 191 new AllAttributeVisitor( 192 new MethodInvocationFixer()))); 193 194 programClassPool.classesAccept(new MemberReferenceFixer()); 196 197 programClassPool.accept(new SideEffectMethodMarker()); 199 200 203 programClassPool.classesAccept(new AllMethodVisitor( 206 new AllAttributeVisitor( 207 new PartialEvaluator(new SpecificValueFactory(), new UnusedParameterInvocationUnit(new StoringInvocationUnit()), false)))); 208 209 programClassPool.classesAccept(new MultiClassVisitor( 211 new ClassVisitor[] 212 { 213 new AllFieldVisitor( 214 new WriteOnlyFieldFilter(writeOnlyFieldCounter)), 215 new AllFieldVisitor( 216 new ConstantMemberFilter(constantFieldCounter)), 217 new AllMethodVisitor( 218 new ConstantMemberFilter(constantMethodCounter)), 219 })); 220 221 programClassPool.classesAccept(new AllMethodVisitor( 225 new AllAttributeVisitor( 226 new EvaluationSimplifier( 227 new PartialEvaluator(new SpecificValueFactory(), new UnusedParameterInvocationUnit(new LoadingInvocationUnit()), false), 228 pushCounter, branchCounter, deletedCounter, addedCounter)))); 229 230 242 programClassPool.classesAccept(new SingleImplementationInliner()); 244 245 programClassPool.classesAccept(new SingleImplementationFixer()); 247 248 if (configuration.allowAccessModification) 249 { 250 programClassPool.classesAccept(new AllConstantVisitor( 253 new AccessFixer())); 254 } 255 256 programClassPool.classesAccept(new ClassReferenceFixer(true)); 258 259 programClassPool.classesAccept(new MemberReferenceFixer()); 261 262 programClassPool.classesAccept(new AllMethodVisitor( 266 new AllAttributeVisitor( 267 new MultiAttributeVisitor( 268 new AttributeVisitor[] 269 { 270 new AllInstructionVisitor( 271 new MultiInstructionVisitor( 272 new InstructionVisitor[] 273 { 274 new MethodInvocationMarker(), 275 new SuperInvocationMarker(), 276 new BackwardBranchMarker(), 277 new AccessMethodMarker(), 278 })), 279 new CatchExceptionMarker(), 280 })))); 281 282 programClassPool.classesAccept(new AllMethodVisitor( 284 new AllAttributeVisitor( 285 new MethodInliner(configuration.allowAccessModification, true, inliningCounter)))); 286 287 programClassPool.classesAccept(new AllMethodVisitor( 289 new AllAttributeVisitor( 290 new MethodInliner(configuration.allowAccessModification, false, inliningCounter)))); 291 292 programClassPool.classesAccept(new NonPrivateMemberMarker()); 294 295 programClassPool.classesAccept(new ClassAccessFilter(0, ClassConstants.INTERNAL_ACC_INTERFACE, 298 new AllMemberVisitor( 299 new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, 300 new MemberPrivatizer(privateFieldCounter, privateMethodCounter))))); 301 302 if (configuration.allowAccessModification) 303 { 304 programClassPool.classesAccept(new AllConstantVisitor( 307 new AccessFixer())); 308 } 309 310 programClassPool.classesAccept(new AllMemberVisitor( 313 new AllAttributeVisitor( 314 new MethodInvocationFixer()))); 315 316 BranchTargetFinder branchTargetFinder = new BranchTargetFinder(); 319 CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); 320 321 programClassPool.classesAccept(new AllMethodVisitor( 323 new AllAttributeVisitor( 324 new GotoCommonCodeReplacer(commonCodeCounter)))); 325 326 programClassPool.classesAccept(new AllMethodVisitor( 328 new AllAttributeVisitor( 329 new PeepholeOptimizer(branchTargetFinder, codeAttributeEditor, 330 new MultiInstructionVisitor( 331 new InstructionVisitor[] 332 { 333 new InstructionSequencesReplacer(InstructionSequenceConstants.PATTERN_CONSTANTS, 334 InstructionSequenceConstants.INSTRUCTION_SEQUENCES, 335 branchTargetFinder, codeAttributeEditor, peepholeCounter), 336 new GotoGotoReplacer( codeAttributeEditor, peepholeCounter), 337 new GotoReturnReplacer( codeAttributeEditor, peepholeCounter), 338 }))))); 339 340 programClassPool.classesAccept(new AllMethodVisitor( 342 new AllAttributeVisitor( 343 new UnreachableExceptionRemover(exceptionCounter)))); 344 345 programClassPool.classesAccept(new AllMethodVisitor( 347 new AllAttributeVisitor( 348 new UnreachableCodeRemover(deletedCounter)))); 349 350 programClassPool.classesAccept(new AllMethodVisitor( 352 new AllAttributeVisitor( 353 new VariableShrinker(variableShrinkCounter)))); 354 355 programClassPool.classesAccept(new AllMethodVisitor( 357 new AllAttributeVisitor( 358 new VariableOptimizer()))); 359 360 int singleImplementationCount = singleImplementationCounter.getCount(); 361 int finalClassCount = finalClassCounter .getCount(); 362 int privateFieldCount = privateFieldCounter .getCount(); 363 int privateMethodCount = privateMethodCounter .getCount(); 364 int staticMethodCount = staticMethodCounter .getCount(); 365 int finalMethodCount = finalMethodCounter .getCount(); 366 int writeOnlyFieldCount = writeOnlyFieldCounter .getCount(); 367 int constantFieldCount = constantFieldCounter .getCount(); 368 int constantMethodCount = constantMethodCounter .getCount(); 369 int descriptorShrinkCount = descriptorShrinkCounter .getCount(); 370 int parameterShrinkCount = parameterShrinkCounter .getCount(); 371 int variableShrinkCount = variableShrinkCounter .getCount(); 372 int exceptionCount = exceptionCounter .getCount(); 373 int inliningCount = inliningCounter .getCount(); 374 int commonCodeCount = commonCodeCounter .getCount(); 375 int pushCount = pushCounter .getCount(); 376 int branchCount = branchCounter .getCount(); 377 int removedCount = deletedCounter .getCount() - addedCounter.getCount(); 378 int peepholeCount = peepholeCounter .getCount(); 379 380 if (configuration.verbose) 381 { 382 System.out.println(" Number of inlined interfaces: "+singleImplementationCount); 383 System.out.println(" Number of finalized classes: "+finalClassCount); 384 System.out.println(" Number of privatized fields: "+privateFieldCount); 385 System.out.println(" Number of privatized methods: "+privateMethodCount); 386 System.out.println(" Number of staticized methods: "+staticMethodCount); 387 System.out.println(" Number of finalized methods: "+finalMethodCount); 388 System.out.println(" Number of removed write-only fields: "+writeOnlyFieldCount); 389 System.out.println(" Number of inlined constant fields: "+constantFieldCount); 390 System.out.println(" Number of inlined constant methods: "+constantMethodCount); 391 System.out.println(" Number of simplified method declarations: "+descriptorShrinkCount); 392 System.out.println(" Number of removed parameters: "+parameterShrinkCount); 393 System.out.println(" Number of removed local variables: "+variableShrinkCount); 394 System.out.println(" Number of inlined method calls: "+inliningCount); 395 System.out.println(" Number of removed exception blocks: "+exceptionCount); 396 System.out.println(" Number of merged code blocks: "+commonCodeCount); 397 System.out.println(" Number of simplified push instructions: "+pushCount); 398 System.out.println(" Number of simplified branches: "+branchCount); 399 System.out.println(" Number of removed instructions: "+removedCount); 400 System.out.println(" Number of peephole optimizations: "+peepholeCount); 401 } 402 403 return singleImplementationCount > 0 || 404 finalClassCount > 0 || 405 privateFieldCount > 0 || 406 privateMethodCount > 0 || 407 staticMethodCount > 0 || 408 finalMethodCount > 0 || 409 writeOnlyFieldCount > 0 || 410 constantFieldCount > 0 || 411 constantMethodCount > 0 || 412 descriptorShrinkCount > 0 || 413 parameterShrinkCount > 0 || 414 variableShrinkCount > 0 || 415 inliningCount > 0 || 416 exceptionCount > 0 || 417 commonCodeCount > 0 || 418 pushCount > 0 || 419 branchCount > 0 || 420 removedCount > 0 || 421 peepholeCount > 0; 422 } 423 } 424 | Popular Tags |