diff options
Diffstat (limited to 'src/proguard/optimize/MethodDescriptorShrinker.java')
-rw-r--r-- | src/proguard/optimize/MethodDescriptorShrinker.java | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/src/proguard/optimize/MethodDescriptorShrinker.java b/src/proguard/optimize/MethodDescriptorShrinker.java deleted file mode 100644 index f5f52b0..0000000 --- a/src/proguard/optimize/MethodDescriptorShrinker.java +++ /dev/null @@ -1,350 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2014 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 - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.optimize; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.editor.ConstantPoolEditor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.MemberVisitor; -import proguard.optimize.info.*; -import proguard.optimize.peephole.VariableShrinker; - -import java.util.Arrays; - -/** - * This MemberVisitor removes unused parameters in the descriptors of the - * methods that it visits. - * - * @see ParameterUsageMarker - * @see VariableUsageMarker - * @see VariableShrinker - * @author Eric Lafortune - */ -public class MethodDescriptorShrinker -extends SimplifiedVisitor -implements MemberVisitor, - AttributeVisitor -{ - private static final boolean DEBUG = false; - - - private final MemberVisitor extraMemberVisitor; - - - /** - * Creates a new MethodDescriptorShrinker. - */ - public MethodDescriptorShrinker() - { - this(null); - } - - - /** - * Creates a new MethodDescriptorShrinker with an extra visitor. - * @param extraMemberVisitor an optional extra visitor for all methods whose - * parameters have been simplified. - */ - public MethodDescriptorShrinker(MemberVisitor extraMemberVisitor) - { - this.extraMemberVisitor = extraMemberVisitor; - } - - - // Implementations for MemberVisitor. - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - if (DEBUG) - { - System.out.println("MethodDescriptorShrinker: ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"]"); - } - - // Update the descriptor if it has any unused parameters. - String descriptor = programMethod.getDescriptor(programClass); - String newDescriptor = shrinkDescriptor(programMethod, descriptor); - - if (!newDescriptor.equals(descriptor)) - { - String name = programMethod.getName(programClass); - String newName = name; - - // Append a code, if the method isn't a class instance initializer. - if (!name.equals(ClassConstants.METHOD_NAME_INIT)) - { - newName += ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); - } - - ConstantPoolEditor constantPoolEditor = - new ConstantPoolEditor(programClass); - - // Update the name, if necessary. - if (!newName.equals(name)) - { - programMethod.u2nameIndex = - constantPoolEditor.addUtf8Constant(newName); - } - - // Update the referenced classes. - programMethod.referencedClasses = - shrinkReferencedClasses(programMethod, - descriptor, - programMethod.referencedClasses); - - // Finally, update the descriptor itself. - programMethod.u2descriptorIndex = - constantPoolEditor.addUtf8Constant(newDescriptor); - - if (DEBUG) - { - System.out.println(" -> ["+newName+newDescriptor+"]"); - } - - // Shrink the signature and parameter annotations. - programMethod.attributesAccept(programClass, this); - - // Visit the method, if required. - if (extraMemberVisitor != null) - { - extraMemberVisitor.visitProgramMethod(programClass, programMethod); - } - } - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute) - { - if (DEBUG) - { - System.out.println(" ["+signatureAttribute.getSignature(clazz)+"]"); - } - - // Compute the new signature. - String signature = signatureAttribute.getSignature(clazz); - String newSignature = shrinkDescriptor(method, signature); - - if (!newSignature.equals(signature)) - { - // Update the signature. - signatureAttribute.u2signatureIndex = - new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newSignature); - - // Update the referenced classes. - signatureAttribute.referencedClasses = - shrinkReferencedClasses(method, - signature, - signatureAttribute.referencedClasses); - - if (DEBUG) - { - System.out.println(" -> ["+newSignature+"]"); - } - } - } - - - public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) - { - int[] annotationsCounts = parameterAnnotationsAttribute.u2parameterAnnotationsCount; - Annotation[][] annotations = parameterAnnotationsAttribute.parameterAnnotations; - - // All parameters of non-static methods are shifted by one in the local - // variable frame. - int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; - - int annotationIndex = 0; - int newAnnotationIndex = 0; - - // Go over the parameters. - String descriptor = method.getDescriptor(clazz); - InternalTypeEnumeration internalTypeEnumeration = - new InternalTypeEnumeration(descriptor); - - while (internalTypeEnumeration.hasMoreTypes()) - { - String type = internalTypeEnumeration.nextType(); - if (ParameterUsageMarker.isParameterUsed(method, parameterIndex)) - { - annotationsCounts[newAnnotationIndex] = annotationsCounts[annotationIndex]; - annotations[newAnnotationIndex++] = annotations[annotationIndex]; - } - - annotationIndex++; - - parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1; - } - - // Update the number of parameters. - parameterAnnotationsAttribute.u1parametersCount = newAnnotationIndex; - - // Clear the unused entries. - while (newAnnotationIndex < annotationIndex) - { - annotationsCounts[newAnnotationIndex] = 0; - annotations[newAnnotationIndex++] = null; - } - } - - - // Small utility methods. - - /** - * Returns a shrunk descriptor or signature of the given method. - */ - private String shrinkDescriptor(Method method, String descriptor) - { - // All parameters of non-static methods are shifted by one in the local - // variable frame. - int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; - - InternalTypeEnumeration internalTypeEnumeration = - new InternalTypeEnumeration(descriptor); - - StringBuffer newDescriptorBuffer = - new StringBuffer(descriptor.length()); - - // Copy the formal type parameters. - newDescriptorBuffer.append(internalTypeEnumeration.formalTypeParameters()); - newDescriptorBuffer.append(ClassConstants.METHOD_ARGUMENTS_OPEN); - - // Go over the parameters. - while (internalTypeEnumeration.hasMoreTypes()) - { - String type = internalTypeEnumeration.nextType(); - if (ParameterUsageMarker.isParameterUsed(method, parameterIndex)) - { - newDescriptorBuffer.append(type); - } - else if (DEBUG) - { - System.out.println(" Deleting parameter #"+parameterIndex+" ["+type+"]"); - } - - parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1; - } - - // Copy the return type. - newDescriptorBuffer.append(ClassConstants.METHOD_ARGUMENTS_CLOSE); - newDescriptorBuffer.append(internalTypeEnumeration.returnType()); - - return newDescriptorBuffer.toString(); - } - - - /** - * Shrinks the array of referenced classes of the given method. - */ - private Clazz[] shrinkReferencedClasses(Method method, - String descriptor, - Clazz[] referencedClasses) - { - if (referencedClasses != null) - { - // All parameters of non-static methods are shifted by one in the local - // variable frame. - int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; - - InternalTypeEnumeration internalTypeEnumeration = - new InternalTypeEnumeration(descriptor); - - int referencedClassIndex = 0; - int newReferencedClassIndex = 0; - - // Copy the formal type parameters. - { - String type = internalTypeEnumeration.formalTypeParameters(); - int count = new DescriptorClassEnumeration(type).classCount(); - for (int counter = 0; counter < count; counter++) - { - referencedClasses[newReferencedClassIndex++] = - referencedClasses[referencedClassIndex++]; - } - } - - // Go over the parameters. - while (internalTypeEnumeration.hasMoreTypes()) - { - // Consider the classes referenced by this parameter type. - String type = internalTypeEnumeration.nextType(); - int count = new DescriptorClassEnumeration(type).classCount(); - - if (ParameterUsageMarker.isParameterUsed(method, parameterIndex)) - { - // Copy the referenced classes. - for (int counter = 0; counter < count; counter++) - { - referencedClasses[newReferencedClassIndex++] = - referencedClasses[referencedClassIndex++]; - } - } - else - { - // Skip the referenced classes. - referencedClassIndex += count; - } - - parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1; - } - - // Copy the return type. - { - String type = internalTypeEnumeration.returnType(); - int count = new DescriptorClassEnumeration(type).classCount(); - for (int counter = 0; counter < count; counter++) - { - referencedClasses[newReferencedClassIndex++] = - referencedClasses[referencedClassIndex++]; - } - } - - // Shrink the array to the proper size. - if (newReferencedClassIndex == 0) - { - referencedClasses = null; - } - else if (newReferencedClassIndex < referencedClassIndex) - { - Clazz[] newReferencedClasses = new Clazz[newReferencedClassIndex]; - System.arraycopy(referencedClasses, 0, - newReferencedClasses, 0, - newReferencedClassIndex); - - referencedClasses = newReferencedClasses; - } - } - - return referencedClasses; - } -} |