summaryrefslogtreecommitdiff
path: root/src/proguard/optimize/MethodDescriptorShrinker.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/optimize/MethodDescriptorShrinker.java')
-rw-r--r--src/proguard/optimize/MethodDescriptorShrinker.java139
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;
}
}