diff options
Diffstat (limited to 'src/proguard/optimize/MethodDescriptorShrinker.java')
-rw-r--r-- | src/proguard/optimize/MethodDescriptorShrinker.java | 139 |
1 files changed, 86 insertions, 53 deletions
diff --git a/src/proguard/optimize/MethodDescriptorShrinker.java b/src/proguard/optimize/MethodDescriptorShrinker.java index d8d4425..f5f52b0 100644 --- a/src/proguard/optimize/MethodDescriptorShrinker.java +++ b/src/proguard/optimize/MethodDescriptorShrinker.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) + * 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 @@ -23,13 +23,15 @@ package proguard.optimize; import proguard.classfile.*; import proguard.classfile.attribute.*; import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.visitor.*; +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. @@ -74,32 +76,26 @@ implements 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 (!descriptor.equals(newDescriptor)) + if (!newDescriptor.equals(descriptor)) { - // Shrink the signature and parameter annotations. - programMethod.attributesAccept(programClass, this); - String name = programMethod.getName(programClass); String newName = name; // Append a code, if the method isn't a class instance initializer. - if (!name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) + if (!name.equals(ClassConstants.METHOD_NAME_INIT)) { newName += ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); } - if (DEBUG) - { - System.out.println("MethodDescriptorShrinker:"); - System.out.println(" ["+programClass.getName()+"."+ - name+descriptor+"] -> ["+ - newName+newDescriptor+"]"); - } - ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(programClass); @@ -120,6 +116,14 @@ implements MemberVisitor, 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) { @@ -136,19 +140,32 @@ implements MemberVisitor, public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute) { + if (DEBUG) + { + System.out.println(" ["+signatureAttribute.getSignature(clazz)+"]"); + } + // Compute the new signature. - String signature = clazz.getString(signatureAttribute.u2signatureIndex); + String signature = signatureAttribute.getSignature(clazz); String newSignature = shrinkDescriptor(method, signature); - // Update the signature. - signatureAttribute.u2signatureIndex = - new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newSignature); + 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); + // Update the referenced classes. + signatureAttribute.referencedClasses = + shrinkReferencedClasses(method, + signature, + signatureAttribute.referencedClasses); + + if (DEBUG) + { + System.out.println(" -> ["+newSignature+"]"); + } + } } @@ -160,7 +177,7 @@ implements MemberVisitor, // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ? + (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? 0 : 1; int annotationIndex = 0; @@ -186,7 +203,7 @@ implements MemberVisitor, } // Update the number of parameters. - parameterAnnotationsAttribute.u2parametersCount = newAnnotationIndex; + parameterAnnotationsAttribute.u1parametersCount = newAnnotationIndex; // Clear the unused entries. while (newAnnotationIndex < annotationIndex) @@ -207,18 +224,20 @@ implements MemberVisitor, // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ? + (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? 0 : 1; - // Go over the parameters. InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(descriptor); - StringBuffer newDescriptorBuffer = new StringBuffer(); + StringBuffer newDescriptorBuffer = + new StringBuffer(descriptor.length()); + // Copy the formal type parameters. newDescriptorBuffer.append(internalTypeEnumeration.formalTypeParameters()); - newDescriptorBuffer.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN); + newDescriptorBuffer.append(ClassConstants.METHOD_ARGUMENTS_OPEN); + // Go over the parameters. while (internalTypeEnumeration.hasMoreTypes()) { String type = internalTypeEnumeration.nextType(); @@ -234,7 +253,8 @@ implements MemberVisitor, parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1; } - newDescriptorBuffer.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE); + // Copy the return type. + newDescriptorBuffer.append(ClassConstants.METHOD_ARGUMENTS_CLOSE); newDescriptorBuffer.append(internalTypeEnumeration.returnType()); return newDescriptorBuffer.toString(); @@ -253,30 +273,32 @@ implements MemberVisitor, // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ? + (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? 0 : 1; - int referencedClassIndex = 0; - int newReferencedClassIndex = 0; - - // Go over the parameters. InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(descriptor); - // Also look at the formal type parameters. - String type = internalTypeEnumeration.formalTypeParameters(); - int count = new DescriptorClassEnumeration(type).classCount(); - for (int counter = 0; counter < count; counter++) + int referencedClassIndex = 0; + int newReferencedClassIndex = 0; + + // Copy the formal type parameters. { - referencedClasses[newReferencedClassIndex++] = - referencedClasses[referencedClassIndex++]; + 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. - type = internalTypeEnumeration.nextType(); - count = new DescriptorClassEnumeration(type).classCount(); + String type = internalTypeEnumeration.nextType(); + int count = new DescriptorClassEnumeration(type).classCount(); if (ParameterUsageMarker.isParameterUsed(method, parameterIndex)) { @@ -296,19 +318,30 @@ implements MemberVisitor, parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1; } - // Also look at the return value. - type = internalTypeEnumeration.returnType(); - count = new DescriptorClassEnumeration(type).classCount(); - for (int counter = 0; counter < count; counter++) + // Copy the return type. { - referencedClasses[newReferencedClassIndex++] = - referencedClasses[referencedClassIndex++]; + String type = internalTypeEnumeration.returnType(); + int count = new DescriptorClassEnumeration(type).classCount(); + for (int counter = 0; counter < count; counter++) + { + referencedClasses[newReferencedClassIndex++] = + referencedClasses[referencedClassIndex++]; + } } - // Clear the unused entries. - while (newReferencedClassIndex < referencedClassIndex) + // Shrink the array to the proper size. + if (newReferencedClassIndex == 0) { - referencedClasses[newReferencedClassIndex++] = null; + referencedClasses = null; + } + else if (newReferencedClassIndex < referencedClassIndex) + { + Clazz[] newReferencedClasses = new Clazz[newReferencedClassIndex]; + System.arraycopy(referencedClasses, 0, + newReferencedClasses, 0, + newReferencedClassIndex); + + referencedClasses = newReferencedClasses; } } |