diff options
Diffstat (limited to 'src/proguard/optimize/TailRecursionSimplifier.java')
-rw-r--r-- | src/proguard/optimize/TailRecursionSimplifier.java | 101 |
1 files changed, 63 insertions, 38 deletions
diff --git a/src/proguard/optimize/TailRecursionSimplifier.java b/src/proguard/optimize/TailRecursionSimplifier.java index 0946b6a..f01dcd9 100644 --- a/src/proguard/optimize/TailRecursionSimplifier.java +++ b/src/proguard/optimize/TailRecursionSimplifier.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -54,9 +54,9 @@ implements AttributeVisitor, private final CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer(); + private final MyRecursionChecker recursionChecker = new MyRecursionChecker(); private Method targetMethod; - private boolean recursive; private boolean inlinedAny; @@ -105,38 +105,31 @@ implements AttributeVisitor, // clazz.getName().equals("abc/Def") && // method.getName(clazz).equals("abc"); - targetMethod = method; - inlinedAny = false; + targetMethod = method; + inlinedAny = false; codeAttributeComposer.reset(); - // Append the body of the code. - copyCode(clazz, method, codeAttribute); + // The code may expand, due to expanding constant and variable + // instructions. + codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); + + // Copy the instructions. + codeAttribute.instructionsAccept(clazz, method, this); // Update the code attribute if any code has been inlined. if (inlinedAny) { - codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute); - } - } - } + // Copy the exceptions. + codeAttribute.exceptionsAccept(clazz, method, this); + // Append a label just after the code. + codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); - /** - * Appends the code of the given code attribute. - */ - private void copyCode(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - // The code may expand, due to expanding constant and variable - // instructions. - codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); - - // Copy the instructions. - codeAttribute.instructionsAccept(clazz, method, this); + codeAttributeComposer.endCodeFragment(); - // Append a label just after the code. - codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); - - codeAttributeComposer.endCodeFragment(); + codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute); + } + } } @@ -159,9 +152,9 @@ implements AttributeVisitor, case InstructionConstants.OP_INVOKESTATIC: { // Is it a recursive call? - clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, recursionChecker); - if (recursive) + if (recursionChecker.isRecursive()) { // Is the next instruction a return? int nextOffset = @@ -180,13 +173,13 @@ implements AttributeVisitor, case InstructionConstants.OP_RETURN: { // Isn't the recursive call inside a try/catch block? - codeAttribute.exceptionsAccept(clazz, method, offset, this); + codeAttribute.exceptionsAccept(clazz, method, offset, recursionChecker); - if (recursive) + if (recursionChecker.isRecursive()) { if (DEBUG) { - System.out.println("TailRecursionSimplifier.visitConstantInstruction: ["+ + System.out.println("TailRecursionSimplifier: ["+ clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"], inlining "+constantInstruction.toString(offset)); } @@ -227,19 +220,52 @@ implements AttributeVisitor, } - // Implementations for ConstantVisitor. + // Implementations for ExceptionInfoVisitor. - public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { - recursive = targetMethod.equals(methodrefConstant.referencedMember); + codeAttributeComposer.appendException(new ExceptionInfo(exceptionInfo.u2startPC, + exceptionInfo.u2endPC, + exceptionInfo.u2handlerPC, + exceptionInfo.u2catchType)); } - // Implementations for ExceptionInfoVisitor. - - public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + /** + * This ConstantVisitor and ExceptionInfoVisitor returns whether a method + * invocation can be treated as tail-recursive. + */ + private class MyRecursionChecker + extends SimplifiedVisitor + implements ConstantVisitor, + ExceptionInfoVisitor { - recursive = false; + private boolean recursive; + + + /** + * Returns whether the method invocation can be treated as + * tail-recursive. + */ + public boolean isRecursive() + { + return recursive; + } + + // Implementations for ConstantVisitor. + + public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) + { + recursive = targetMethod.equals(methodrefConstant.referencedMember); + } + + + // Implementations for ExceptionInfoVisitor. + + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + { + recursive = false; + } } @@ -257,7 +283,6 @@ implements AttributeVisitor, (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0; // Count the number of parameters, taking into account their categories. - int parameterCount = ClassUtil.internalMethodParameterCount(descriptor); int parameterSize = ClassUtil.internalMethodParameterSize(descriptor); int parameterOffset = isStatic ? 0 : 1; |