diff options
Diffstat (limited to 'src/proguard/optimize')
77 files changed, 680 insertions, 2975 deletions
diff --git a/src/proguard/optimize/BootstrapMethodArgumentShrinker.java b/src/proguard/optimize/BootstrapMethodArgumentShrinker.java deleted file mode 100644 index 70d031d..0000000 --- a/src/proguard/optimize/BootstrapMethodArgumentShrinker.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * 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 - * 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.*; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.editor.ConstantPoolEditor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.MemberVisitor; -import proguard.optimize.info.*; -import proguard.optimize.peephole.VariableShrinker; - -/** - * This BootstrapMethodInfoVisitor removes unused constant arguments from - * bootstrap method entries that it visits. - * - * @see ParameterUsageMarker - * @see VariableUsageMarker - * @see VariableShrinker - * @author Eric Lafortune - */ -public class BootstrapMethodArgumentShrinker -extends SimplifiedVisitor -implements BootstrapMethodInfoVisitor, - ConstantVisitor, - MemberVisitor -{ - private long usedParameters; - - - // Implementations for BootstrapMethodInfoVisitor. - - public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) - { - // Check which method parameters are used. - usedParameters = -1L; - clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this); - - // Remove the unused arguments. - int methodArgumentCount = bootstrapMethodInfo.u2methodArgumentCount; - int[] methodArguments = bootstrapMethodInfo.u2methodArguments; - - int newArgumentIndex = 0; - - for (int argumentIndex = 0; argumentIndex < methodArgumentCount; argumentIndex++) - { - if (argumentIndex >= 64 || - (usedParameters & (1L << argumentIndex)) != 0L) - { - methodArguments[newArgumentIndex++] = methodArguments[argumentIndex]; - } - } - - // Update the number of arguments. - bootstrapMethodInfo.u2methodArgumentCount = newArgumentIndex; - } - - - // Implementations for ConstantVisitor. - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - // Check the referenced bootstrap method. - clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); - } - - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) - { - // Check the referenced class member itself. - refConstant.referencedMemberAccept(this); - } - - - // Implementations for MemberVisitor. - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - usedParameters = ParameterUsageMarker.getUsedParameters(programMethod); - } -} diff --git a/src/proguard/optimize/ChangedCodePrinter.java b/src/proguard/optimize/ChangedCodePrinter.java index e0d00b8..67a79ab 100644 --- a/src/proguard/optimize/ChangedCodePrinter.java +++ b/src/proguard/optimize/ChangedCodePrinter.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,12 +54,6 @@ implements AttributeVisitor } - public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) - { - attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute); - } - - public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute); diff --git a/src/proguard/optimize/ConstantMemberFilter.java b/src/proguard/optimize/ConstantMemberFilter.java index d3a8207..56437c3 100644 --- a/src/proguard/optimize/ConstantMemberFilter.java +++ b/src/proguard/optimize/ConstantMemberFilter.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 diff --git a/src/proguard/optimize/ConstantParameterFilter.java b/src/proguard/optimize/ConstantParameterFilter.java index 6920990..24a7040 100644 --- a/src/proguard/optimize/ConstantParameterFilter.java +++ b/src/proguard/optimize/ConstantParameterFilter.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 diff --git a/src/proguard/optimize/DuplicateInitializerFixer.java b/src/proguard/optimize/DuplicateInitializerFixer.java index 07b7d82..746d182 100644 --- a/src/proguard/optimize/DuplicateInitializerFixer.java +++ b/src/proguard/optimize/DuplicateInitializerFixer.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 @@ -86,7 +86,7 @@ implements MemberVisitor, if (!programMethod.equals(similarMethod)) { // Should this initializer be preserved? - if (KeepMarker.isKept(programMethod)) + if (!KeepMarker.isKept(programMethod)) { // Fix the other initializer. programMethod = (ProgramMethod)similarMethod; @@ -95,23 +95,12 @@ implements MemberVisitor, int index = descriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE); // Try to find a new, unique descriptor. - int typeCounter = 0; - while (true) + for (int typeIndex = 0; typeIndex < TYPES.length; typeIndex++) { - // Construct the new descriptor by inserting a new type - // as an additional last argument. - StringBuffer newDescriptorBuffer = - new StringBuffer(descriptor.substring(0, index)); - - for (int arrayDimension = 0; arrayDimension < typeCounter / TYPES.length; arrayDimension++) - { - newDescriptorBuffer.append(ClassConstants.INTERNAL_TYPE_ARRAY); - } - - newDescriptorBuffer.append(TYPES[typeCounter % TYPES.length]); - newDescriptorBuffer.append(descriptor.substring(index)); - - String newDescriptor = newDescriptorBuffer.toString(); + String newDescriptor = + descriptor.substring(0, index) + + TYPES[typeIndex] + + descriptor.substring(index); // Is the new initializer descriptor unique? if (programClass.findMethod(name, newDescriptor) == null) @@ -119,7 +108,7 @@ implements MemberVisitor, if (DEBUG) { System.out.println("DuplicateInitializerFixer:"); - System.out.println(" ["+programClass.getName()+"."+name+descriptor+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") -> ["+newDescriptor+"]"); + System.out.println(" ["+programClass.getName()+"]: "+name+descriptor+" -> "+newDescriptor); } // Update the descriptor. @@ -141,9 +130,12 @@ implements MemberVisitor, // We're done with this constructor. return; } - - typeCounter++; } + + throw new IllegalStateException("Can't find unique constructor descriptor for ["+ + programClass.getName()+"."+ + programMethod.getName(programClass)+ + programMethod.getDescriptor(programClass)+"]"); } } } diff --git a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java b/src/proguard/optimize/DuplicateInitializerInvocationFixer.java index e900232..ca24481 100644 --- a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java +++ b/src/proguard/optimize/DuplicateInitializerInvocationFixer.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 @@ -28,7 +28,7 @@ import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.editor.CodeAttributeEditor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; -import proguard.classfile.util.*; +import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.MemberVisitor; /** @@ -48,12 +48,12 @@ implements AttributeVisitor, private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); - private String descriptor; - private int descriptorLengthDelta; + private String descriptor; + private boolean hasBeenFixed; /** - * Creates a new DuplicateInitializerInvocationFixer. + * Creates a new EvaluationSimplifier. */ public DuplicateInitializerInvocationFixer() { @@ -62,7 +62,7 @@ implements AttributeVisitor, /** - * Creates a new DuplicateInitializerInvocationFixer. + * Creates a new EvaluationSimplifier. * @param extraAddedInstructionVisitor an optional extra visitor for all * added instructions. */ @@ -102,22 +102,21 @@ implements AttributeVisitor, { if (constantInstruction.opcode == InstructionConstants.OP_INVOKESPECIAL) { - descriptorLengthDelta = 0; + hasBeenFixed = false; clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); - if (descriptorLengthDelta > 0) + if (hasBeenFixed) { Instruction extraInstruction = - new SimpleInstruction(descriptorLengthDelta == 1 ? - InstructionConstants.OP_ICONST_0 : - InstructionConstants.OP_ACONST_NULL); + new SimpleInstruction(InstructionConstants.OP_ICONST_0); codeAttributeEditor.insertBeforeInstruction(offset, extraInstruction); if (DEBUG) { - System.out.println(" ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset)); + System.out.println("DuplicateInitializerInvocationFixer:"); + System.out.println(" Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset)); } if (extraAddedInstructionVisitor != null) @@ -146,16 +145,6 @@ implements AttributeVisitor, public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { - descriptorLengthDelta = - programMethod.getDescriptor(programClass).length() - descriptor.length(); - - if (DEBUG) - { - if (descriptorLengthDelta > 0) - { - System.out.println("DuplicateInitializerInvocationFixer:"); - System.out.println(" ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") referenced by:"); - } - } + hasBeenFixed = !descriptor.equals(programMethod.getDescriptor(programClass)); } -} +}
\ No newline at end of file diff --git a/src/proguard/optimize/KeepMarker.java b/src/proguard/optimize/KeepMarker.java index f8087be..4297996 100644 --- a/src/proguard/optimize/KeepMarker.java +++ b/src/proguard/optimize/KeepMarker.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 diff --git a/src/proguard/optimize/KeptClassFilter.java b/src/proguard/optimize/KeptClassFilter.java deleted file mode 100644 index 4b9d090..0000000 --- a/src/proguard/optimize/KeptClassFilter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * 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 - * 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.visitor.ClassVisitor; - -/** - * This ClassVisitor delegates all its method calls to another ClassVisitor, - * but only for Clazz objects that are marked as kept. - * - * @see KeepMarker - * - * @author Eric Lafortune - */ -public class KeptClassFilter -implements ClassVisitor -{ - private final ClassVisitor classVisitor; - - - /** - * Creates a new KeptClassFilter. - * @param classVisitor the class visitor to which the visiting will be - * delegated. - */ - public KeptClassFilter(ClassVisitor classVisitor) - { - this.classVisitor = classVisitor; - } - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - if (KeepMarker.isKept(programClass)) - { - classVisitor.visitProgramClass(programClass); - } - } - - - public void visitLibraryClass(LibraryClass libraryClass) - { - if (KeepMarker.isKept(libraryClass)) - { - classVisitor.visitLibraryClass(libraryClass); - } - } -}
\ No newline at end of file diff --git a/src/proguard/optimize/KeptMemberFilter.java b/src/proguard/optimize/KeptMemberFilter.java deleted file mode 100644 index 5b25425..0000000 --- a/src/proguard/optimize/KeptMemberFilter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * 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 - * 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.visitor.MemberVisitor; - -/** - * This MemberVisitor delegates all its method calls to another MemberVisitor, - * but only for Member objects that are marked as kept. - * - * @see KeepMarker - * - * @author Eric Lafortune - */ -public class KeptMemberFilter -implements MemberVisitor -{ - private final MemberVisitor memberVisitor; - - - /** - * Creates a new KeptMemberFilter. - * @param memberVisitor the member visitor to which the visiting will be - * delegated. - */ - public KeptMemberFilter(MemberVisitor memberVisitor) - { - this.memberVisitor = memberVisitor; - } - - - // Implementations for MemberVisitor. - - - public void visitProgramField(ProgramClass programClass, ProgramField programField) - { - if (KeepMarker.isKept(programField)) - { - memberVisitor.visitProgramField(programClass, programField); - } - } - - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - if (KeepMarker.isKept(programMethod)) - { - memberVisitor.visitProgramMethod(programClass, programMethod); - } - } - - - public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) - { - if (KeepMarker.isKept(libraryField)) - { - memberVisitor.visitLibraryField(libraryClass, libraryField); - } - } - - - public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) - { - if (KeepMarker.isKept(libraryMethod)) - { - memberVisitor.visitLibraryMethod(libraryClass, libraryMethod); - } - } -}
\ No newline at end of file diff --git a/src/proguard/optimize/MemberDescriptorSpecializer.java b/src/proguard/optimize/MemberDescriptorSpecializer.java index 7f051f5..0d0b841 100644 --- a/src/proguard/optimize/MemberDescriptorSpecializer.java +++ b/src/proguard/optimize/MemberDescriptorSpecializer.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 @@ -39,7 +39,7 @@ public class MemberDescriptorSpecializer extends SimplifiedVisitor implements MemberVisitor { - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; private final MemberVisitor extraParameterMemberVisitor; diff --git a/src/proguard/optimize/MethodDescriptorShrinker.java b/src/proguard/optimize/MethodDescriptorShrinker.java index f4667ee..48374e7 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-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 @@ -23,7 +23,7 @@ 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; @@ -95,9 +95,11 @@ implements MemberVisitor, if (DEBUG) { System.out.println("MethodDescriptorShrinker:"); - System.out.println(" ["+programClass.getName()+"."+ - name+descriptor+"] -> ["+ - newName+newDescriptor+"]"); + System.out.println(" Class file = "+programClass.getName()); + System.out.println(" Method name = "+name); + System.out.println(" -> "+newName); + System.out.println(" Method descriptor = "+descriptor); + System.out.println(" -> "+newDescriptor); } ConstantPoolEditor constantPoolEditor = diff --git a/src/proguard/optimize/MethodStaticizer.java b/src/proguard/optimize/MethodStaticizer.java index 9bd7b2a..8dd11e1 100644 --- a/src/proguard/optimize/MethodStaticizer.java +++ b/src/proguard/optimize/MethodStaticizer.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 diff --git a/src/proguard/optimize/OptimizationInfoMemberFilter.java b/src/proguard/optimize/OptimizationInfoMemberFilter.java index a6d3cc7..8760aee 100644 --- a/src/proguard/optimize/OptimizationInfoMemberFilter.java +++ b/src/proguard/optimize/OptimizationInfoMemberFilter.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 diff --git a/src/proguard/optimize/Optimizer.java b/src/proguard/optimize/Optimizer.java index c5db18b..a3e8a6e 100644 --- a/src/proguard/optimize/Optimizer.java +++ b/src/proguard/optimize/Optimizer.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 @@ -23,8 +23,7 @@ package proguard.optimize; import proguard.*; import proguard.classfile.*; import proguard.classfile.attribute.visitor.*; -import proguard.classfile.constant.Constant; -import proguard.classfile.constant.visitor.*; +import proguard.classfile.constant.visitor.AllConstantVisitor; import proguard.classfile.editor.*; import proguard.classfile.instruction.visitor.*; import proguard.classfile.util.MethodLinker; @@ -67,7 +66,6 @@ public class Optimizer private static final String CODE_SIMPLIFICATION_CAST = "code/simplification/cast"; private static final String CODE_SIMPLIFICATION_FIELD = "code/simplification/field"; private static final String CODE_SIMPLIFICATION_BRANCH = "code/simplification/branch"; - private static final String CODE_SIMPLIFICATION_STRING = "code/simplification/string"; private static final String CODE_SIMPLIFICATION_ADVANCED = "code/simplification/advanced"; private static final String CODE_REMOVAL_ADVANCED = "code/removal/advanced"; private static final String CODE_REMOVAL_SIMPLE = "code/removal/simple"; @@ -82,7 +80,6 @@ public class Optimizer CLASS_MERGING_VERTICAL, CLASS_MERGING_HORIZONTAL, FIELD_REMOVAL_WRITEONLY, - FIELD_MARKING_PRIVATE, FIELD_PROPAGATION_VALUE, METHOD_MARKING_PRIVATE, METHOD_MARKING_STATIC, @@ -99,7 +96,6 @@ public class Optimizer CODE_SIMPLIFICATION_CAST, CODE_SIMPLIFICATION_FIELD, CODE_SIMPLIFICATION_BRANCH, - CODE_SIMPLIFICATION_STRING, CODE_SIMPLIFICATION_ADVANCED, CODE_REMOVAL_ADVANCED, CODE_REMOVAL_SIMPLE, @@ -161,7 +157,6 @@ public class Optimizer boolean codeSimplificationCast = filter.matches(CODE_SIMPLIFICATION_CAST); boolean codeSimplificationField = filter.matches(CODE_SIMPLIFICATION_FIELD); boolean codeSimplificationBranch = filter.matches(CODE_SIMPLIFICATION_BRANCH); - boolean codeSimplificationString = filter.matches(CODE_SIMPLIFICATION_STRING); boolean codeSimplificationAdvanced = filter.matches(CODE_SIMPLIFICATION_ADVANCED); boolean codeRemovalAdvanced = filter.matches(CODE_REMOVAL_ADVANCED); boolean codeRemovalSimple = filter.matches(CODE_REMOVAL_SIMPLE); @@ -191,15 +186,13 @@ public class Optimizer InstructionCounter codeSimplificationCastCounter = new InstructionCounter(); InstructionCounter codeSimplificationFieldCounter = new InstructionCounter(); InstructionCounter codeSimplificationBranchCounter = new InstructionCounter(); - InstructionCounter codeSimplificationStringCounter = new InstructionCounter(); InstructionCounter codeSimplificationAdvancedCounter = new InstructionCounter(); InstructionCounter deletedCounter = new InstructionCounter(); InstructionCounter addedCounter = new InstructionCounter(); MemberCounter codeRemovalVariableCounter = new MemberCounter(); ExceptionCounter codeRemovalExceptionCounter = new ExceptionCounter(); MemberCounter codeAllocationVariableCounter = new MemberCounter(); - MemberCounter initializerFixCounter1 = new MemberCounter(); - MemberCounter initializerFixCounter2 = new MemberCounter(); + MemberCounter initializerFixCounter = new MemberCounter(); // Some optimizations are required by other optimizations. codeSimplificationAdvanced = @@ -257,27 +250,10 @@ public class Optimizer new AllInstructionVisitor( new DotClassClassVisitor(keepMarker))))); - // We also keep all classes that are accessed dynamically. + // We also keep all classes that are involved in Class.forName constructs. programClassPool.classesAccept( new AllConstantVisitor( - new ConstantTagFilter(ClassConstants.CONSTANT_String, - new ReferencedClassVisitor(keepMarker)))); - - // We also keep all class members that are accessed dynamically. - programClassPool.classesAccept( - new AllConstantVisitor( - new ConstantTagFilter(ClassConstants.CONSTANT_String, - new ReferencedMemberVisitor(keepMarker)))); - - // We also keep all bootstrap method signatures. - programClassPool.classesAccept( - new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_7, - new AllAttributeVisitor( - new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods, - new AllBootstrapMethodInfoVisitor( - new BootstrapMethodHandleTraveler( - new MethodrefTraveler( - new ReferencedMemberVisitor(keepMarker)))))))); + new ClassForNameClassVisitor(keepMarker))); // Attach some optimization info to all classes and class members, so // it can be filled out later. @@ -344,9 +320,6 @@ public class Optimizer new ParameterUsageMarker(!methodMarkingStatic, !methodRemovalParameter)))); - // Mark all classes that have static initializers. - programClassPool.classesAccept(new StaticInitializerContainingClassMarker()); - // Mark all methods that have side effects. programClassPool.accept(new SideEffectMethodMarker()); @@ -374,29 +347,18 @@ public class Optimizer new AllAttributeVisitor( new PartialEvaluator(valueFactory, storingInvocationUnit, false)))); - if (fieldPropagationValue) - { - // Count the constant fields. - programClassPool.classesAccept( + // Count the constant fields and methods. + programClassPool.classesAccept( + new MultiClassVisitor( + new ClassVisitor[] + { new AllFieldVisitor( - new ConstantMemberFilter(fieldPropagationValueCounter))); - } - - if (methodPropagationParameter) - { - // Count the constant method parameters. - programClassPool.classesAccept( + new ConstantMemberFilter(fieldPropagationValueCounter)), new AllMethodVisitor( - new ConstantParameterFilter(methodPropagationParameterCounter))); - } - - if (methodPropagationReturnvalue) - { - // Count the constant method return values. - programClassPool.classesAccept( + new ConstantParameterFilter(methodPropagationParameterCounter)), new AllMethodVisitor( - new ConstantMemberFilter(methodPropagationReturnvalueCounter))); - } + new ConstantMemberFilter(methodPropagationReturnvalueCounter)), + })); } InvocationUnit loadingInvocationUnit = @@ -456,12 +418,6 @@ public class Optimizer // This operation also updates the stack sizes. programClassPool.classesAccept( new MemberReferenceFixer()); - - // Remove unused bootstrap method arguments. - programClassPool.classesAccept( - new AllAttributeVisitor( - new AllBootstrapMethodInfoVisitor( - new BootstrapMethodArgumentShrinker()))); } if (methodRemovalParameter || @@ -485,39 +441,17 @@ public class Optimizer new StackSizeUpdater()))); } - if (methodRemovalParameter && - methodRemovalParameterCounter.getCount() > 0) - { - // Tweak the descriptors of duplicate initializers, due to removed - // method parameters. - programClassPool.classesAccept( - new AllMethodVisitor( - new DuplicateInitializerFixer(initializerFixCounter1))); - - if (initializerFixCounter1.getCount() > 0) - { - // Fix all invocations of tweaked initializers. - programClassPool.classesAccept( - new AllMethodVisitor( - new AllAttributeVisitor( - new DuplicateInitializerInvocationFixer(addedCounter)))); - - // Fix all references to tweaked initializers. - programClassPool.classesAccept(new MemberReferenceFixer()); - } - } - - //// Specializing the class member descriptors seems to increase the - //// class file size, on average. - //// Specialize all class member descriptors. - //programClassPool.classesAccept(new AllMemberVisitor( - // new OptimizationInfoMemberFilter( - // new MemberDescriptorSpecializer()))); - // - //// Fix all references to classes, for MemberDescriptorSpecializer. - //programClassPool.classesAccept(new AllMemberVisitor( - // new OptimizationInfoMemberFilter( - // new ClassReferenceFixer(true)))); +// // Specializing the class member descriptors seems to increase the +// // class file size, on average. +// // Specialize all class member descriptors. +// programClassPool.classesAccept(new AllMemberVisitor( +// new OptimizationInfoMemberFilter( +// new MemberDescriptorSpecializer()))); +// +// // Fix all references to classes, for MemberDescriptorSpecializer. +// programClassPool.classesAccept(new AllMemberVisitor( +// new OptimizationInfoMemberFilter( +// new ClassReferenceFixer(true)))); // Mark all classes with package visible members. // Mark all exception catches of methods. @@ -527,13 +461,13 @@ public class Optimizer new MultiClassVisitor( new ClassVisitor[] { - new PackageVisibleMemberContainingClassMarker(), new AllConstantVisitor( new PackageVisibleMemberInvokingClassMarker()), new AllMethodVisitor( new MultiMemberVisitor( new MemberVisitor[] { + new PackageVisibleMemberContainingClassMarker(), new AllAttributeVisitor( new MultiAttributeVisitor( new AttributeVisitor[] @@ -577,8 +511,8 @@ public class Optimizer classMergingHorizontalCounter)); } - if (classMergingVerticalCounter .getCount() > 0 || - classMergingHorizontalCounter.getCount() > 0) + if (classMergingVertical || + classMergingHorizontal) { // Clean up inner class attributes to avoid loops. programClassPool.classesAccept(new RetargetedInnerClassAttributeRemover()); @@ -596,20 +530,18 @@ public class Optimizer new AllConstantVisitor( new AccessFixer())); } + } - // Fix the access flags of the inner classes information. - programClassPool.classesAccept( - new AllAttributeVisitor( - new AllInnerClassesInfoVisitor( - new InnerClassesAccessFixer()))); - - // Tweak the descriptors of duplicate initializers, due to merged - // parameter classes. + if (methodRemovalParameter || + classMergingVertical || + classMergingHorizontal) + { + // Tweak the descriptors of duplicate initializers. programClassPool.classesAccept( new AllMethodVisitor( - new DuplicateInitializerFixer(initializerFixCounter2))); + new DuplicateInitializerFixer(initializerFixCounter))); - if (initializerFixCounter2.getCount() > 0) + if (initializerFixCounter.getCount() > 0) { // Fix all invocations of tweaked initializers. programClassPool.classesAccept( @@ -663,14 +595,14 @@ public class Optimizer new NonPrivateMemberMarker()); } - if (fieldMarkingPrivate) + if (fieldMarkingPrivate || + methodMarkingPrivate) { // Make all non-private fields private, whereever possible. programClassPool.classesAccept( - new ClassAccessFilter(0, ClassConstants.INTERNAL_ACC_INTERFACE, new AllFieldVisitor( new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, - new MemberPrivatizer(fieldMarkingPrivateCounter))))); + new MemberPrivatizer(fieldMarkingPrivateCounter)))); } if (methodMarkingPrivate) @@ -683,9 +615,9 @@ public class Optimizer new MemberPrivatizer(methodMarkingPrivateCounter))))); } - if ((methodInliningUniqueCounter .getCount() > 0 || - methodInliningShortCounter .getCount() > 0 || - methodInliningTailrecursionCounter.getCount() > 0) && + if ((methodInliningUnique || + methodInliningShort || + methodInliningTailrecursion) && configuration.allowAccessModification) { // Fix the access flags of referenced classes and class members, @@ -695,10 +627,10 @@ public class Optimizer new AccessFixer())); } - if (methodRemovalParameterCounter .getCount() > 0 || - classMergingVerticalCounter .getCount() > 0 || - classMergingHorizontalCounter .getCount() > 0 || - methodMarkingPrivateCounter .getCount() > 0 ) + if (methodRemovalParameter || + classMergingVertical || + classMergingHorizontal || + methodMarkingPrivate) { // Fix invocations of interface methods, of methods that have become // non-abstract or private, and of methods that have moved to a @@ -775,15 +707,6 @@ public class Optimizer new GotoReturnReplacer(codeAttributeEditor, codeSimplificationBranchCounter)); } - if (codeSimplificationString) - { - // Peephole optimizations involving branches. - peepholeOptimizations.add( - new InstructionSequencesReplacer(InstructionSequenceConstants.CONSTANTS, - InstructionSequenceConstants.STRING, - branchTargetFinder, codeAttributeEditor, codeSimplificationStringCounter)); - } - if (!peepholeOptimizations.isEmpty()) { // Convert the list into an array. @@ -826,6 +749,14 @@ public class Optimizer new AllAttributeVisitor( new VariableShrinker(codeRemovalVariableCounter)))); } + else + { + // Clean up all unused local variables. + programClassPool.classesAccept( + new AllMethodVisitor( + new AllAttributeVisitor( + new VariableCleaner()))); + } if (codeAllocationVariable) { @@ -836,11 +767,6 @@ public class Optimizer new VariableOptimizer(false, codeAllocationVariableCounter)))); } - - // Remove unused constants. - programClassPool.classesAccept( - new ConstantPoolShrinker()); - int classMarkingFinalCount = classMarkingFinalCounter .getCount(); int classMergingVerticalCount = classMergingVerticalCounter .getCount(); int classMergingHorizontalCount = classMergingHorizontalCounter .getCount(); @@ -850,7 +776,7 @@ public class Optimizer int methodMarkingPrivateCount = methodMarkingPrivateCounter .getCount(); int methodMarkingStaticCount = methodMarkingStaticCounter .getCount(); int methodMarkingFinalCount = methodMarkingFinalCounter .getCount(); - int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter1.getCount() - initializerFixCounter2.getCount(); + int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter.getCount(); int methodPropagationParameterCount = methodPropagationParameterCounter .getCount(); int methodPropagationReturnvalueCount = methodPropagationReturnvalueCounter.getCount(); int methodInliningShortCount = methodInliningShortCounter .getCount(); @@ -862,23 +788,12 @@ public class Optimizer int codeSimplificationCastCount = codeSimplificationCastCounter .getCount(); int codeSimplificationFieldCount = codeSimplificationFieldCounter .getCount(); int codeSimplificationBranchCount = codeSimplificationBranchCounter .getCount(); - int codeSimplificationStringCount = codeSimplificationStringCounter .getCount(); int codeSimplificationAdvancedCount = codeSimplificationAdvancedCounter .getCount(); int codeRemovalCount = deletedCounter .getCount() - addedCounter.getCount(); int codeRemovalVariableCount = codeRemovalVariableCounter .getCount(); int codeRemovalExceptionCount = codeRemovalExceptionCounter .getCount(); int codeAllocationVariableCount = codeAllocationVariableCounter .getCount(); - // Forget about constant fields, parameters, and return values, if they - // didn't lead to any useful optimizations. We want to avoid fruitless - // additional optimization passes. - if (codeSimplificationAdvancedCount == 0) - { - fieldPropagationValueCount = 0; - methodPropagationParameterCount = 0; - methodPropagationReturnvalueCount = 0; - } - if (configuration.verbose) { System.out.println(" Number of finalized classes: " + classMarkingFinalCount + disabled(classMarkingFinal)); @@ -902,7 +817,6 @@ public class Optimizer System.out.println(" Number of cast peephole optimizations: " + codeSimplificationCastCount + disabled(codeSimplificationCast)); System.out.println(" Number of field peephole optimizations: " + codeSimplificationFieldCount + disabled(codeSimplificationField)); System.out.println(" Number of branch peephole optimizations: " + codeSimplificationBranchCount + disabled(codeSimplificationBranch)); - System.out.println(" Number of string peephole optimizations: " + codeSimplificationStringCount + disabled(codeSimplificationString)); System.out.println(" Number of simplified instructions: " + codeSimplificationAdvancedCount + disabled(codeSimplificationAdvanced)); System.out.println(" Number of removed instructions: " + codeRemovalCount + disabled(codeRemovalAdvanced)); System.out.println(" Number of removed local variables: " + codeRemovalVariableCount + disabled(codeRemovalVariable)); @@ -931,7 +845,6 @@ public class Optimizer codeSimplificationCastCount > 0 || codeSimplificationFieldCount > 0 || codeSimplificationBranchCount > 0 || - codeSimplificationStringCount > 0 || codeSimplificationAdvancedCount > 0 || codeRemovalCount > 0 || codeRemovalVariableCount > 0 || diff --git a/src/proguard/optimize/ParameterShrinker.java b/src/proguard/optimize/ParameterShrinker.java index 2021861..a2bc6d3 100644 --- a/src/proguard/optimize/ParameterShrinker.java +++ b/src/proguard/optimize/ParameterShrinker.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 @@ -23,7 +23,7 @@ package proguard.optimize; import proguard.classfile.*; import proguard.classfile.attribute.*; import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.editor.VariableRemapper; +import proguard.classfile.editor.*; import proguard.classfile.util.*; import proguard.classfile.visitor.MemberVisitor; import proguard.optimize.info.ParameterUsageMarker; 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; diff --git a/src/proguard/optimize/WriteOnlyFieldFilter.java b/src/proguard/optimize/WriteOnlyFieldFilter.java index 4a0e095..578beb2 100644 --- a/src/proguard/optimize/WriteOnlyFieldFilter.java +++ b/src/proguard/optimize/WriteOnlyFieldFilter.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 diff --git a/src/proguard/optimize/evaluation/EvaluationShrinker.java b/src/proguard/optimize/evaluation/EvaluationShrinker.java index bc5f658..1463feb 100644 --- a/src/proguard/optimize/evaluation/EvaluationShrinker.java +++ b/src/proguard/optimize/evaluation/EvaluationShrinker.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 @@ -34,8 +34,6 @@ import proguard.evaluation.*; import proguard.evaluation.value.*; import proguard.optimize.info.*; -import java.util.Arrays; - /** * This AttributeVisitor simplifies the code attributes that it visits, based * on partial evaluation. @@ -57,14 +55,13 @@ implements AttributeVisitor private final InstructionVisitor extraDeletedInstructionVisitor; private final InstructionVisitor extraAddedInstructionVisitor; - private final PartialEvaluator partialEvaluator; - private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator(); - private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true); - private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier(); - private final MyProducerMarker producerMarker = new MyProducerMarker(); - private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker(); - private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer(); - private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false); + private final PartialEvaluator partialEvaluator; + private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator(); + private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true); + private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier(); + private final MyProducerMarker producerMarker = new MyProducerMarker(); + private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer(); + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false); private boolean[][] variablesNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_VARIABLES_SIZE]; private boolean[][] stacksNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_STACK_SIZE]; @@ -279,10 +276,18 @@ implements AttributeVisitor if (partialEvaluator.isTraced(offset) && !isInstructionNecessary(offset)) { - Instruction instruction = InstructionFactory.create(codeAttribute.code, - offset); - - instruction.accept(clazz, method, codeAttribute, offset, variableInitializationMarker); + // Is the corresponding variable necessary anywhere in the code, + // accoriding to a simple partial evaluation? + int variableIndex = partialEvaluator.initializedVariable(offset); + if (variableIndex >= 0 && + isVariableInitializationNecessary(clazz, + method, + codeAttribute, + offset, + variableIndex)) + { + markInstruction(offset); + } } } if (DEBUG) System.out.println(); @@ -462,9 +467,7 @@ implements AttributeVisitor */ private class MyUnusedParameterSimplifier extends SimplifiedVisitor - implements InstructionVisitor, - ConstantVisitor, - MemberVisitor + implements InstructionVisitor, ConstantVisitor, MemberVisitor { private int invocationOffset; private ConstantInstruction invocationInstruction; @@ -654,40 +657,6 @@ implements AttributeVisitor /** - * This InstructionVisitor marks variable initializations that are - * necessary to appease the JVM. - */ - private class MyVariableInitializationMarker - extends SimplifiedVisitor - implements InstructionVisitor - { - // Implementations for InstructionVisitor. - - public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} - - - public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) - { - if (!variableInstruction.isLoad()) - { - int variableIndex = variableInstruction.variableIndex; - - if (isVariableInitialization(offset, - variableIndex) && - isVariableInitializationNecessary(clazz, - method, - codeAttribute, - offset, - variableIndex)) - { - markInstruction(offset); - } - } - } - } - - - /** * This InstructionVisitor fixes instructions locally, popping any unused * produced stack entries after marked instructions, and popping produced * stack entries and pushing missing stack entries instead of unmarked @@ -718,23 +687,12 @@ implements AttributeVisitor int requiredPushCount = 0; for (int stackIndex = 0; stackIndex < popCount; stackIndex++) { - InstructionOffsetValue producerOffsets = - tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(); - - if (!isStackSimplifiedBefore(offset, top - stackIndex)) + // Is the stack entry required by other consumers? + if (!isStackSimplifiedBefore(offset, top - stackIndex) && + !isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex)) { - // Is the stack entry pushed by any producer, - // because it is required by other consumers? - if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex)) - { - // Make sure it is pushed after all producers. - markStackEntriesAfter(producerOffsets, top - stackIndex); - } - else - { - // Remember to push it. - requiredPushCount++; - } + // Remember to push it. + requiredPushCount++; } } @@ -799,16 +757,9 @@ implements AttributeVisitor int expectedPopCount = 0; for (int stackIndex = 0; stackIndex < popCount; stackIndex++) { - InstructionOffsetValue producerOffsets = - tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(); - - // Is the stack entry pushed by any producer, - // because it is required by other consumers? - if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex)) + // Is the stack entry required by other consumers? + if (isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex)) { - // Make sure it is pushed after all producers. - markStackEntriesAfter(producerOffsets, top - stackIndex); - // Remember to pop it. expectedPopCount++; } @@ -1101,7 +1052,6 @@ implements AttributeVisitor byte oldOpcode = instruction.opcode; byte newOpcode = 0; - byte addOpcode = 0; // Simplify the popping instruction if possible. switch (oldOpcode) @@ -1282,20 +1232,9 @@ implements AttributeVisitor stackEntryPresent1) { // Will both elements be present? - if (!stackEntryPresent1) - { - // Pop the original top element (later bottom element). - newOpcode = InstructionConstants.OP_POP; - } - else if (!stackEntryPresent0) - { - // Swap both elements and pop the top one. - newOpcode = InstructionConstants.OP_SWAP; - addOpcode = InstructionConstants.OP_POP; - } - else + if (stackEntryPresent0 && + stackEntryPresent1) { - // Just swap both elements. newOpcode = InstructionConstants.OP_SWAP; } } @@ -1303,7 +1242,6 @@ implements AttributeVisitor } } - // Is there a replacement opcode? if (newOpcode == 0) { // Delete the instruction. @@ -1332,21 +1270,6 @@ implements AttributeVisitor if (DEBUG) System.out.println(" Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString()); } - - // Is there an additional opcode? - if (addOpcode != 0) - { - // Add the instruction. - Instruction additionalInstruction = new SimpleInstruction(addOpcode); - codeAttributeEditor.insertAfterInstruction(dupOffset, additionalInstruction); - - if (extraAddedInstructionVisitor != null) - { - extraAddedInstructionVisitor.visitSimpleInstruction(null, null, null, dupOffset, null); - } - - if (DEBUG) System.out.println(" Adding instruction "+additionalInstruction.toString(dupOffset)); - } } @@ -1673,7 +1596,10 @@ implements AttributeVisitor { for (int offset = 0; offset < codeLength; offset++) { - Arrays.fill(variablesNecessaryAfter[offset], 0, maxLocals, false); + for (int index = 0; index < maxLocals; index++) + { + variablesNecessaryAfter[offset][index] = false; + } } } @@ -1686,7 +1612,10 @@ implements AttributeVisitor { for (int offset = 0; offset < codeLength; offset++) { - Arrays.fill(stacksNecessaryAfter[offset], 0, maxStack, false); + for (int index = 0; index < maxStack; index++) + { + stacksNecessaryAfter[offset][index] = false; + } } } @@ -1699,7 +1628,10 @@ implements AttributeVisitor { for (int offset = 0; offset < codeLength; offset++) { - Arrays.fill(stacksSimplifiedBefore[offset], 0, maxStack, false); + for (int index = 0; index < maxStack; index++) + { + stacksSimplifiedBefore[offset][index] = false; + } } } @@ -1709,7 +1641,10 @@ implements AttributeVisitor } else { - Arrays.fill(instructionsNecessary, 0, codeLength, false); + for (int index = 0; index < codeLength; index++) + { + instructionsNecessary[index] = false; + } } } @@ -1735,34 +1670,6 @@ implements AttributeVisitor /** - * Returns whether the specified variable is initialized at the specified - * offset. - */ - private boolean isVariableInitialization(int instructionOffset, - int variableIndex) - { - // Wasn't the variable set yet? - Value valueBefore = partialEvaluator.getVariablesBefore(instructionOffset).getValue(variableIndex); - if (valueBefore == null) - { - return true; - } - - // Is the computational type different now? - Value valueAfter = partialEvaluator.getVariablesAfter(instructionOffset).getValue(variableIndex); - if (valueAfter.computationalType() != valueBefore.computationalType()) - { - return true; - } - - // Was the producer an argument (which may be removed)? - Value producersBefore = partialEvaluator.getVariablesBefore(instructionOffset).getProducerValue(variableIndex); - return producersBefore.instructionOffsetValue().instructionOffsetCount() == 1 && - producersBefore.instructionOffsetValue().instructionOffset(0) == PartialEvaluator.AT_METHOD_ENTRY; - } - - - /** * Returns whether the specified variable must be initialized at the * specified offset, according to the verifier of the JVM. */ @@ -1779,8 +1686,8 @@ implements AttributeVisitor { if (DEBUG) System.out.println("Simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]"); - // Lazily perform simple partial evaluation, the way the JVM - // verifier would do it. + // Lazily compute perform simple partial evaluation, the way the + // JVM preverifier would do it. simplePartialEvaluator.visitCodeAttribute(clazz, method, codeAttribute); if (DEBUG) System.out.println("End of simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]"); @@ -1788,7 +1695,7 @@ implements AttributeVisitor // Check if the variable is necessary elsewhere. for (int offset = 0; offset < codeLength; offset++) { - if (partialEvaluator.isTraced(offset)) + if (isInstructionNecessary(offset)) { Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex); if (producer != null) @@ -1801,22 +1708,16 @@ implements AttributeVisitor InstructionOffsetValue simpleProducerOffsets = simpleProducer.instructionOffsetValue(); - if (DEBUG) + // Does the sophisticated partial evaluation have fewer + // producers than the simple one? + // And does the simple partial evaluation point to an + // initialization of the variable? + if (producerOffsets.instructionOffsetCount() < + simpleProducerOffsets.instructionOffsetCount() && + isVariableNecessaryAfterAny(producerOffsets, variableIndex) && + simpleProducerOffsets.contains(initializationOffset)) { - System.out.println(" ["+offset+"] producers ["+producerOffsets+"], simple producers ["+simpleProducerOffsets+"]"); - } - - // Is the variable being used without all of its - // immediate simple producers being marked? - if (isVariableNecessaryAfterAny(producerOffsets, variableIndex) && - !isVariableNecessaryAfterAll(simpleProducerOffsets, variableIndex)) - { - if (DEBUG) - { - System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] necessary"); - } - - // Then the initialization may be necessary. + // Then the initialization is necessary. return true; } } @@ -1825,11 +1726,6 @@ implements AttributeVisitor } } - if (DEBUG) - { - System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] not necessary"); - } - return false; } @@ -1853,7 +1749,7 @@ implements AttributeVisitor /** * Returns whether the specified variable is ever necessary after any - * instructions in the specified block. + * instruction in the specified block. */ private boolean isVariableNecessaryAfterAny(int startOffset, int endOffset, @@ -1873,7 +1769,7 @@ implements AttributeVisitor /** * Returns whether the specified variable is ever necessary after any - * instructions in the specified set of instructions offsets. + * instruction in the specified set of instructions offsets. */ private boolean isVariableNecessaryAfterAny(InstructionOffsetValue instructionOffsetValue, int variableIndex) @@ -1893,28 +1789,6 @@ implements AttributeVisitor } - /** - * Returns whether the specified variable is ever necessary after all - * instructions in the specified set of instructions offsets. - */ - private boolean isVariableNecessaryAfterAll(InstructionOffsetValue instructionOffsetValue, - int variableIndex) - { - int count = instructionOffsetValue.instructionOffsetCount(); - - for (int index = 0; index < count; index++) - { - if (!isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index), - variableIndex)) - { - return false; - } - } - - return true; - } - - private boolean isVariableNecessaryAfter(int instructionOffset, int variableIndex) { @@ -1923,36 +1797,6 @@ implements AttributeVisitor } - /** - * Marks the stack entries after the given offsets. - * @param instructionOffsets the offsets of the stack entries to be marked. - * @param stackIndex the index of the stack entries to be marked - * (counting from the bottom). - */ - private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets, - int stackIndex) - { - if (instructionOffsets != null) - { - int offsetCount = instructionOffsets.instructionOffsetCount(); - for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++) - { - // Make sure the stack entry and the instruction are marked - // at the producing offset. - int offset = instructionOffsets.instructionOffset(offsetIndex); - - markStackEntryAfter(offset, stackIndex); - } - } - } - - - /** - * Marks the stack entry after the given offset. - * @param instructionOffset the offset of the stack entry to be marked. - * @param stackIndex the index of the stack entry to be marked - * (counting from the bottom). - */ private void markStackEntryAfter(int instructionOffset, int stackIndex) { @@ -1970,13 +1814,6 @@ implements AttributeVisitor } - /** - * Returns whether any of the stack entries after the given offsets are - * necessary. - * @param instructionOffsets the offsets of the stack entries to be checked. - * @param stackIndex the index of the stack entries to be checked - * (counting from the bottom). - */ private boolean isAnyStackEntryNecessaryAfter(InstructionOffsetValue instructionOffsets, int stackIndex) { @@ -1994,13 +1831,6 @@ implements AttributeVisitor } - /** - * Returns whether any of the stack entries after the given offset are - * necessary. - * @param instructionOffset the offset of the stack entry to be checked. - * @param stackIndex the index of the stack entry to be checked - * (counting from the bottom). - */ private boolean isStackEntryNecessaryAfter(int instructionOffset, int stackIndex) { diff --git a/src/proguard/optimize/evaluation/EvaluationSimplifier.java b/src/proguard/optimize/evaluation/EvaluationSimplifier.java index b207108..0c3a9c7 100644 --- a/src/proguard/optimize/evaluation/EvaluationSimplifier.java +++ b/src/proguard/optimize/evaluation/EvaluationSimplifier.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 @@ -43,9 +43,6 @@ extends SimplifiedVisitor implements AttributeVisitor, InstructionVisitor { - private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f); - private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0); - //* private static final boolean DEBUG = false; /*/ @@ -562,11 +559,10 @@ implements AttributeVisitor, Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0); if (pushedValue.isParticular()) { - // Make sure to distinguish between +0.0 and -0.0. float value = pushedValue.floatValue().value(); - if (value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS || - value == 1.0f || - value == 2.0f) + if (value == 0f || + value == 1f || + value == 2f) { replaceConstantPushInstruction(clazz, offset, @@ -631,9 +627,8 @@ implements AttributeVisitor, Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0); if (pushedValue.isParticular()) { - // Make sure to distinguish between +0.0 and -0.0. double value = pushedValue.doubleValue().value(); - if (value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS || + if (value == 0.0 || value == 1.0) { replaceConstantPushInstruction(clazz, diff --git a/src/proguard/optimize/evaluation/LivenessAnalyzer.java b/src/proguard/optimize/evaluation/LivenessAnalyzer.java index 747f993..9915027 100644 --- a/src/proguard/optimize/evaluation/LivenessAnalyzer.java +++ b/src/proguard/optimize/evaluation/LivenessAnalyzer.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 @@ -79,16 +79,6 @@ implements AttributeVisitor, /** - * Returns whether the instruction at the given offset has ever been - * executed during the partial evaluation. - */ - public boolean isTraced(int instructionOffset) - { - return partialEvaluator.isTraced(instructionOffset); - } - - - /** * Returns whether the specified variable is alive before the instruction * at the given offset. */ diff --git a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java b/src/proguard/optimize/evaluation/LoadingInvocationUnit.java index 578ece5..8379c57 100644 --- a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java +++ b/src/proguard/optimize/evaluation/LoadingInvocationUnit.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 @@ -35,9 +35,9 @@ import proguard.evaluation.value.*; public class LoadingInvocationUnit extends BasicInvocationUnit { - private final boolean loadFieldValues; - private final boolean loadMethodParameterValues; - private final boolean loadMethodReturnValues; + private boolean loadFieldValues; + private boolean loadMethodParameterValues; + private boolean loadMethodReturnValues; /** @@ -84,6 +84,8 @@ extends BasicInvocationUnit value.isParticular()) { return value; +// // Make sure the value is refreshed. +// return refresh(value); } } } @@ -108,6 +110,8 @@ extends BasicInvocationUnit value.isParticular()) { return value; +// // Make sure the value is refreshed. +// return refresh(value); } } } @@ -130,6 +134,8 @@ extends BasicInvocationUnit value.isParticular()) { return value; +// // Make sure the value is refreshed. +// return refresh(value); } } @@ -157,6 +163,8 @@ extends BasicInvocationUnit value.isParticular()) { return value; +// // Make sure the value is refreshed. +// return refresh(value); } } } @@ -165,8 +173,8 @@ extends BasicInvocationUnit refConstant, type); } - - +// +// // // Small utility methods. // // private Value refresh(Value value) diff --git a/src/proguard/optimize/evaluation/PartialEvaluator.java b/src/proguard/optimize/evaluation/PartialEvaluator.java index b2776d1..5790a36 100644 --- a/src/proguard/optimize/evaluation/PartialEvaluator.java +++ b/src/proguard/optimize/evaluation/PartialEvaluator.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 @@ -31,8 +31,6 @@ import proguard.evaluation.*; import proguard.evaluation.value.*; import proguard.optimize.peephole.BranchTargetFinder; -import java.util.Arrays; - /** * This AttributeVisitor performs partial evaluation on the code attributes * that it visits. @@ -70,6 +68,7 @@ implements AttributeVisitor, private TracedStack[] stacksAfter = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH]; private boolean[] generalizedContexts = new boolean[ClassConstants.TYPICAL_CODE_LENGTH]; private int[] evaluationCounts = new int[ClassConstants.TYPICAL_CODE_LENGTH]; + private int[] initializedVariables = new int[ClassConstants.TYPICAL_CODE_LENGTH]; private boolean evaluateExceptions; private final BasicBranchUnit branchUnit; @@ -190,47 +189,6 @@ implements AttributeVisitor, if (DEBUG) { method.accept(clazz, new ClassPrinter()); - - System.out.println("Evaluation results:"); - - int offset = 0; - do - { - if (isBranchOrExceptionTarget(offset)) - { - System.out.println("Branch target from ["+branchOriginValues[offset]+"]:"); - if (isTraced(offset)) - { - System.out.println(" Vars: "+variablesBefore[offset]); - System.out.println(" Stack: "+stacksBefore[offset]); - } - } - - Instruction instruction = InstructionFactory.create(codeAttribute.code, - offset); - System.out.println(instruction.toString(offset)); - - if (isTraced(offset)) - { - int initializationOffset = branchTargetFinder.initializationOffset(offset); - if (initializationOffset != NONE) - { - System.out.println(" is to be initialized at ["+initializationOffset+"]"); - } - - InstructionOffsetValue branchTargets = branchTargets(offset); - if (branchTargets != null) - { - System.out.println(" has overall been branching to "+branchTargets); - } - - System.out.println(" Vars: "+variablesAfter[offset]); - System.out.println(" Stack: "+stacksAfter[offset]); - } - - offset += instruction.length(offset); - } - while (offset < codeAttribute.u4codeLength); } throw ex; @@ -254,8 +212,7 @@ implements AttributeVisitor, TracedStack stack = new TracedStack(codeAttribute.u2maxStack); // Initialize the reusable arrays and variables. - initializeArrays(codeAttribute); - initializeParameters(clazz, method, codeAttribute, variables); + initializeVariables(clazz, method, codeAttribute, variables, stack); // Find all instruction offsets,... codeAttribute.accept(clazz, method, branchTargetFinder); @@ -292,6 +249,12 @@ implements AttributeVisitor, if (isTraced(offset)) { + int variableIndex = initializedVariable(offset); + if (variableIndex >= 0) + { + System.out.println(" is initializing variable v"+variableIndex); + } + int initializationOffset = branchTargetFinder.initializationOffset(offset); if (initializationOffset != NONE) { @@ -516,6 +479,16 @@ implements AttributeVisitor, } + /** + * Returns the variable that is initialized at the given instruction offset, + * or <code>NONE</code> if no variable was initialized. + */ + public int initializedVariable(int instructionOffset) + { + return initializedVariables[instructionOffset]; + } + + // Utility methods to evaluate instruction blocks. /** @@ -729,6 +702,9 @@ implements AttributeVisitor, // Reset the trace value. InstructionOffsetValue traceValue = InstructionOffsetValue.EMPTY_VALUE; + // Reset the initialization flag. + variables.resetInitialization(); + // Note that the instruction is only volatile. Instruction instruction = InstructionFactory.create(code, instructionOffset); @@ -767,6 +743,9 @@ implements AttributeVisitor, throw ex; } + // Collect the offsets of the instructions whose results were used. + initializedVariables[instructionOffset] = variables.getInitializationIndex(); + // Collect the branch targets from the branch unit. InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets(); int branchTargetCount = branchTargets.instructionOffsetCount(); @@ -917,7 +896,11 @@ implements AttributeVisitor, subroutinePartialEvaluator = new PartialEvaluator(this); - subroutinePartialEvaluator.initializeArrays(codeAttribute); + subroutinePartialEvaluator.initializeVariables(clazz, + method, + codeAttribute, + variables, + stack); } // Evaluate the subroutine. @@ -969,12 +952,13 @@ implements AttributeVisitor, if (evaluationCounts[offset] == 0) { - variablesBefore[offset] = other.variablesBefore[offset]; - stacksBefore[offset] = other.stacksBefore[offset]; - variablesAfter[offset] = other.variablesAfter[offset]; - stacksAfter[offset] = other.stacksAfter[offset]; - generalizedContexts[offset] = other.generalizedContexts[offset]; - evaluationCounts[offset] = other.evaluationCounts[offset]; + variablesBefore[offset] = other.variablesBefore[offset]; + stacksBefore[offset] = other.stacksBefore[offset]; + variablesAfter[offset] = other.variablesAfter[offset]; + stacksAfter[offset] = other.stacksAfter[offset]; + generalizedContexts[offset] = other.generalizedContexts[offset]; + evaluationCounts[offset] = other.evaluationCounts[offset]; + initializedVariables[offset] = other.initializedVariables[offset]; } else { @@ -984,6 +968,7 @@ implements AttributeVisitor, stacksAfter[offset] .generalize(other.stacksAfter[offset]); //generalizedContexts[offset] evaluationCounts[offset] += other.evaluationCounts[offset]; + //initializedVariables[offset] } } } @@ -1109,7 +1094,11 @@ implements AttributeVisitor, /** * Initializes the data structures for the variables, stack, etc. */ - private void initializeArrays(CodeAttribute codeAttribute) + private void initializeVariables(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + TracedVariables variables, + TracedStack stack) { int codeLength = codeAttribute.u4codeLength; @@ -1117,25 +1106,33 @@ implements AttributeVisitor, if (variablesAfter.length < codeLength) { // Create new arrays. - branchOriginValues = new InstructionOffsetValue[codeLength]; - branchTargetValues = new InstructionOffsetValue[codeLength]; - variablesBefore = new TracedVariables[codeLength]; - stacksBefore = new TracedStack[codeLength]; - variablesAfter = new TracedVariables[codeLength]; - stacksAfter = new TracedStack[codeLength]; - generalizedContexts = new boolean[codeLength]; - evaluationCounts = new int[codeLength]; + branchOriginValues = new InstructionOffsetValue[codeLength]; + branchTargetValues = new InstructionOffsetValue[codeLength]; + variablesBefore = new TracedVariables[codeLength]; + stacksBefore = new TracedStack[codeLength]; + variablesAfter = new TracedVariables[codeLength]; + stacksAfter = new TracedStack[codeLength]; + generalizedContexts = new boolean[codeLength]; + evaluationCounts = new int[codeLength]; + initializedVariables = new int[codeLength]; + + // Reset the arrays. + for (int index = 0; index < codeLength; index++) + { + initializedVariables[index] = NONE; + } } else { // Reset the arrays. - Arrays.fill(branchOriginValues, null); - Arrays.fill(branchTargetValues, null); - Arrays.fill(generalizedContexts, false); - Arrays.fill(evaluationCounts, 0); - for (int index = 0; index < codeLength; index++) { + branchOriginValues[index] = null; + branchTargetValues[index] = null; + generalizedContexts[index] = false; + evaluationCounts[index] = 0; + initializedVariables[index] = NONE; + if (variablesBefore[index] != null) { variablesBefore[index].reset(codeAttribute.u2maxLocals); @@ -1157,17 +1154,7 @@ implements AttributeVisitor, } } } - } - - /** - * Initializes the data structures for the variables, stack, etc. - */ - private void initializeParameters(Clazz clazz, - Method method, - CodeAttribute codeAttribute, - TracedVariables variables) - { // Create the method parameters. TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals); diff --git a/src/proguard/optimize/evaluation/StoringInvocationUnit.java b/src/proguard/optimize/evaluation/StoringInvocationUnit.java index 010dab0..bcbb69f 100644 --- a/src/proguard/optimize/evaluation/StoringInvocationUnit.java +++ b/src/proguard/optimize/evaluation/StoringInvocationUnit.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 diff --git a/src/proguard/optimize/evaluation/TracedBranchUnit.java b/src/proguard/optimize/evaluation/TracedBranchUnit.java index b7dd469..fa5bb79 100644 --- a/src/proguard/optimize/evaluation/TracedBranchUnit.java +++ b/src/proguard/optimize/evaluation/TracedBranchUnit.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 diff --git a/src/proguard/optimize/evaluation/VariableOptimizer.java b/src/proguard/optimize/evaluation/VariableOptimizer.java index a824481..b3ae81c 100644 --- a/src/proguard/optimize/evaluation/VariableOptimizer.java +++ b/src/proguard/optimize/evaluation/VariableOptimizer.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 @@ -21,10 +21,10 @@ package proguard.optimize.evaluation; import proguard.classfile.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.editor.*; import proguard.classfile.visitor.MemberVisitor; import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.VariableRemapper; import proguard.classfile.util.*; /** @@ -35,9 +35,7 @@ import proguard.classfile.util.*; */ public class VariableOptimizer extends SimplifiedVisitor -implements AttributeVisitor, - LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor +implements AttributeVisitor { //* private static final boolean DEBUG = false; @@ -53,7 +51,6 @@ implements AttributeVisitor, private final LivenessAnalyzer livenessAnalyzer = new LivenessAnalyzer(); private final VariableRemapper variableRemapper = new VariableRemapper(); - private VariableCleaner variableCleaner = new VariableCleaner(); private int[] variableMap = new int[ClassConstants.TYPICAL_VARIABLES_SIZE]; @@ -104,11 +101,6 @@ implements AttributeVisitor, // Analyze the liveness of the variables in the code. livenessAnalyzer.visitCodeAttribute(clazz, method, codeAttribute); - // Trim the variables in the local variable tables, because even - // clipping the tables individually may leave some inconsistencies - // between them. - codeAttribute.attributesAccept(clazz, method, this); - int startIndex = (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 || reuseThis ? 0 : 1; @@ -150,19 +142,23 @@ implements AttributeVisitor, } } - // Have we been able to remap any variables? + // Remap the variables. if (remapping) { if (DEBUG) { - System.out.println("VariableOptimizer: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); - for (int index= 0; index < variableSize; index++) + System.out.println("Remapping variables:"); + System.out.println(" Class "+ ClassUtil.externalClassName(clazz.getName())); + System.out.println(" Method "+ClassUtil.externalFullMethodDescription(clazz.getName(), + 0, + method.getName(clazz), + method.getDescriptor(clazz))); + for (int index = 0; index < variableSize; index++) { - System.out.println(" v"+index+" -> "+variableMap[index]); + System.out.println(" ["+index+"] -> ["+variableMap[index]+"]"); } } - // Remap the variables. variableRemapper.setVariableMap(variableMap); variableRemapper.visitCodeAttribute(clazz, method, codeAttribute); @@ -172,59 +168,6 @@ implements AttributeVisitor, method.accept(clazz, extraVariableMemberVisitor); } } - else - { - // Just clean up any empty variables. - variableCleaner.visitCodeAttribute(clazz, method, codeAttribute); - } - } - - - public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) - { - // Trim the variables in the local variable table. - localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) - { - // Trim the variables in the local variable type table. - localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - // Implementations for LocalVariableInfoVisitor. - - public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) - { - // Trim the local variable to the instructions at which it is alive. - int variable = localVariableInfo.u2index; - int startPC = localVariableInfo.u2startPC; - int endPC = startPC + localVariableInfo.u2length; - - startPC = firstLiveness(startPC, endPC, variable); - endPC = lastLiveness(startPC, endPC, variable); - - localVariableInfo.u2startPC = startPC; - localVariableInfo.u2length = endPC - startPC; - } - - - // Implementations for LocalVariableTypeInfoVisitor. - - public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) - { - // Trim the local variable type to the instructions at which it is alive. - int variable = localVariableTypeInfo.u2index; - int startPC = localVariableTypeInfo.u2startPC; - int endPC = startPC + localVariableTypeInfo.u2length; - - startPC = firstLiveness(startPC, endPC, variable); - endPC = lastLiveness(startPC, endPC, variable); - - localVariableTypeInfo.u2startPC = startPC; - localVariableTypeInfo.u2length = endPC - startPC; } @@ -298,48 +241,4 @@ implements AttributeVisitor, } } } - - - /** - * Returns the first instruction offset between the given offsets at which - * the given variable goes alive. - */ - private int firstLiveness(int startOffset, int endOffset, int variableIndex) - { - for (int offset = startOffset; offset < endOffset; offset++) - { - if (livenessAnalyzer.isTraced(offset) && - livenessAnalyzer.isAliveBefore(offset, variableIndex)) - { - return offset; - } - } - - return endOffset; - } - - - /** - * Returns the last instruction offset between the given offsets before - * which the given variable is still alive. - */ - private int lastLiveness(int startOffset, int endOffset, int variableIndex) - { - int previousOffset = endOffset; - - for (int offset = endOffset-1; offset >= startOffset; offset--) - { - if (livenessAnalyzer.isTraced(offset)) - { - if (livenessAnalyzer.isAliveBefore(offset, variableIndex)) - { - return previousOffset; - } - - previousOffset = offset; - } - } - - return endOffset; - } } diff --git a/src/proguard/optimize/info/AccessMethodMarker.java b/src/proguard/optimize/info/AccessMethodMarker.java index 8d758ce..6965cec 100644 --- a/src/proguard/optimize/info/AccessMethodMarker.java +++ b/src/proguard/optimize/info/AccessMethodMarker.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 @@ -21,8 +21,7 @@ package proguard.optimize.info; import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.*; +import proguard.classfile.attribute.CodeAttribute; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.instruction.*; @@ -72,20 +71,6 @@ implements InstructionVisitor, } - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - // Check the bootstrap method. - invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - // Check the method reference. - clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); - } - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { // Check the referenced class. diff --git a/src/proguard/optimize/info/BackwardBranchMarker.java b/src/proguard/optimize/info/BackwardBranchMarker.java index d53a5b2..9e09b0f 100644 --- a/src/proguard/optimize/info/BackwardBranchMarker.java +++ b/src/proguard/optimize/info/BackwardBranchMarker.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 diff --git a/src/proguard/optimize/info/CatchExceptionMarker.java b/src/proguard/optimize/info/CatchExceptionMarker.java index 5d74047..3f2a06f 100644 --- a/src/proguard/optimize/info/CatchExceptionMarker.java +++ b/src/proguard/optimize/info/CatchExceptionMarker.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 diff --git a/src/proguard/optimize/info/CaughtClassFilter.java b/src/proguard/optimize/info/CaughtClassFilter.java index 4f7caff..5e17763 100644 --- a/src/proguard/optimize/info/CaughtClassFilter.java +++ b/src/proguard/optimize/info/CaughtClassFilter.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 diff --git a/src/proguard/optimize/info/CaughtClassMarker.java b/src/proguard/optimize/info/CaughtClassMarker.java index 5a60aaf..0cc350e 100644 --- a/src/proguard/optimize/info/CaughtClassMarker.java +++ b/src/proguard/optimize/info/CaughtClassMarker.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 @@ -25,9 +25,8 @@ import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.ClassVisitor; /** - * This ClassVisitor marks all program classes that it visits as caught. - * This means that these classes are exception classes that occur in exception - * handlers. + * This InstructionVisitor marks all classes that are used in an 'instanceof' + * test by any of the instructions that it visits. * * @author Eric Lafortune */ diff --git a/src/proguard/optimize/info/ClassOptimizationInfo.java b/src/proguard/optimize/info/ClassOptimizationInfo.java index e440eef..99b6e7b 100644 --- a/src/proguard/optimize/info/ClassOptimizationInfo.java +++ b/src/proguard/optimize/info/ClassOptimizationInfo.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 @@ -34,7 +34,6 @@ public class ClassOptimizationInfo private boolean isInstanceofed = false; private boolean isDotClassed = false; private boolean isCaught = false; - private boolean containsStaticInitializer = false; private boolean containsPackageVisibleMembers = false; private boolean invokesPackageVisibleMembers = false; private Clazz targetClass; @@ -88,18 +87,6 @@ public class ClassOptimizationInfo } - public void setContainsStaticInitializer() - { - containsStaticInitializer = true; - } - - - public boolean containsStaticInitializer() - { - return containsStaticInitializer; - } - - public void setContainsPackageVisibleMembers() { containsPackageVisibleMembers = true; @@ -142,7 +129,6 @@ public class ClassOptimizationInfo this.isInstanceofed |= other.isInstanceofed; this.isDotClassed |= other.isDotClassed; this.isCaught |= other.isCaught; - this.containsStaticInitializer |= other.containsStaticInitializer; this.containsPackageVisibleMembers |= other.containsPackageVisibleMembers; this.invokesPackageVisibleMembers |= other.invokesPackageVisibleMembers; } diff --git a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java b/src/proguard/optimize/info/ClassOptimizationInfoSetter.java index bc58f2d..9cb167c 100644 --- a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java +++ b/src/proguard/optimize/info/ClassOptimizationInfoSetter.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 diff --git a/src/proguard/optimize/info/DotClassFilter.java b/src/proguard/optimize/info/DotClassFilter.java index c55925c..8cbe7f0 100644 --- a/src/proguard/optimize/info/DotClassFilter.java +++ b/src/proguard/optimize/info/DotClassFilter.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 diff --git a/src/proguard/optimize/info/DotClassMarker.java b/src/proguard/optimize/info/DotClassMarker.java index 2819441..b5f12a7 100644 --- a/src/proguard/optimize/info/DotClassMarker.java +++ b/src/proguard/optimize/info/DotClassMarker.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 diff --git a/src/proguard/optimize/info/ExceptionInstructionChecker.java b/src/proguard/optimize/info/ExceptionInstructionChecker.java index 40287f3..2792d90 100644 --- a/src/proguard/optimize/info/ExceptionInstructionChecker.java +++ b/src/proguard/optimize/info/ExceptionInstructionChecker.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 @@ -67,39 +67,34 @@ implements InstructionVisitor byte opcode = simpleInstruction.opcode; // Check for instructions that may throw exceptions. - // Note that monitorexit can not sensibly throw exceptions, except the - // broken and deprecated asynchronous ThreadDeath. Removing the - // artificial infinite looping exception blocks that recent compilers - // add does not strictly follow the JVM specs, but it does have the - // additional benefit of avoiding a bug in the JVM in JDK 1.1. - switch (opcode) + if (opcode == InstructionConstants.OP_IDIV || + opcode == InstructionConstants.OP_LDIV || + opcode == InstructionConstants.OP_IREM || + opcode == InstructionConstants.OP_LREM || + opcode == InstructionConstants.OP_IALOAD || + opcode == InstructionConstants.OP_LALOAD || + opcode == InstructionConstants.OP_FALOAD || + opcode == InstructionConstants.OP_DALOAD || + opcode == InstructionConstants.OP_AALOAD || + opcode == InstructionConstants.OP_BALOAD || + opcode == InstructionConstants.OP_CALOAD || + opcode == InstructionConstants.OP_SALOAD || + opcode == InstructionConstants.OP_IASTORE || + opcode == InstructionConstants.OP_LASTORE || + opcode == InstructionConstants.OP_FASTORE || + opcode == InstructionConstants.OP_DASTORE || + opcode == InstructionConstants.OP_AASTORE || + opcode == InstructionConstants.OP_BASTORE || + opcode == InstructionConstants.OP_CASTORE || + opcode == InstructionConstants.OP_SASTORE || + opcode == InstructionConstants.OP_NEWARRAY || + opcode == InstructionConstants.OP_ARRAYLENGTH || + opcode == InstructionConstants.OP_ATHROW || + opcode == InstructionConstants.OP_MONITORENTER || + opcode == InstructionConstants.OP_MONITOREXIT) { - case InstructionConstants.OP_IDIV: - case InstructionConstants.OP_LDIV: - case InstructionConstants.OP_IREM: - case InstructionConstants.OP_LREM: - case InstructionConstants.OP_IALOAD: - case InstructionConstants.OP_LALOAD: - case InstructionConstants.OP_FALOAD: - case InstructionConstants.OP_DALOAD: - case InstructionConstants.OP_AALOAD: - case InstructionConstants.OP_BALOAD: - case InstructionConstants.OP_CALOAD: - case InstructionConstants.OP_SALOAD: - case InstructionConstants.OP_IASTORE: - case InstructionConstants.OP_LASTORE: - case InstructionConstants.OP_FASTORE: - case InstructionConstants.OP_DASTORE: - case InstructionConstants.OP_AASTORE: - case InstructionConstants.OP_BASTORE: - case InstructionConstants.OP_CASTORE: - case InstructionConstants.OP_SASTORE: - case InstructionConstants.OP_NEWARRAY: - case InstructionConstants.OP_ARRAYLENGTH: - case InstructionConstants.OP_ATHROW: - case InstructionConstants.OP_MONITORENTER: - // These instructions may throw exceptions. - mayThrowExceptions = true; + // These instructions may throw exceptions. + mayThrowExceptions = true; } } @@ -110,32 +105,31 @@ implements InstructionVisitor byte opcode = constantInstruction.opcode; // Check for instructions that may throw exceptions. - switch (opcode) + if (opcode == InstructionConstants.OP_GETSTATIC || + opcode == InstructionConstants.OP_PUTSTATIC || + opcode == InstructionConstants.OP_GETFIELD || + opcode == InstructionConstants.OP_PUTFIELD || + opcode == InstructionConstants.OP_INVOKEVIRTUAL || + opcode == InstructionConstants.OP_INVOKESPECIAL || + opcode == InstructionConstants.OP_INVOKESTATIC || + opcode == InstructionConstants.OP_INVOKEINTERFACE || + opcode == InstructionConstants.OP_NEW || + opcode == InstructionConstants.OP_ANEWARRAY || + opcode == InstructionConstants.OP_CHECKCAST || + opcode == InstructionConstants.OP_MULTIANEWARRAY) { - case InstructionConstants.OP_GETSTATIC: - case InstructionConstants.OP_PUTSTATIC: - case InstructionConstants.OP_GETFIELD: - case InstructionConstants.OP_PUTFIELD: - case InstructionConstants.OP_INVOKEVIRTUAL: - case InstructionConstants.OP_INVOKESPECIAL: - case InstructionConstants.OP_INVOKESTATIC: - case InstructionConstants.OP_INVOKEINTERFACE: - case InstructionConstants.OP_INVOKEDYNAMIC: - case InstructionConstants.OP_NEW: - case InstructionConstants.OP_ANEWARRAY: - case InstructionConstants.OP_CHECKCAST: - case InstructionConstants.OP_INSTANCEOF: - case InstructionConstants.OP_MULTIANEWARRAY: - // These instructions may throw exceptions. - mayThrowExceptions = true; + // These instructions may throw exceptions. + mayThrowExceptions = true; } - -// case InstructionConstants.OP_INVOKEVIRTUAL: -// case InstructionConstants.OP_INVOKESPECIAL: -// case InstructionConstants.OP_INVOKESTATIC: -// case InstructionConstants.OP_INVOKEINTERFACE: +// else +// if (opcode == InstructionConstants.OP_INVOKEVIRTUAL || +// opcode == InstructionConstants.OP_INVOKESPECIAL || +// opcode == InstructionConstants.OP_INVOKESTATIC || +// opcode == InstructionConstants.OP_INVOKEINTERFACE) +// { // // Check if the invoking the method may throw an exception. // clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); +// } } diff --git a/src/proguard/optimize/info/FieldOptimizationInfo.java b/src/proguard/optimize/info/FieldOptimizationInfo.java index 6797a14..7a2d068 100644 --- a/src/proguard/optimize/info/FieldOptimizationInfo.java +++ b/src/proguard/optimize/info/FieldOptimizationInfo.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 @@ -21,11 +21,8 @@ package proguard.optimize.info; import proguard.classfile.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.attribute.*; -import proguard.classfile.util.*; +import proguard.classfile.util.MethodLinker; import proguard.evaluation.value.*; -import proguard.evaluation.ConstantValueFactory; /** * This class stores some optimization information that can be attached to @@ -34,11 +31,8 @@ import proguard.evaluation.ConstantValueFactory; * @author Eric Lafortune */ public class FieldOptimizationInfo -extends SimplifiedVisitor -implements AttributeVisitor { - private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory(); - private static final ConstantValueFactory CONSTANT_VALUE_FACTORY = new ConstantValueFactory(VALUE_FACTORY); + private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory(); private boolean isWritten; private boolean isRead; @@ -49,33 +43,9 @@ implements AttributeVisitor public FieldOptimizationInfo(Clazz clazz, Field field) { - int accessFlags = field.getAccessFlags(); - isWritten = - isRead = (accessFlags & ClassConstants.INTERNAL_ACC_VOLATILE) != 0; - - if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0) - { - // See if we can initialize the static field with a constant value. - field.accept(clazz, new AllAttributeVisitor(this)); - } - - if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 && - value == null) - { - // Otherwise initialize the non-final field with the default value. - value = initialValue(field.getDescriptor(clazz)); - } - } - - - public FieldOptimizationInfo(FieldOptimizationInfo FieldOptimizationInfo) - { - this.isWritten = FieldOptimizationInfo.isWritten; - this.isRead = FieldOptimizationInfo.isRead; - this.canBeMadePrivate = FieldOptimizationInfo.canBeMadePrivate; - this.referencedClass = FieldOptimizationInfo.referencedClass; - this.value = FieldOptimizationInfo.value; + isRead = (field.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0; + value = initialValue(field.getDescriptor(clazz)); } @@ -143,18 +113,6 @@ implements AttributeVisitor } - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) - { - // Retrieve the initial static field value. - value = CONSTANT_VALUE_FACTORY.constantValue(clazz, constantValueAttribute.u2constantValueIndex); - } - - // Small utility methods. private Value initialValue(String type) @@ -189,13 +147,13 @@ implements AttributeVisitor public static void setFieldOptimizationInfo(Clazz clazz, Field field) { - field.setVisitorInfo(new FieldOptimizationInfo(clazz, field)); + MethodLinker.lastMember(field).setVisitorInfo(new FieldOptimizationInfo(clazz, field)); } public static FieldOptimizationInfo getFieldOptimizationInfo(Field field) { - Object visitorInfo = field.getVisitorInfo(); + Object visitorInfo = MethodLinker.lastMember(field).getVisitorInfo(); return visitorInfo instanceof FieldOptimizationInfo ? (FieldOptimizationInfo)visitorInfo : diff --git a/src/proguard/optimize/info/InstanceofClassFilter.java b/src/proguard/optimize/info/InstanceofClassFilter.java index 955fe9e..35e1d77 100644 --- a/src/proguard/optimize/info/InstanceofClassFilter.java +++ b/src/proguard/optimize/info/InstanceofClassFilter.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 diff --git a/src/proguard/optimize/info/InstanceofClassMarker.java b/src/proguard/optimize/info/InstanceofClassMarker.java index 6d2f8aa..c60e1f8 100644 --- a/src/proguard/optimize/info/InstanceofClassMarker.java +++ b/src/proguard/optimize/info/InstanceofClassMarker.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 diff --git a/src/proguard/optimize/info/InstantiationClassFilter.java b/src/proguard/optimize/info/InstantiationClassFilter.java index e67e0b5..a24e617 100644 --- a/src/proguard/optimize/info/InstantiationClassFilter.java +++ b/src/proguard/optimize/info/InstantiationClassFilter.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 diff --git a/src/proguard/optimize/info/InstantiationClassMarker.java b/src/proguard/optimize/info/InstantiationClassMarker.java index dc623c2..124c23b 100644 --- a/src/proguard/optimize/info/InstantiationClassMarker.java +++ b/src/proguard/optimize/info/InstantiationClassMarker.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 diff --git a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java b/src/proguard/optimize/info/MemberOptimizationInfoSetter.java index d222d81..a170a8e 100644 --- a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java +++ b/src/proguard/optimize/info/MemberOptimizationInfoSetter.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 @@ -38,22 +38,22 @@ implements MemberVisitor { // Implementations for MemberVisitor. - public void visitProgramField(ProgramClass programClass, ProgramField programField) + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { - if (!KeepMarker.isKept(programField)) + if (!KeepMarker.isKept(programMethod)) { - FieldOptimizationInfo.setFieldOptimizationInfo(programClass, - programField); + MethodOptimizationInfo.setMethodOptimizationInfo(programClass, + programMethod); } } - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + public void visitProgramField(ProgramClass programClass, ProgramField programField) { - if (!KeepMarker.isKept(programMethod)) + if (!KeepMarker.isKept(programField)) { - MethodOptimizationInfo.setMethodOptimizationInfo(programClass, - programMethod); + FieldOptimizationInfo.setFieldOptimizationInfo(programClass, + programField); } } } diff --git a/src/proguard/optimize/info/MethodInvocationMarker.java b/src/proguard/optimize/info/MethodInvocationMarker.java index 9d573b7..2528c94 100644 --- a/src/proguard/optimize/info/MethodInvocationMarker.java +++ b/src/proguard/optimize/info/MethodInvocationMarker.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 diff --git a/src/proguard/optimize/info/MethodOptimizationInfo.java b/src/proguard/optimize/info/MethodOptimizationInfo.java index dd76f97..d3b1bde 100644 --- a/src/proguard/optimize/info/MethodOptimizationInfo.java +++ b/src/proguard/optimize/info/MethodOptimizationInfo.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 @@ -204,7 +204,7 @@ public class MethodOptimizationInfo public void setParameterUsed(int parameterIndex) { - usedParameters |= 1L << parameterIndex; + usedParameters |= 1 << parameterIndex; } @@ -216,7 +216,7 @@ public class MethodOptimizationInfo public boolean isParameterUsed(int parameterIndex) { - return parameterIndex >= 64 || (usedParameters & (1L << parameterIndex)) != 0; + return parameterIndex >= 64 || (usedParameters & (1 << parameterIndex)) != 0; } diff --git a/src/proguard/optimize/info/NoSideEffectMethodMarker.java b/src/proguard/optimize/info/NoSideEffectMethodMarker.java index 2e0516b..5c78408 100644 --- a/src/proguard/optimize/info/NoSideEffectMethodMarker.java +++ b/src/proguard/optimize/info/NoSideEffectMethodMarker.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 diff --git a/src/proguard/optimize/info/NonPrivateMemberMarker.java b/src/proguard/optimize/info/NonPrivateMemberMarker.java index 23e33a9..d451643 100644 --- a/src/proguard/optimize/info/NonPrivateMemberMarker.java +++ b/src/proguard/optimize/info/NonPrivateMemberMarker.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 @@ -77,9 +77,15 @@ implements ClassVisitor, public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { - // The referenced class member, if any, can never be made private, - // even if it's in the same class. - stringConstant.referencedMemberAccept(this); + Clazz referencedClass = stringConstant.referencedClass; + + // Is it refering to another class or class member? + if (referencedClass != null && + !referencedClass.equals(clazz)) + { + // The referenced class member, if any, can never be made private. + stringConstant.referencedMemberAccept(this); + } } @@ -87,7 +93,7 @@ implements ClassVisitor, { Clazz referencedClass = refConstant.referencedClass; - // Is it referring to a class member in another class? + // Is it refering to a class member in another class? // The class member might be in another class, or // it may be referenced through another class. if (referencedClass != null && diff --git a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java index 85ff4b9..d40bc6b 100644 --- a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java +++ b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.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 @@ -22,36 +22,18 @@ package proguard.optimize.info; import proguard.classfile.*; import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.*; +import proguard.classfile.visitor.MemberVisitor; /** - * This ClassVisitor marks all classes that contain package visible members. + * This MemberVisitor marks all classes that contain visited package visible + * members. * * @author Eric Lafortune */ public class PackageVisibleMemberContainingClassMarker extends SimplifiedVisitor -implements ClassVisitor, - MemberVisitor +implements MemberVisitor { - // Implementations for ClassVisitor. - - public void visitAnyClass(Clazz clazz) - { - // Check the class itself. - if ((clazz.getAccessFlags() & ClassConstants.INTERNAL_ACC_PUBLIC) == 0) - { - setPackageVisibleMembers(clazz); - } - else - { - // Check the members. - clazz.fieldsAccept(this); - clazz.methodsAccept(this); - } - } - - // Implementations for MemberVisitor. public void visitAnyMember(Clazz clazz, Member member) diff --git a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java index 42cc14f..9ec8ec6 100644 --- a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java +++ b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.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 @@ -24,87 +24,39 @@ import proguard.classfile.*; import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.constant.*; import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.*; /** - * This ConstantVisitor marks all classes that refer to package visible classes - * or class members. + * This ConstantVisitor marks all classes that invoke package visible members + * in other classes. * * @author Eric Lafortune */ public class PackageVisibleMemberInvokingClassMarker extends SimplifiedVisitor -implements ConstantVisitor, - ClassVisitor, - MemberVisitor +implements ConstantVisitor { - private Clazz referencingClass; - - // Implementations for ConstantVisitor. public void visitAnyConstant(Clazz clazz, Constant constant) {} - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) - { - // Check the referenced class and class member, if any. - if (stringConstant.referencedClass != clazz) - { - referencingClass = clazz; - - stringConstant.referencedClassAccept(this); - stringConstant.referencedMemberAccept(this); - } - } - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { - // Check the referenced class and class member. - if (refConstant.referencedClass != clazz) - { - referencingClass = clazz; - - refConstant.referencedClassAccept(this); - refConstant.referencedMemberAccept(this); - } - } - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - // Check the referenced class. - if (classConstant.referencedClass != clazz) - { - referencingClass = clazz; - - classConstant.referencedClassAccept(this); - } - } - - - // Implementations for ClassVisitor. - - public void visitAnyClass(Clazz clazz) - { - if ((clazz.getAccessFlags() & + Clazz referencedClass = refConstant.referencedClass; + if (referencedClass != null && + (referencedClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_PUBLIC) == 0) { - setInvokesPackageVisibleMembers(referencingClass); + setInvokesPackageVisibleMembers(clazz); } - } - - // Implementations for MemberVisitor. - - public void visitAnyMember(Clazz clazz, Member member) - { - if ((member.getAccessFlags() & + Member referencedMember = refConstant.referencedMember; + if (referencedMember != null && + (referencedMember.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PUBLIC | ClassConstants.INTERNAL_ACC_PRIVATE)) == 0) { - setInvokesPackageVisibleMembers(referencingClass); + setInvokesPackageVisibleMembers(clazz); } } diff --git a/src/proguard/optimize/info/ParameterUsageMarker.java b/src/proguard/optimize/info/ParameterUsageMarker.java index abae946..15ce88a 100644 --- a/src/proguard/optimize/info/ParameterUsageMarker.java +++ b/src/proguard/optimize/info/ParameterUsageMarker.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 @@ -21,14 +21,14 @@ package proguard.optimize.info; import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.attribute.*; import proguard.classfile.util.*; import proguard.classfile.visitor.MemberVisitor; -import proguard.evaluation.value.Value; import proguard.optimize.evaluation.PartialEvaluator; +import proguard.evaluation.value.*; /** * This MemberVisitor counts the parameters and marks the used parameters diff --git a/src/proguard/optimize/info/ReadWriteFieldMarker.java b/src/proguard/optimize/info/ReadWriteFieldMarker.java index 236cb17..57d8561 100644 --- a/src/proguard/optimize/info/ReadWriteFieldMarker.java +++ b/src/proguard/optimize/info/ReadWriteFieldMarker.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 diff --git a/src/proguard/optimize/info/SideEffectInstructionChecker.java b/src/proguard/optimize/info/SideEffectInstructionChecker.java index 1444e5a..8be9dc1 100644 --- a/src/proguard/optimize/info/SideEffectInstructionChecker.java +++ b/src/proguard/optimize/info/SideEffectInstructionChecker.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 @@ -29,14 +29,11 @@ import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.*; -import java.util.*; - /** * This class can tell whether an instruction has any side effects. Return * instructions can be included or not. * * @see ReadWriteFieldMarker - * @see StaticInitializerContainingClassMarker * @see NoSideEffectMethodMarker * @see SideEffectMethodMarker * @author Eric Lafortune @@ -50,7 +47,6 @@ implements InstructionVisitor, private final boolean includeReturnInstructions; // A return value for the visitor methods. - private Clazz referencingClass; private boolean hasSideEffects; @@ -64,7 +60,7 @@ implements InstructionVisitor, { hasSideEffects = false; - instruction.accept(clazz, method, codeAttribute, offset, this); + instruction.accept(clazz, method, codeAttribute, offset, this); return hasSideEffects; } @@ -122,16 +118,14 @@ implements InstructionVisitor, public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) { byte opcode = constantInstruction.opcode; + // Check for instructions that might cause side effects. - if (opcode == InstructionConstants.OP_GETSTATIC || - opcode == InstructionConstants.OP_PUTSTATIC || - opcode == InstructionConstants.OP_GETFIELD || - opcode == InstructionConstants.OP_PUTFIELD || - opcode == InstructionConstants.OP_INVOKEVIRTUAL || - opcode == InstructionConstants.OP_INVOKESPECIAL || - opcode == InstructionConstants.OP_INVOKESTATIC || - opcode == InstructionConstants.OP_INVOKEINTERFACE || - opcode == InstructionConstants.OP_INVOKEDYNAMIC) + if (opcode == InstructionConstants.OP_PUTSTATIC || + opcode == InstructionConstants.OP_PUTFIELD || + opcode == InstructionConstants.OP_INVOKEVIRTUAL || + opcode == InstructionConstants.OP_INVOKESPECIAL || + opcode == InstructionConstants.OP_INVOKESTATIC || + opcode == InstructionConstants.OP_INVOKEINTERFACE) { // Check if the field is write-only or volatile, or if the invoked // method is causing any side effects. @@ -156,36 +150,48 @@ implements InstructionVisitor, // Implementations for ConstantVisitor. - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - // We'll have to assume invoking an unknown method has side effects. - hasSideEffects = true; - } - - public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { - // Pass the referencing class. - referencingClass = clazz; - // We'll have to assume accessing an unknown field has side effects. hasSideEffects = true; - // Check the referenced field, if known. + // Check the referenced field. fieldrefConstant.referencedMemberAccept(this); } public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) { - // Pass the referencing class. - referencingClass = clazz; + Member referencedMember = refConstant.referencedMember; - // We'll have to assume invoking an unknown method has side effects. - hasSideEffects = true; - - // Check the referenced method, if known. - refConstant.referencedMemberAccept(this); + // Do we have a reference to the method? + if (referencedMember == null) + { + // We'll have to assume invoking the unknown method has side effects. + hasSideEffects = true; + } + else + { + // First check the referenced method itself. + refConstant.referencedMemberAccept(this); + + // If the result isn't conclusive, check down the hierarchy. + if (!hasSideEffects) + { + Clazz referencedClass = refConstant.referencedClass; + Method referencedMethod = (Method)referencedMember; + + // Check all other implementations of the method down the class + // hierarchy. + if ((referencedMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_PRIVATE) == 0) + { + clazz.hierarchyAccept(false, false, false, true, + new NamedMethodVisitor(referencedMethod.getName(referencedClass), + referencedMethod.getDescriptor(referencedClass), + this)); + } + } + } } @@ -193,24 +199,14 @@ implements InstructionVisitor, public void visitProgramField(ProgramClass programClass, ProgramField programField) { - hasSideEffects = - (ReadWriteFieldMarker.isRead(programField) && - ReadWriteFieldMarker.isWritten(programField)) || - ((programField.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0) || - (!programClass.equals(referencingClass) && - !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass))); + hasSideEffects = ReadWriteFieldMarker.isRead(programField); } public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { - // Note that side effects already include synchronization of some - // implementation of the method. - hasSideEffects = - !NoSideEffectMethodMarker.hasNoSideEffects(programMethod) && - (SideEffectMethodMarker.hasSideEffects(programMethod) || - (!programClass.equals(referencingClass) && - !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass)))); + hasSideEffects = hasSideEffects || + SideEffectMethodMarker.hasSideEffects(programMethod); } @@ -222,24 +218,7 @@ implements InstructionVisitor, public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) { - hasSideEffects = - !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod); - } - - - /** - * Returns the set of superclasses and interfaces that are initialized. - */ - private Set initializedSuperClasses(Clazz clazz) - { - Set set = new HashSet(); - - // Visit all superclasses and interfaces, collecting the ones that have - // static initializers. - clazz.hierarchyAccept(true, true, true, false, - new StaticInitializerContainingClassFilter( - new ClassCollector(set))); - - return set; + hasSideEffects = hasSideEffects || + !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod); } } diff --git a/src/proguard/optimize/info/SideEffectMethodMarker.java b/src/proguard/optimize/info/SideEffectMethodMarker.java index d73179e..25fda72 100644 --- a/src/proguard/optimize/info/SideEffectMethodMarker.java +++ b/src/proguard/optimize/info/SideEffectMethodMarker.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 diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java b/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java deleted file mode 100644 index 197668d..0000000 --- a/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * 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 - * 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.info; - -import proguard.classfile.*; -import proguard.classfile.visitor.ClassVisitor; - -/** - * This ClassVisitor delegates all its method calls to another ClassVisitor, - * but only for Clazz objects that are instantiated. - * - * @author Eric Lafortune - */ -public class StaticInitializerContainingClassFilter -implements ClassVisitor -{ - private final ClassVisitor classVisitor; - - - public StaticInitializerContainingClassFilter(ClassVisitor classVisitor) - { - this.classVisitor = classVisitor; - } - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - if (StaticInitializerContainingClassMarker.containsStaticInitializer(programClass)) - { - classVisitor.visitProgramClass(programClass); - } - } - - - public void visitLibraryClass(LibraryClass libraryClass) - { - if (StaticInitializerContainingClassMarker.containsStaticInitializer(libraryClass)) - { - classVisitor.visitLibraryClass(libraryClass); - } - } -}
\ No newline at end of file diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java b/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java deleted file mode 100644 index a121250..0000000 --- a/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * 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 - * 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.info; - -import proguard.classfile.*; -import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.*; - -/** - * This ClassVisitor marks all classes that contain static initializers. - * - * @author Eric Lafortune - */ -public class StaticInitializerContainingClassMarker -extends SimplifiedVisitor -implements ClassVisitor -{ - // Implementations for ClassVisitor. - - public void visitAnyClass(Clazz clazz) - { - if (clazz.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT, - ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) != null) - { - setStaticInitializer(clazz); - } - } - - - // Small utility methods. - - private static void setStaticInitializer(Clazz clazz) - { - ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); - if (info != null) - { - info.setContainsStaticInitializer(); - } - } - - - public static boolean containsStaticInitializer(Clazz clazz) - { - ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); - return info == null || info.containsStaticInitializer(); - } -}
\ No newline at end of file diff --git a/src/proguard/optimize/info/SuperInvocationMarker.java b/src/proguard/optimize/info/SuperInvocationMarker.java index 07e33bb..6f3d3bd 100644 --- a/src/proguard/optimize/info/SuperInvocationMarker.java +++ b/src/proguard/optimize/info/SuperInvocationMarker.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 diff --git a/src/proguard/optimize/info/VariableUsageMarker.java b/src/proguard/optimize/info/VariableUsageMarker.java index a1c6a9a..660c4ba 100644 --- a/src/proguard/optimize/info/VariableUsageMarker.java +++ b/src/proguard/optimize/info/VariableUsageMarker.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 @@ -27,8 +27,6 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import java.util.Arrays; - /** * This AttributeVisitor marks the local variables that are used in the code * attributes that it visits. @@ -64,13 +62,14 @@ implements AttributeVisitor, // Try to reuse the previous array. if (variableUsed.length < maxLocals) { - // Create a new array. variableUsed = new boolean[maxLocals]; } else { - // Reset the array. - Arrays.fill(variableUsed, 0, maxLocals, false); + for (int index = 0; index < maxLocals; index++) + { + variableUsed[index] = false; + } } codeAttribute.instructionsAccept(clazz, method, this); diff --git a/src/proguard/optimize/peephole/BranchTargetFinder.java b/src/proguard/optimize/peephole/BranchTargetFinder.java index 7e5a11f..8f650bb 100644 --- a/src/proguard/optimize/peephole/BranchTargetFinder.java +++ b/src/proguard/optimize/peephole/BranchTargetFinder.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 @@ -29,8 +29,6 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import java.util.Arrays; - /** * This AttributeVisitor finds all instruction offsets, branch targets, and * exception targets in the CodeAttribute objects that it visits. @@ -314,19 +312,25 @@ implements AttributeVisitor, initializationOffsets = new int[codeLength]; // Reset the arrays. - Arrays.fill(subroutineStarts, 0, codeLength, NONE); - Arrays.fill(subroutineEnds, 0, codeLength, NONE); - Arrays.fill(creationOffsets, 0, codeLength, NONE); - Arrays.fill(initializationOffsets, 0, codeLength, NONE); + for (int index = 0; index < codeLength; index++) + { + subroutineStarts[index] = NONE; + subroutineEnds[index] = NONE; + creationOffsets[index] = NONE; + initializationOffsets[index] = NONE; + } } else { // Reset the arrays. - Arrays.fill(instructionMarks, 0, codeLength, (short)0); - Arrays.fill(subroutineStarts, 0, codeLength, NONE); - Arrays.fill(subroutineEnds, 0, codeLength, NONE); - Arrays.fill(creationOffsets, 0, codeLength, NONE); - Arrays.fill(initializationOffsets, 0, codeLength, NONE); + for (int index = 0; index < codeLength; index++) + { + instructionMarks[index] = 0; + subroutineStarts[index] = NONE; + subroutineEnds[index] = NONE; + creationOffsets[index] = NONE; + initializationOffsets[index] = NONE; + } instructionMarks[codeLength] = 0; } diff --git a/src/proguard/optimize/peephole/ClassFinalizer.java b/src/proguard/optimize/peephole/ClassFinalizer.java index 063f254..b5e54f8 100644 --- a/src/proguard/optimize/peephole/ClassFinalizer.java +++ b/src/proguard/optimize/peephole/ClassFinalizer.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 diff --git a/src/proguard/optimize/peephole/ClassMerger.java b/src/proguard/optimize/peephole/ClassMerger.java index 4971cab..1e1a950 100644 --- a/src/proguard/optimize/peephole/ClassMerger.java +++ b/src/proguard/optimize/peephole/ClassMerger.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 @@ -21,7 +21,6 @@ package proguard.optimize.peephole; import proguard.classfile.*; -import proguard.classfile.constant.ClassConstant; import proguard.classfile.constant.visitor.*; import proguard.classfile.editor.*; import proguard.classfile.util.*; @@ -60,8 +59,6 @@ implements ClassVisitor, private final boolean mergeInterfacesAggressively; private final ClassVisitor extraClassVisitor; - private final MemberVisitor fieldOptimizationInfoCopier = new FieldOptimizationInfoCopier(); - /** * Creates a new ClassMerger that will merge classes into the given target @@ -154,7 +151,7 @@ implements ClassVisitor, // infinite recursion. (programClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_ANNOTATTION) == 0 && - // Only merge classes if we can change the access permissions, or + // Only merge classes if we can change the access permissioms, or // if they are in the same package, or // if they are public and don't contain or invoke package visible // class members. @@ -238,12 +235,11 @@ implements ClassVisitor, targetClass.u2accessFlags = ((targetAccessFlags & sourceAccessFlags) & - (ClassConstants.INTERNAL_ACC_INTERFACE | + (ClassConstants.INTERNAL_ACC_INTERFACE | ClassConstants.INTERNAL_ACC_ABSTRACT)) | ((targetAccessFlags | sourceAccessFlags) & - (ClassConstants.INTERNAL_ACC_PUBLIC | - ClassConstants.INTERNAL_ACC_SUPER | + (ClassConstants.INTERNAL_ACC_PUBLIC | ClassConstants.INTERNAL_ACC_ANNOTATTION | ClassConstants.INTERNAL_ACC_ENUM)); @@ -264,7 +260,7 @@ implements ClassVisitor, // Copy over the class members. MemberAdder memberAdder = - new MemberAdder(targetClass, fieldOptimizationInfoCopier); + new MemberAdder(targetClass); programClass.fieldsAccept(memberAdder); programClass.methodsAccept(memberAdder); @@ -340,8 +336,10 @@ implements ClassVisitor, // Visit all superclasses and interfaces, collecting the ones that have // static initializers. clazz.hierarchyAccept(true, true, true, false, - new StaticInitializerContainingClassFilter( - new ClassCollector(set))); + new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_CLINIT, + ClassConstants.INTERNAL_METHOD_TYPE_INIT, + new MemberToClassVisitor( + new ClassCollector(set)))); return set; } @@ -370,19 +368,12 @@ implements ClassVisitor, */ private Set caughtSuperClasses(Clazz clazz) { - // Don't bother if this isn't an exception at all. - if (!clazz.extends_(ClassConstants.INTERNAL_NAME_JAVA_LANG_THROWABLE)) - { - return Collections.EMPTY_SET; - } - - // Visit all superclasses, collecting the ones that are caught - // (plus java.lang.Object, in the current implementation). Set set = new HashSet(); + // Visit all superclasses, collecting the ones that are caught. clazz.hierarchyAccept(true, true, false, false, new CaughtClassFilter( - new ClassCollector(set))); + new ClassCollector(set))); return set; } @@ -547,30 +538,4 @@ implements ClassVisitor, targetClass = clazz; } } - - - /** - * This MemberVisitor copies field optimization info from copied fields. - */ - private static class FieldOptimizationInfoCopier - extends SimplifiedVisitor - implements MemberVisitor - { - public void visitProgramField(ProgramClass programClass, ProgramField programField) - { - // Copy the optimization info from the field that was just copied. - ProgramField copiedField = (ProgramField)programField.getVisitorInfo(); - Object info = copiedField.getVisitorInfo(); - - programField.setVisitorInfo(info instanceof FieldOptimizationInfo ? - new FieldOptimizationInfo((FieldOptimizationInfo)info) : - info); - } - - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - // Linked methods share their optimization info. - } - } }
\ No newline at end of file diff --git a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java index 0dd93b1..4833275 100644 --- a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java +++ b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.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 diff --git a/src/proguard/optimize/peephole/GotoGotoReplacer.java b/src/proguard/optimize/peephole/GotoGotoReplacer.java index d05d7b6..7d7e66c 100644 --- a/src/proguard/optimize/peephole/GotoGotoReplacer.java +++ b/src/proguard/optimize/peephole/GotoGotoReplacer.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 @@ -84,9 +84,8 @@ implements InstructionVisitor int branchOffset = branchInstruction.branchOffset; int targetOffset = offset + branchOffset; - if (branchOffset != 0 && - branchOffset != branchInstruction.length(offset) && - !codeAttributeEditor.isModified(offset) && + if (branchOffset != branchInstruction.length(offset) && + !codeAttributeEditor.isModified(offset) && !codeAttributeEditor.isModified(targetOffset)) { Instruction targetInstruction = diff --git a/src/proguard/optimize/peephole/GotoReturnReplacer.java b/src/proguard/optimize/peephole/GotoReturnReplacer.java index cafda92..5c3eb77 100644 --- a/src/proguard/optimize/peephole/GotoReturnReplacer.java +++ b/src/proguard/optimize/peephole/GotoReturnReplacer.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 diff --git a/src/proguard/optimize/peephole/HorizontalClassMerger.java b/src/proguard/optimize/peephole/HorizontalClassMerger.java index d12c2c0..a37b9a5 100644 --- a/src/proguard/optimize/peephole/HorizontalClassMerger.java +++ b/src/proguard/optimize/peephole/HorizontalClassMerger.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 diff --git a/src/proguard/optimize/peephole/InstructionSequenceConstants.java b/src/proguard/optimize/peephole/InstructionSequenceConstants.java index eb24061..b33204b 100644 --- a/src/proguard/optimize/peephole/InstructionSequenceConstants.java +++ b/src/proguard/optimize/peephole/InstructionSequenceConstants.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 @@ -20,179 +20,81 @@ */ package proguard.optimize.peephole; -import proguard.classfile.*; import proguard.classfile.constant.*; import proguard.classfile.instruction.*; -import proguard.classfile.visitor.ClassPrinter; +import proguard.classfile.util.InstructionSequenceMatcher; /** * This class contains a set of instruction sequences and their suggested * replacements. * * @see InstructionSequencesReplacer - * @see InstructionSequenceReplacer * @author Eric Lafortune */ public class InstructionSequenceConstants { - private static final int X = InstructionSequenceReplacer.X; - private static final int Y = InstructionSequenceReplacer.Y; - private static final int Z = InstructionSequenceReplacer.Z; + public static final int X = InstructionSequenceMatcher.X; + public static final int Y = InstructionSequenceMatcher.Y; + public static final int Z = InstructionSequenceMatcher.Z; - private static final int A = InstructionSequenceReplacer.A; - private static final int B = InstructionSequenceReplacer.B; - private static final int C = InstructionSequenceReplacer.C; - private static final int D = InstructionSequenceReplacer.D; + public static final int A = InstructionSequenceMatcher.A; + public static final int B = InstructionSequenceMatcher.B; + public static final int C = InstructionSequenceMatcher.C; + public static final int D = InstructionSequenceMatcher.D; - private static final int STRING_A_LENGTH = InstructionSequenceReplacer.STRING_A_LENGTH; - private static final int BOOLEAN_A_STRING = InstructionSequenceReplacer.BOOLEAN_A_STRING; - private static final int CHAR_A_STRING = InstructionSequenceReplacer.CHAR_A_STRING; - private static final int INT_A_STRING = InstructionSequenceReplacer.INT_A_STRING; - private static final int LONG_A_STRING = InstructionSequenceReplacer.LONG_A_STRING; - private static final int FLOAT_A_STRING = InstructionSequenceReplacer.FLOAT_A_STRING; - private static final int DOUBLE_A_STRING = InstructionSequenceReplacer.DOUBLE_A_STRING; - private static final int STRING_A_STRING = InstructionSequenceReplacer.STRING_A_STRING; - private static final int BOOLEAN_B_STRING = InstructionSequenceReplacer.BOOLEAN_B_STRING; - private static final int CHAR_B_STRING = InstructionSequenceReplacer.CHAR_B_STRING; - private static final int INT_B_STRING = InstructionSequenceReplacer.INT_B_STRING; - private static final int LONG_B_STRING = InstructionSequenceReplacer.LONG_B_STRING; - private static final int FLOAT_B_STRING = InstructionSequenceReplacer.FLOAT_B_STRING; - private static final int DOUBLE_B_STRING = InstructionSequenceReplacer.DOUBLE_B_STRING; - private static final int STRING_B_STRING = InstructionSequenceReplacer.STRING_B_STRING; - private static final int I_32768 = 0; - private static final int I_65536 = 1; - private static final int I_16777216 = 2; + private static final int I_32768 = 0; + private static final int I_65536 = 1; + private static final int I_16777216 = 2; // private static final int I_0x000000ff - private static final int I_0x0000ff00 = 3; - private static final int I_0x00ff0000 = 4; - private static final int I_0xff000000 = 5; - private static final int I_0x0000ffff = 6; - private static final int I_0xffff0000 = 7; + private static final int I_0x0000ff00 = 3; + private static final int I_0x00ff0000 = 4; + private static final int I_0xff000000 = 5; + private static final int I_0x0000ffff = 6; + private static final int I_0xffff0000 = 7; - private static final int L_M1 = 8; - private static final int L_2 = 9; - private static final int L_4 = 10; - private static final int L_8 = 11; - private static final int L_16 = 12; - private static final int L_32 = 13; - private static final int L_64 = 14; - private static final int L_128 = 15; - private static final int L_256 = 16; - private static final int L_512 = 17; - private static final int L_1024 = 18; - private static final int L_2048 = 19; - private static final int L_4096 = 20; - private static final int L_8192 = 21; - private static final int L_16384 = 22; - private static final int L_32768 = 23; - private static final int L_65536 = 24; - private static final int L_16777216 = 25; - private static final int L_4294967296 = 26; + private static final int L_M1 = 8; + private static final int L_2 = 9; + private static final int L_4 = 10; + private static final int L_8 = 11; + private static final int L_16 = 12; + private static final int L_32 = 13; + private static final int L_64 = 14; + private static final int L_128 = 15; + private static final int L_256 = 16; + private static final int L_512 = 17; + private static final int L_1024 = 18; + private static final int L_2048 = 19; + private static final int L_4096 = 20; + private static final int L_8192 = 21; + private static final int L_16384 = 22; + private static final int L_32768 = 23; + private static final int L_65536 = 24; + private static final int L_16777216 = 25; + private static final int L_4294967296 = 26; - private static final int L_0x00000000ffffffff = 27; - private static final int L_0xffffffff00000000 = 28; + private static final int L_0x00000000ffffffff = 27; + private static final int L_0xffffffff00000000 = 28; - private static final int F_M1 = 29; + private static final int F_M1 = 29; - private static final int D_M1 = 30; + private static final int D_M1 = 30; - private static final int STRING_EMPTY = 31; + private static final int FIELD_I = 31; + private static final int FIELD_L = 32; + private static final int FIELD_F = 33; + private static final int FIELD_D = 34; - private static final int FIELD_I = 32; - private static final int FIELD_L = 33; - private static final int FIELD_F = 34; - private static final int FIELD_D = 35; + private static final int NAME_AND_TYPE_I = 35; + private static final int NAME_AND_TYPE_L = 36; + private static final int NAME_AND_TYPE_F = 37; + private static final int NAME_AND_TYPE_D = 38; - private static final int METHOD_STRING_EQUALS = 36; - private static final int METHOD_STRING_LENGTH = 37; - private static final int METHOD_STRINGBUFFER_INIT = 38; - private static final int METHOD_STRINGBUFFER_INIT_STRING = 39; - private static final int METHOD_STRINGBUFFER_APPEND_BOOLEAN = 40; - private static final int METHOD_STRINGBUFFER_APPEND_CHAR = 41; - private static final int METHOD_STRINGBUFFER_APPEND_INTEGER = 42; - private static final int METHOD_STRINGBUFFER_APPEND_LONG = 43; - private static final int METHOD_STRINGBUFFER_APPEND_FLOAT = 44; - private static final int METHOD_STRINGBUFFER_APPEND_DOUBLE = 45; - private static final int METHOD_STRINGBUFFER_APPEND_STRING = 46; - private static final int METHOD_STRINGBUFFER_LENGTH = 47; - private static final int METHOD_STRINGBUFFER_TOSTRING = 48; - private static final int METHOD_STRINGBUILDER_INIT = 49; - private static final int METHOD_STRINGBUILDER_INIT_STRING = 50; - private static final int METHOD_STRINGBUILDER_APPEND_BOOLEAN = 51; - private static final int METHOD_STRINGBUILDER_APPEND_CHAR = 52; - private static final int METHOD_STRINGBUILDER_APPEND_INTEGER = 53; - private static final int METHOD_STRINGBUILDER_APPEND_LONG = 54; - private static final int METHOD_STRINGBUILDER_APPEND_FLOAT = 55; - private static final int METHOD_STRINGBUILDER_APPEND_DOUBLE = 56; - private static final int METHOD_STRINGBUILDER_APPEND_STRING = 57; - private static final int METHOD_STRINGBUILDER_LENGTH = 58; - private static final int METHOD_STRINGBUILDER_TOSTRING = 59; - - private static final int CLASS_STRING = 60; - private static final int CLASS_STRINGBUFFER = 61; - private static final int CLASS_STRINGBUILDER = 62; - - private static final int NAME_AND_TYPE_I = 63; - private static final int NAME_AND_TYPE_L = 64; - private static final int NAME_AND_TYPE_F = 65; - private static final int NAME_AND_TYPE_D = 66; - - private static final int NAME_AND_TYPE_EQUALS = 67; - private static final int NAME_AND_TYPE_LENGTH = 68; - private static final int NAME_AND_TYPE_INIT = 69; - private static final int NAME_AND_TYPE_INIT_STRING = 70; - private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUFFER = 71; - private static final int NAME_AND_TYPE_APPEND_C_STRINGBUFFER = 72; - private static final int NAME_AND_TYPE_APPEND_I_STRINGBUFFER = 73; - private static final int NAME_AND_TYPE_APPEND_J_STRINGBUFFER = 74; - private static final int NAME_AND_TYPE_APPEND_F_STRINGBUFFER = 75; - private static final int NAME_AND_TYPE_APPEND_D_STRINGBUFFER = 76; - private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER = 77; - private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUILDER = 78; - private static final int NAME_AND_TYPE_APPEND_C_STRINGBUILDER = 79; - private static final int NAME_AND_TYPE_APPEND_I_STRINGBUILDER = 80; - private static final int NAME_AND_TYPE_APPEND_J_STRINGBUILDER = 81; - private static final int NAME_AND_TYPE_APPEND_F_STRINGBUILDER = 82; - private static final int NAME_AND_TYPE_APPEND_D_STRINGBUILDER = 83; - private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER = 84; - private static final int NAME_AND_TYPE_TOSTRING = 85; - - private static final int UTF8_EMPTY = 86; - private static final int UTF8_I = 87; - private static final int UTF8_L = 88; - private static final int UTF8_F = 89; - private static final int UTF8_D = 90; - private static final int UTF8_STRING = 91; - private static final int UTF8_STRINGBUFFER = 92; - private static final int UTF8_STRINGBUILDER = 93; - private static final int UTF8_EQUALS = 94; - private static final int UTF8_OBJECT_Z = 95; - private static final int UTF8_LENGTH = 96; - private static final int UTF8__I = 97; - private static final int UTF8_INIT = 98; - private static final int UTF8__VOID = 99; - private static final int UTF8_STRING_VOID = 100; - private static final int UTF8_TOSTRING = 101; - private static final int UTF8__STRING = 102; - private static final int UTF8_APPEND = 103; - private static final int UTF8_Z_STRINGBUFFER = 104; - private static final int UTF8_C_STRINGBUFFER = 105; - private static final int UTF8_I_STRINGBUFFER = 106; - private static final int UTF8_J_STRINGBUFFER = 107; - private static final int UTF8_F_STRINGBUFFER = 108; - private static final int UTF8_D_STRINGBUFFER = 109; - private static final int UTF8_STRING_STRINGBUFFER = 110; - private static final int UTF8_Z_STRINGBUILDER = 111; - private static final int UTF8_C_STRINGBUILDER = 112; - private static final int UTF8_I_STRINGBUILDER = 113; - private static final int UTF8_J_STRINGBUILDER = 114; - private static final int UTF8_F_STRINGBUILDER = 115; - private static final int UTF8_D_STRINGBUILDER = 116; - private static final int UTF8_STRING_STRINGBUILDER = 117; - - private static final int SENTINEL = 118; + private static final int TYPE_I = 39; + private static final int TYPE_L = 40; + private static final int TYPE_F = 41; + private static final int TYPE_D = 42; public static final Constant[] CONSTANTS = new Constant[] @@ -234,100 +136,23 @@ public class InstructionSequenceConstants new DoubleConstant(-1d), - new StringConstant(UTF8_EMPTY, null, null), - new FieldrefConstant(X, NAME_AND_TYPE_I, null, null), new FieldrefConstant(X, NAME_AND_TYPE_L, null, null), new FieldrefConstant(X, NAME_AND_TYPE_F, null, null), new FieldrefConstant(X, NAME_AND_TYPE_D, null, null), - new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_EQUALS, null, null), - new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_LENGTH, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT_STRING, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_Z_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_C_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_I_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_J_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_F_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_D_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_LENGTH, null, null), - new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_TOSTRING, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT_STRING, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_Z_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_C_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_I_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_J_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_F_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_D_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_LENGTH, null, null), - new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_TOSTRING, null, null), - - new ClassConstant(UTF8_STRING, null), - new ClassConstant(UTF8_STRINGBUFFER, null), - new ClassConstant(UTF8_STRINGBUILDER, null), - - new NameAndTypeConstant(Y, UTF8_I), - new NameAndTypeConstant(Y, UTF8_L), - new NameAndTypeConstant(Y, UTF8_F), - new NameAndTypeConstant(Y, UTF8_D), - new NameAndTypeConstant(UTF8_EQUALS, UTF8_OBJECT_Z), - new NameAndTypeConstant(UTF8_LENGTH, UTF8__I), - new NameAndTypeConstant(UTF8_INIT, UTF8__VOID), - new NameAndTypeConstant(UTF8_INIT, UTF8_STRING_VOID), - new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUFFER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUILDER), - new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUILDER), - new NameAndTypeConstant(UTF8_TOSTRING, UTF8__STRING), + new NameAndTypeConstant(Y, TYPE_I), + new NameAndTypeConstant(Y, TYPE_L), + new NameAndTypeConstant(Y, TYPE_F), + new NameAndTypeConstant(Y, TYPE_D), - new Utf8Constant(""), new Utf8Constant("I"), new Utf8Constant("J"), new Utf8Constant("F"), new Utf8Constant("D"), - new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING), - new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_EQUALS), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_EQUALS), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_LENGTH), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LENGTH), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_INIT), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INIT), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_VOID), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_TOSTRING), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_TOSTRING), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_APPEND), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER), - new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER), }; + public static final Instruction[][][] VARIABLE = new Instruction[][][] { { // nop = nothing @@ -412,7 +237,7 @@ public class InstructionSequenceConstants { // a = a = nothing { new VariableInstruction(InstructionConstants.OP_ALOAD, X), - new VariableInstruction(InstructionConstants.OP_ASTORE, X), + new SimpleInstruction(InstructionConstants.OP_POP), },{ // Nothing. }, @@ -557,12 +382,12 @@ public class InstructionSequenceConstants }, { // c * i = i * c { - new SimpleInstruction(InstructionConstants.OP_SIPUSH, A), + new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), new VariableInstruction(InstructionConstants.OP_ILOAD, X), new SimpleInstruction(InstructionConstants.OP_IMUL), },{ new VariableInstruction(InstructionConstants.OP_ILOAD, X), - new SimpleInstruction(InstructionConstants.OP_SIPUSH, A), + new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), new SimpleInstruction(InstructionConstants.OP_IMUL), }, }, @@ -723,7 +548,7 @@ public class InstructionSequenceConstants { // i = i + c = i += c { new VariableInstruction(InstructionConstants.OP_ILOAD, X), - new SimpleInstruction(InstructionConstants.OP_SIPUSH, A), + new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), new SimpleInstruction(InstructionConstants.OP_IADD), new VariableInstruction(InstructionConstants.OP_ISTORE, X), },{ @@ -826,23 +651,22 @@ public class InstructionSequenceConstants // Nothing. }, }, - // Not valid for -0.0. -// { // ... + 0f = ... -// { -// new SimpleInstruction(InstructionConstants.OP_FCONST_0), -// new SimpleInstruction(InstructionConstants.OP_FADD), -// },{ -// // Nothing. -// }, -// }, -// { // ... + 0d = ... -// { -// new SimpleInstruction(InstructionConstants.OP_DCONST_0), -// new SimpleInstruction(InstructionConstants.OP_DADD), -// },{ -// // Nothing. -// }, -// }, + { // ... + 0f = ... + { + new SimpleInstruction(InstructionConstants.OP_FCONST_0), + new SimpleInstruction(InstructionConstants.OP_FADD), + },{ + // Nothing. + }, + }, + { // ... + 0d = ... + { + new SimpleInstruction(InstructionConstants.OP_DCONST_0), + new SimpleInstruction(InstructionConstants.OP_DADD), + },{ + // Nothing. + }, + }, { // ... - 0 = ... { new SimpleInstruction(InstructionConstants.OP_ICONST_0), @@ -1248,8 +1072,7 @@ public class InstructionSequenceConstants new SimpleInstruction(InstructionConstants.OP_FNEG), }, }, - // Not valid for -0.0 and for NaN. -// { // ... * 0f = 0f +// { // ... * 0f = 0f (or NaN) // { // new SimpleInstruction(InstructionConstants.OP_FCONST_0), // new SimpleInstruction(InstructionConstants.OP_FMUL), @@ -1274,8 +1097,7 @@ public class InstructionSequenceConstants new SimpleInstruction(InstructionConstants.OP_DNEG), }, }, - // Not valid for -0.0 and for NaN. -// { // ... * 0d = 0d +// { // ... * 0d = 0d (or NaN) // { // new SimpleInstruction(InstructionConstants.OP_DCONST_0), // new SimpleInstruction(InstructionConstants.OP_DMUL), @@ -1682,7 +1504,6 @@ public class InstructionSequenceConstants new SimpleInstruction(InstructionConstants.OP_ICONST_0), }, }, - // Not valid for negative values. // { // ... % 2 = ... & 0x1 // { // new SimpleInstruction(InstructionConstants.OP_ICONST_2), @@ -3527,898 +3348,4 @@ public class InstructionSequenceConstants // }, // } }; - - public static final Instruction[][][] STRING = new Instruction[][][] - { - { // "...".equals("...") = true - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_EQUALS), - },{ - new SimpleInstruction(InstructionConstants.OP_ICONST_1), - }, - }, - { // "...".length() = ... - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_LENGTH), - },{ - new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH), - }, - }, - - { // new StringBuffer("...").toString() = "..." (ignoring identity) - { - new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER), - new SimpleInstruction(InstructionConstants.OP_DUP), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_TOSTRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, A), - }, - }, - { // new StringBuffer("...").length() = length - { - new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER), - new SimpleInstruction(InstructionConstants.OP_DUP), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_LENGTH), - },{ - new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH), - }, - }, - { // StringBuffer#append("") = nothing - { - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - },{ - // Nothing. - }, - }, - { // new StringBuffer().append(Z) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(C) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(Cc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(I) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(Ic) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(J) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(Jc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(F) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(Fc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(D) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append(Dc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer().append("...") = new StringBuffer("......") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Z) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(C) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Cc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(I) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Ic) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(J) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Jc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(F) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Fc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(D) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append(Dc) = new StringBuffer("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // new StringBuffer("...").append("...") = new StringBuffer("......") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING), - }, - }, - { // StringBuffer#append("...").append(Z) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(C) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(Cc) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(I) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(Ic) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(J) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(Jc) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(F) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(Fc) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(D) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append(Dc) = StringBuffer#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - { // StringBuffer#append("...").append("...") = StringBuffer#append("......") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING), - }, - }, - - { // new StringBuilder("...").toString() = "..." (ignoring identity) - { - new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER), - new SimpleInstruction(InstructionConstants.OP_DUP), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_TOSTRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, A), - }, - }, - { // new StringBuilder("...").length() = length - { - new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER), - new SimpleInstruction(InstructionConstants.OP_DUP), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_LENGTH), - },{ - new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH), - }, - }, - { // StringBuilder#append("") = nothing - { - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - },{ - // Nothing. - }, - }, - { // new StringBuilder().append(Z) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(C) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(Cc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(I) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(Ic) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(J) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(Jc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(F) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(Fc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(D) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append(Dc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder().append("...") = new StringBuilder("......") - { - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT), - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Z) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(C) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Cc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(I) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Ic) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(J) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Jc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(F) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Fc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(D) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append(Dc) = new StringBuilder("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // new StringBuilder("...").append("...") = new StringBuilder("......") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING), - }, - }, - { // StringBuilder#append("...").append(Z) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(C) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(Cc) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(I) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_ICONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(Ic) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(J) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_LCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(Jc) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(F) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_FCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(Fc) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(D) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new SimpleInstruction(InstructionConstants.OP_DCONST_0, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append(Dc) = StringBuilder#append("....") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC2_W, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - { // StringBuilder#append("...").append("...") = StringBuilder#append("......") - { - new ConstantInstruction(InstructionConstants.OP_LDC, A), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - new ConstantInstruction(InstructionConstants.OP_LDC, B), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - },{ - new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING), - new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING), - }, - }, - }; - - /* - static - { - ProgramClass clazz = new ProgramClass(); - clazz.constantPool = CONSTANTS; - - ClassPrinter printer = new ClassPrinter(); - - for (int index = 0; index < CONSTANTS.length; index++) - { - System.out.print("["+index+"] "); - try - { - CONSTANTS[index].accept(clazz, printer); - } - catch (Exception e) - { - System.out.println("("+e.getClass().getName()+")"); - } - } - - if (CONSTANTS.length != SENTINEL) - { - throw new IllegalStateException("Constants length ["+CONSTANTS.length+"] different from number of constant names ["+SENTINEL+"]"); - } - - Instruction[] instructions = STRING[2][0]; - - for (int index = 0; index < instructions.length; index++) - { - Instruction instruction = instructions[index]; - try - { - instruction.accept(clazz, null, null, index, new ClassPrinter()); - } - catch (Exception e) - { - //System.out.println(" "+instruction.toString(offset)); - } - } - } - //*/ -} +}
\ No newline at end of file diff --git a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java b/src/proguard/optimize/peephole/InstructionSequenceReplacer.java index be65b53..bce06e2 100644 --- a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java +++ b/src/proguard/optimize/peephole/InstructionSequenceReplacer.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 @@ -22,9 +22,9 @@ package proguard.optimize.peephole; import proguard.classfile.*; import proguard.classfile.attribute.CodeAttribute; -import proguard.classfile.constant.*; +import proguard.classfile.constant.Constant; import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.editor.*; +import proguard.classfile.editor.CodeAttributeEditor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.*; @@ -42,48 +42,10 @@ extends SimplifiedVisitor implements InstructionVisitor, ConstantVisitor { - /* - public static boolean DEBUG = true; - /*/ private static final boolean DEBUG = false; - //*/ - - public static final int X = InstructionSequenceMatcher.X; - public static final int Y = InstructionSequenceMatcher.Y; - public static final int Z = InstructionSequenceMatcher.Z; - - public static final int A = InstructionSequenceMatcher.A; - public static final int B = InstructionSequenceMatcher.B; - public static final int C = InstructionSequenceMatcher.C; - public static final int D = InstructionSequenceMatcher.D; - - private static final int BOOLEAN_STRING = 0x1; - private static final int CHAR_STRING = 0x2; - private static final int INT_STRING = 0x3; - private static final int LONG_STRING = 0x4; - private static final int FLOAT_STRING = 0x5; - private static final int DOUBLE_STRING = 0x6; - private static final int STRING_STRING = 0x7; - - public static final int STRING_A_LENGTH = 0x20000000; - public static final int BOOLEAN_A_STRING = 0x20000001; - public static final int CHAR_A_STRING = 0x20000002; - public static final int INT_A_STRING = 0x20000003; - public static final int LONG_A_STRING = 0x20000004; - public static final int FLOAT_A_STRING = 0x20000005; - public static final int DOUBLE_A_STRING = 0x20000006; - public static final int STRING_A_STRING = 0x20000007; - public static final int BOOLEAN_B_STRING = 0x20000010; - public static final int CHAR_B_STRING = 0x20000020; - public static final int INT_B_STRING = 0x20000030; - public static final int LONG_B_STRING = 0x20000040; - public static final int FLOAT_B_STRING = 0x20000050; - public static final int DOUBLE_B_STRING = 0x20000060; - public static final int STRING_B_STRING = 0x20000070; private final InstructionSequenceMatcher instructionSequenceMatcher; - private final Constant[] patternConstants; private final Instruction[] replacementInstructions; private final BranchTargetFinder branchTargetFinder; private final CodeAttributeEditor codeAttributeEditor; @@ -139,7 +101,6 @@ implements InstructionVisitor, InstructionVisitor extraInstructionVisitor) { this.instructionSequenceMatcher = new InstructionSequenceMatcher(patternConstants, patternInstructions); - this.patternConstants = patternConstants; this.replacementInstructions = replacementInstructions; this.branchTargetFinder = branchTargetFinder; this.codeAttributeEditor = codeAttributeEditor; @@ -179,7 +140,7 @@ implements InstructionVisitor, for (int index = 0; index < replacementInstructions.length; index++) { int matchedOffset = instructionSequenceMatcher.matchedInstructionOffset(index); - System.out.println(" "+replacementInstructionFactory.create(clazz, index).shrink().toString(matchedOffset)); + System.out.println(" "+replacementInstructionFactory.create(index).shrink().toString(matchedOffset)); } } @@ -187,7 +148,7 @@ implements InstructionVisitor, for (int index = 0; index < replacementInstructions.length; index++) { codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index), - replacementInstructionFactory.create(clazz, index).shrink()); + replacementInstructionFactory.create(index).shrink()); } // Delete any remaining instructions in the from sequence. @@ -243,10 +204,10 @@ implements InstructionVisitor, * Creates the replacement instruction for the given index in the * instruction sequence. */ - public Instruction create(Clazz clazz, int index) + public Instruction create(int index) { // Create the instruction. - replacementInstructions[index].accept(clazz, + replacementInstructions[index].accept(null, null, null, instructionSequenceMatcher.matchedInstructionOffset(index), @@ -263,7 +224,7 @@ implements InstructionVisitor, { replacementInstruction = new SimpleInstruction(simpleInstruction.opcode, - matchedArgument(clazz, simpleInstruction.constant)); + instructionSequenceMatcher.matchedArgument(simpleInstruction.constant)); } @@ -280,8 +241,7 @@ implements InstructionVisitor, { replacementInstruction = new ConstantInstruction(constantInstruction.opcode, - matchedConstantIndex((ProgramClass)clazz, - constantInstruction.constantIndex), + instructionSequenceMatcher.matchedConstantIndex(constantInstruction.constantIndex), instructionSequenceMatcher.matchedArgument(constantInstruction.constant)); } @@ -290,8 +250,7 @@ implements InstructionVisitor, { replacementInstruction = new BranchInstruction(branchInstruction.opcode, - instructionSequenceMatcher.matchedBranchOffset(offset, - branchInstruction.branchOffset)); + instructionSequenceMatcher.matchedBranchOffset(offset, branchInstruction.branchOffset)); } @@ -302,8 +261,7 @@ implements InstructionVisitor, instructionSequenceMatcher.matchedBranchOffset(offset, tableSwitchInstruction.defaultOffset), instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.lowCase), instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.highCase), - instructionSequenceMatcher.matchedJumpOffsets(offset, - tableSwitchInstruction.jumpOffsets)); + instructionSequenceMatcher.matchedJumpOffsets(offset, tableSwitchInstruction.jumpOffsets)); } @@ -316,105 +274,5 @@ implements InstructionVisitor, instructionSequenceMatcher.matchedArguments(lookUpSwitchInstruction.cases), instructionSequenceMatcher.matchedJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets)); } - - - /** - * Returns the matched argument for the given pattern argument. - */ - private int matchedArgument(Clazz clazz, int argument) - { - // Special case: do we have to compute the string length? - if (argument == STRING_A_LENGTH) - { - // Return the string length. - return clazz.getStringString(instructionSequenceMatcher.matchedArgument(A)).length(); - } - - // Otherwise, just return the matched argument. - return instructionSequenceMatcher.matchedArgument(argument); - } - - - /** - * Returns the matched or newly created constant index for the given - * pattern constant index. - */ - private int matchedConstantIndex(ProgramClass programClass, int constantIndex) - { - // Special case: do we have to create a concatenated string? - if (constantIndex >= BOOLEAN_A_STRING && - constantIndex <= (STRING_A_STRING | STRING_B_STRING)) - { - // Create a new string constant and return its index. - return new ConstantPoolEditor(programClass).addStringConstant( - argumentAsString(programClass, constantIndex & 0xf, A) + - argumentAsString(programClass, (constantIndex >>> 4) & 0xf, B), - null, - null); - } - - int matchedConstantIndex = - instructionSequenceMatcher.matchedConstantIndex(constantIndex); - - // Do we have a matched constant index? - if (matchedConstantIndex > 0) - { - // Return its index. - return matchedConstantIndex; - } - - // Otherwise, we still have to create a new constant. - // This currently only works for constants without any wildcards. - ProgramClass dummyClass = new ProgramClass(); - dummyClass.constantPool = patternConstants; - - return new ConstantAdder(programClass).addConstant(dummyClass, constantIndex); - } - - - private String argumentAsString(ProgramClass programClass, - int valueType, - int argument) - { - switch (valueType) - { - case BOOLEAN_STRING: - return Boolean.toString((instructionSequenceMatcher.wasConstant(argument) ? - ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument)) != 0); - - case CHAR_STRING: - return Character.toString((char)(instructionSequenceMatcher.wasConstant(argument) ? - ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument))); - - case INT_STRING: - return Integer.toString(instructionSequenceMatcher.wasConstant(argument) ? - ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument)); - - case LONG_STRING: - return Long.toString(instructionSequenceMatcher.wasConstant(argument) ? - ((LongConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument)); - - case FLOAT_STRING: - return Float.toString(instructionSequenceMatcher.wasConstant(argument) ? - ((FloatConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument)); - - case DOUBLE_STRING: - return Double.toString(instructionSequenceMatcher.wasConstant(argument) ? - ((DoubleConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() : - instructionSequenceMatcher.matchedArgument(argument)); - - case STRING_STRING: - return - programClass.getStringString(instructionSequenceMatcher.matchedConstantIndex(argument)); - - default: - return ""; - } - } } } diff --git a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java b/src/proguard/optimize/peephole/InstructionSequencesReplacer.java index 72fc334..f12b51a 100644 --- a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java +++ b/src/proguard/optimize/peephole/InstructionSequencesReplacer.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 diff --git a/src/proguard/optimize/peephole/MemberPrivatizer.java b/src/proguard/optimize/peephole/MemberPrivatizer.java index 254e968..55b2f31 100644 --- a/src/proguard/optimize/peephole/MemberPrivatizer.java +++ b/src/proguard/optimize/peephole/MemberPrivatizer.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 diff --git a/src/proguard/optimize/peephole/MethodFinalizer.java b/src/proguard/optimize/peephole/MethodFinalizer.java index 140a114..af1811b 100644 --- a/src/proguard/optimize/peephole/MethodFinalizer.java +++ b/src/proguard/optimize/peephole/MethodFinalizer.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 diff --git a/src/proguard/optimize/peephole/MethodInliner.java b/src/proguard/optimize/peephole/MethodInliner.java index 8857202..55f9ccb 100644 --- a/src/proguard/optimize/peephole/MethodInliner.java +++ b/src/proguard/optimize/peephole/MethodInliner.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 @@ -29,10 +29,10 @@ import proguard.classfile.editor.*; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.*; -import proguard.classfile.visitor.*; +import proguard.classfile.visitor.MemberVisitor; import proguard.optimize.info.*; -import java.util.*; +import java.util.Stack; /** * This AttributeVisitor inlines short methods or methods that are only invoked @@ -48,7 +48,7 @@ implements AttributeVisitor, MemberVisitor { private static final int MAXIMUM_INLINED_CODE_LENGTH = Integer.parseInt(System.getProperty("maximum.inlined.code.length", "8")); - private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "7000")); + private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "8000")); private static final int MAXIMUM_RESULTING_CODE_LENGTH_JME = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "2000")); private static final int MAXIMUM_CODE_EXPANSION = 2; private static final int MAXIMUM_EXTRA_CODE_LENGTH = 128; @@ -138,42 +138,6 @@ implements AttributeVisitor, public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { - // TODO: Remove this when the method inliner has stabilized. - // Catch any unexpected exceptions from the actual visiting method. - try - { - // Process the code. - visitCodeAttribute0(clazz, method, codeAttribute); - } - catch (RuntimeException ex) - { - System.err.println("Unexpected error while inlining method:"); - System.err.println(" Target class = ["+targetClass.getName()+"]"); - System.err.println(" Target method = ["+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]"); - if (inlining) - { - System.err.println(" Inlined class = ["+clazz.getName()+"]"); - System.err.println(" Inlined method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]"); - } - System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")"); - System.err.println("Not inlining this method"); - - if (DEBUG) - { - targetMethod.accept(targetClass, new ClassPrinter()); - if (inlining) - { - method.accept(clazz, new ClassPrinter()); - } - - throw ex; - } - } - } - - - public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) - { if (!inlining) { // codeAttributeComposer.DEBUG = DEBUG = @@ -341,12 +305,12 @@ implements AttributeVisitor, // Copy the instructions. codeAttribute.instructionsAccept(clazz, method, this); - // Append a label just after the code. - codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); - // Copy the exceptions. codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder); + // Append a label just after the code. + codeAttributeComposer.appendLabel(codeAttribute.u4codeLength); + codeAttributeComposer.endCodeFragment(); } @@ -493,42 +457,42 @@ implements AttributeVisitor, if (// Only inline the method if it is private, static, or final. (accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC | - ClassConstants.INTERNAL_ACC_FINAL)) != 0 && + ClassConstants.INTERNAL_ACC_FINAL)) != 0 && // Only inline the method if it is not synchronized, etc. (accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED | ClassConstants.INTERNAL_ACC_NATIVE | ClassConstants.INTERNAL_ACC_INTERFACE | - ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 && + ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 && // Don't inline an <init> method, except in an <init> method in the // same class. // (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) || // (programClass.equals(targetClass) && // targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) && - !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) && + !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) && // Don't inline a method into itself. (!programMethod.equals(targetMethod) || - !programClass.equals(targetClass)) && + !programClass.equals(targetClass)) && // Only inline the method if it isn't recursing. - !inliningMethods.contains(programMethod) && + !inliningMethods.contains(programMethod) && // Only inline the method if its target class has at least the // same version number as the source class, in order to avoid // introducing incompatible constructs. - targetClass.u4version >= programClass.u4version && + targetClass.u4version >= programClass.u4version && // Only inline the method if it doesn't invoke a super method, or if // it is in the same class. (!SuperInvocationMarker.invokesSuperMethods(programMethod) || - programClass.equals(targetClass)) && + programClass.equals(targetClass)) && // Only inline the method if it doesn't branch backward while there // are uninitialized objects. (!BackwardBranchMarker.branchesBackward(programMethod) || - uninitializedObjectCount == 0) && + uninitializedObjectCount == 0) && // Only inline if the code access of the inlined method allows it. (allowAccessModification || @@ -537,24 +501,47 @@ implements AttributeVisitor, (!AccessMethodMarker.accessesPackageCode(programMethod) || ClassUtil.internalPackageName(programClass.getName()).equals( - ClassUtil.internalPackageName(targetClass.getName()))))) && + ClassUtil.internalPackageName(targetClass.getName()))))) && // (!AccessMethodMarker.accessesProtectedCode(programMethod) || // targetClass.extends_(programClass) || // targetClass.implements_(programClass)) || (!AccessMethodMarker.accessesProtectedCode(programMethod) || - programClass.equals(targetClass)) && + programClass.equals(targetClass)) && // Only inline the method if it doesn't catch exceptions, or if it // is invoked with an empty stack. (!CatchExceptionMarker.catchesExceptions(programMethod) || - emptyInvokingStack) && + emptyInvokingStack) && - // Only inline the method if it comes from the a class with at most - // a subset of the initialized superclasses. + // Only inline the method if it comes from the same class or from + // a class with a static initializer. (programClass.equals(targetClass) || - initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass)))) - { boolean oldInlining = inlining; + programClass.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT, + ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) == null)) + { +// System.out.print("MethodInliner: inlining "); +// programMethod.accept(programClass, new SimpleClassPrinter(true)); +// System.out.print(" in "); +// targetMethod.accept(targetClass, new SimpleClassPrinter(true)); +// +// System.out.println(" Private: "+ +// (!AccessMethodMarker.accessesPrivateCode(programMethod) || +// programClass.equals(targetClass))); +// +// System.out.println(" Package: "+ +// (!AccessMethodMarker.accessesPackageCode(programMethod) || +// ClassUtil.internalPackageName(programClass.getName()).equals( +// ClassUtil.internalPackageName(targetClass.getName())))); +// +// System.out.println(" Protected: "+ +// ((!AccessMethodMarker.accessesProtectedCode(programMethod) || +// targetClass.extends_(programClass) || +// targetClass.implements_(programClass)) || +// ClassUtil.internalPackageName(programClass.getName()).equals( +// ClassUtil.internalPackageName(targetClass.getName())))); + + boolean oldInlining = inlining; inlining = true; inliningMethods.push(programMethod); @@ -577,21 +564,4 @@ implements AttributeVisitor, uninitializedObjectCount--; } } - - - /** - * Returns the set of superclasses and interfaces that are initialized. - */ - private Set initializedSuperClasses(Clazz clazz) - { - Set set = new HashSet(); - - // Visit all superclasses and interfaces, collecting the ones that have - // static initializers. - clazz.hierarchyAccept(true, true, true, false, - new StaticInitializerContainingClassFilter( - new ClassCollector(set))); - - return set; - } } diff --git a/src/proguard/optimize/peephole/NopRemover.java b/src/proguard/optimize/peephole/NopRemover.java index 4c99f3a..69adb30 100644 --- a/src/proguard/optimize/peephole/NopRemover.java +++ b/src/proguard/optimize/peephole/NopRemover.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 diff --git a/src/proguard/optimize/peephole/PeepholeOptimizer.java b/src/proguard/optimize/peephole/PeepholeOptimizer.java index d865638..98f8e8d 100644 --- a/src/proguard/optimize/peephole/PeepholeOptimizer.java +++ b/src/proguard/optimize/peephole/PeepholeOptimizer.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 diff --git a/src/proguard/optimize/peephole/ReachableCodeMarker.java b/src/proguard/optimize/peephole/ReachableCodeMarker.java index cac1965..d9dbf2d 100644 --- a/src/proguard/optimize/peephole/ReachableCodeMarker.java +++ b/src/proguard/optimize/peephole/ReachableCodeMarker.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 @@ -27,8 +27,6 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import java.util.Arrays; - /** * This AttributeVisitor finds all instruction offsets, branch targets, and * exception targets in the CodeAttribute objects that it visits. @@ -93,7 +91,10 @@ implements AttributeVisitor, else { // Reset the array. - Arrays.fill(isReachable, 0, codeLength, false); + for (int index = 0; index < codeLength; index++) + { + isReachable[index] = false; + } } // Mark the code, starting at the entry point. diff --git a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java index 254f748..6707a12 100644 --- a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java +++ b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.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 @@ -28,8 +28,6 @@ import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.ClassVisitor; -import java.util.Arrays; - /** * This ClassVisitor removes InnerClasses and EnclosingMethod attributes in * classes that are retargeted or that refer to classes that are retargeted. @@ -72,7 +70,10 @@ implements ClassVisitor, } // Clean up any remaining array elements. - Arrays.fill(attributes, newAtributesCount, attributesCount, null); + for (int index = newAtributesCount; index < attributesCount; index++) + { + attributes[index] = null; + } // Update the number of attribuets. programClass.u2attributesCount = newAtributesCount; @@ -89,39 +90,8 @@ implements ClassVisitor, // Check whether the class itself is retargeted. checkTarget(clazz); - if (!retargeted) - { - // Check whether the referenced classes are retargeted. - innerClassesAttribute.innerClassEntriesAccept(clazz, this); - int classesCount = innerClassesAttribute.u2classesCount; - InnerClassesInfo[] classes = innerClassesAttribute.classes; - - int newClassesCount = 0; - - // Copy over all non-retargeted attributes. - for (int index = 0; index < classesCount; index++) - { - InnerClassesInfo classInfo = classes[index]; - - // Check if the outer class or inner class is a retargeted class. - retargeted = false; - classInfo.outerClassConstantAccept(clazz, this); - classInfo.innerClassConstantAccept(clazz, this); - if (!retargeted) - { - classes[newClassesCount++] = classInfo; - } - } - - // Clean up any remaining array elements. - Arrays.fill(classes, newClassesCount, classesCount, null); - - // Update the number of classes. - innerClassesAttribute.u2classesCount = newClassesCount; - - // Remove the attribute altogether if it's empty. - retargeted = newClassesCount == 0; - } + // Check whether the referenced classes are retargeted. + innerClassesAttribute.innerClassEntriesAccept(clazz, this); } diff --git a/src/proguard/optimize/peephole/TargetClassChanger.java b/src/proguard/optimize/peephole/TargetClassChanger.java index 5fa4fac..22fd83d 100644 --- a/src/proguard/optimize/peephole/TargetClassChanger.java +++ b/src/proguard/optimize/peephole/TargetClassChanger.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 @@ -51,13 +51,13 @@ implements ClassVisitor, AnnotationVisitor, ElementValueVisitor { - private static final boolean DEBUG = false; - - // Implementations for ClassVisitor. public void visitProgramClass(ProgramClass programClass) { + Clazz superClass = null; + Clazz[] interfaceClasses = null; + // Change the references of the constant pool. programClass.constantPoolEntriesAccept(this); @@ -80,39 +80,34 @@ implements ClassVisitor, programClass.getName(), programClass); - // This class will loose all its interfaces. - programClass.u2interfacesCount = 0; - // This class will loose all its subclasses. programClass.subClasses = null; } - else + + // Remove interface classes that are pointing to this class. + int newInterfacesCount = 0; + for (int index = 0; index < programClass.u2interfacesCount; index++) { - // Remove interface classes that are pointing to this class. - int newInterfacesCount = 0; - for (int index = 0; index < programClass.u2interfacesCount; index++) + Clazz interfaceClass = programClass.getInterface(index); + if (!programClass.equals(interfaceClass)) { - Clazz interfaceClass = programClass.getInterface(index); - if (!programClass.equals(interfaceClass)) - { - programClass.u2interfaces[newInterfacesCount++] = - programClass.u2interfaces[index]; - } + programClass.u2interfaces[newInterfacesCount++] = + programClass.u2interfaces[index]; } - programClass.u2interfacesCount = newInterfacesCount; + } + programClass.u2interfacesCount = newInterfacesCount; - // Update the subclasses of the superclass and interfaces of the - // target class. - ConstantVisitor subclassAdder = - new ReferencedClassVisitor( - new SubclassFilter(programClass, - new SubclassAdder(programClass))); + // Update the subclasses of the superclass and interfaces of the + // target class. + ConstantVisitor subclassAdder = + new ReferencedClassVisitor( + new SubclassFilter(programClass, + new SubclassAdder(programClass))); - programClass.superClassConstantAccept(subclassAdder); - programClass.interfaceConstantsAccept(subclassAdder); + programClass.superClassConstantAccept(subclassAdder); + programClass.interfaceConstantsAccept(subclassAdder); - // TODO: Maybe restore private method references. - } + // TODO: Maybe restore private method references. } @@ -193,12 +188,6 @@ implements ClassVisitor, Clazz newReferencedClass = updateReferencedClass(referencedClass); if (referencedClass != newReferencedClass) { - if (DEBUG) - { - System.out.println("TargetClassChanger:"); - System.out.println(" ["+clazz.getName()+"] changing reference from ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]"); - } - // Change the referenced class. refConstant.referencedClass = newReferencedClass; @@ -208,11 +197,6 @@ implements ClassVisitor, refConstant.getName(clazz), refConstant.getType(clazz), newReferencedClass); - - if (DEBUG) - { - System.out.println(" ["+clazz.getName()+"] to ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]"); - } } } diff --git a/src/proguard/optimize/peephole/UnreachableCodeRemover.java b/src/proguard/optimize/peephole/UnreachableCodeRemover.java index fcb8914..e8a99ab 100644 --- a/src/proguard/optimize/peephole/UnreachableCodeRemover.java +++ b/src/proguard/optimize/peephole/UnreachableCodeRemover.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 diff --git a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java b/src/proguard/optimize/peephole/UnreachableExceptionRemover.java index f3ecf0b..048f5e3 100644 --- a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java +++ b/src/proguard/optimize/peephole/UnreachableExceptionRemover.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 diff --git a/src/proguard/optimize/peephole/VariableShrinker.java b/src/proguard/optimize/peephole/VariableShrinker.java index 55f42ca..45b694f 100644 --- a/src/proguard/optimize/peephole/VariableShrinker.java +++ b/src/proguard/optimize/peephole/VariableShrinker.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 diff --git a/src/proguard/optimize/peephole/VerticalClassMerger.java b/src/proguard/optimize/peephole/VerticalClassMerger.java index 721f2a5..29ed6ff 100644 --- a/src/proguard/optimize/peephole/VerticalClassMerger.java +++ b/src/proguard/optimize/peephole/VerticalClassMerger.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 |