diff options
Diffstat (limited to 'src/proguard/optimize/TailRecursionSimplifier.java')
-rw-r--r-- | src/proguard/optimize/TailRecursionSimplifier.java | 101 |
1 files changed, 38 insertions, 63 deletions
diff --git a/src/proguard/optimize/TailRecursionSimplifier.java b/src/proguard/optimize/TailRecursionSimplifier.java index f01dcd9..0946b6a 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-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 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,34 +105,41 @@ implements AttributeVisitor, // clazz.getName().equals("abc/Def") && // method.getName(clazz).equals("abc"); - targetMethod = method; - inlinedAny = false; + targetMethod = method; + inlinedAny = false; codeAttributeComposer.reset(); - // The code may expand, due to expanding constant and variable - // instructions. - codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); - - // Copy the instructions. - codeAttribute.instructionsAccept(clazz, method, this); + // Append the body of the code. + copyCode(clazz, method, codeAttribute); // Update the code attribute if any code has been inlined. if (inlinedAny) { - // Copy the exceptions. - codeAttribute.exceptionsAccept(clazz, method, this); - - // Append a label just after the code. - codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); - - codeAttributeComposer.endCodeFragment(); - codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute); } } } + /** + * 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); + + // Append a label just after the code. + codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); + + codeAttributeComposer.endCodeFragment(); + } + + // Implementations for InstructionVisitor. public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) @@ -152,9 +159,9 @@ implements AttributeVisitor, case InstructionConstants.OP_INVOKESTATIC: { // Is it a recursive call? - clazz.constantPoolEntryAccept(constantInstruction.constantIndex, recursionChecker); + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); - if (recursionChecker.isRecursive()) + if (recursive) { // Is the next instruction a return? int nextOffset = @@ -173,13 +180,13 @@ implements AttributeVisitor, case InstructionConstants.OP_RETURN: { // Isn't the recursive call inside a try/catch block? - codeAttribute.exceptionsAccept(clazz, method, offset, recursionChecker); + codeAttribute.exceptionsAccept(clazz, method, offset, this); - if (recursionChecker.isRecursive()) + if (recursive) { if (DEBUG) { - System.out.println("TailRecursionSimplifier: ["+ + System.out.println("TailRecursionSimplifier.visitConstantInstruction: ["+ clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"], inlining "+constantInstruction.toString(offset)); } @@ -220,52 +227,19 @@ implements AttributeVisitor, } - // Implementations for ExceptionInfoVisitor. + // Implementations for ConstantVisitor. - public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) { - codeAttributeComposer.appendException(new ExceptionInfo(exceptionInfo.u2startPC, - exceptionInfo.u2endPC, - exceptionInfo.u2handlerPC, - exceptionInfo.u2catchType)); + recursive = targetMethod.equals(methodrefConstant.referencedMember); } - /** - * This ConstantVisitor and ExceptionInfoVisitor returns whether a method - * invocation can be treated as tail-recursive. - */ - private class MyRecursionChecker - extends SimplifiedVisitor - implements ConstantVisitor, - ExceptionInfoVisitor - { - 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. + // Implementations for ExceptionInfoVisitor. - public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) - { - recursive = false; - } + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + { + recursive = false; } @@ -283,6 +257,7 @@ 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; |