diff options
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info')
36 files changed, 4368 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java new file mode 100644 index 0000000000..b030c55ddb --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/AccessMethodMarker.java @@ -0,0 +1,201 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * This InstructionVisitor marks the types of class accesses and class member + * accesses of the methods whose instructions it visits. + * + * @author Eric Lafortune + */ +public class AccessMethodMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + ClassVisitor, + MemberVisitor +{ + private Method invokingMethod; + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + invokingMethod = method; + + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + // Check the referenced class or class member, if any. + stringConstant.referencedClassAccept(this); + stringConstant.referencedMemberAccept(this); + } + + + 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. + clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); + + // Check the referenced class member itself. + refConstant.referencedClassAccept(this); + refConstant.referencedMemberAccept(this); + } + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + // Check the referenced class. + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) + { + int accessFlags = clazz.getAccessFlags(); + + if ((accessFlags & ClassConstants.ACC_PUBLIC) == 0) + { + setAccessesPackageCode(invokingMethod); + } + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz clazz, Member member) + { + int accessFlags = member.getAccessFlags(); + + if ((accessFlags & ClassConstants.ACC_PRIVATE) != 0) + { + setAccessesPrivateCode(invokingMethod); + } + else if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0) + { + setAccessesProtectedCode(invokingMethod); + } + else if ((accessFlags & ClassConstants.ACC_PUBLIC) == 0) + { + setAccessesPackageCode(invokingMethod); + } + } + + + // Small utility methods. + + private static void setAccessesPrivateCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setAccessesPrivateCode(); + } + } + + + /** + * Returns whether the given method accesses private class members. + */ + public static boolean accessesPrivateCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.accessesPrivateCode(); + } + + + private static void setAccessesPackageCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setAccessesPackageCode(); + } + } + + + /** + * Returns whether the given method accesses package visible classes or class + * members. + */ + public static boolean accessesPackageCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.accessesPackageCode(); + } + + + private static void setAccessesProtectedCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setAccessesProtectedCode(); + } + } + + + /** + * Returns whether the given method accesses protected class members. + */ + public static boolean accessesProtectedCode(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.accessesProtectedCode(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java new file mode 100644 index 0000000000..af1862e36e --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/BackwardBranchMarker.java @@ -0,0 +1,90 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This InstructionVisitor marks all methods that branch backward in any of the + * instructions that it visits. + * + * @author Eric Lafortune + */ +public class BackwardBranchMarker +extends SimplifiedVisitor +implements InstructionVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) + { + markBackwardBranch(method, branchInstruction.branchOffset); + } + + + public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction) + { + markBackwardBranch(method, switchInstruction.defaultOffset); + + for (int index = 0; index < switchInstruction.jumpOffsets.length; index++) + { + markBackwardBranch(method, switchInstruction.jumpOffsets[index]); + } + } + + + // Small utility methods. + + /** + * Marks the given method if the given branch offset is negative. + */ + private void markBackwardBranch(Method method, int branchOffset) + { + if (branchOffset < 0) + { + setBranchesBackward(method); + } + } + + + private static void setBranchesBackward(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setBranchesBackward(); + } + } + + + public static boolean branchesBackward(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.branchesBackward(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java new file mode 100644 index 0000000000..9105142d6e --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CatchExceptionMarker.java @@ -0,0 +1,69 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This AttributeVisitor marks all methods that catch exceptions. + * + * @author Eric Lafortune + */ +public class CatchExceptionMarker +extends SimplifiedVisitor +implements AttributeVisitor +{ + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + if (codeAttribute.u2exceptionTableLength > 0) + { + markCatchException(method); + } + } + + + // Small utility methods. + + private static void markCatchException(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setCatchesExceptions(); + } + } + + + public static boolean catchesExceptions(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || + info.catchesExceptions(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java new file mode 100644 index 0000000000..78f10cf034 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassFilter.java @@ -0,0 +1,63 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 caught as exceptions. + * + * @see CaughtClassMarker + * @author Eric Lafortune + */ +public class CaughtClassFilter +implements ClassVisitor +{ + private final ClassVisitor classVisitor; + + + public CaughtClassFilter(ClassVisitor classVisitor) + { + this.classVisitor = classVisitor; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + if (CaughtClassMarker.isCaught(programClass)) + { + classVisitor.visitProgramClass(programClass); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + if (CaughtClassMarker.isCaught(libraryClass)) + { + classVisitor.visitLibraryClass(libraryClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java new file mode 100644 index 0000000000..9d4a1e9e52 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/CaughtClassMarker.java @@ -0,0 +1,63 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 marks all program classes that it visits as caught. + * This means that these classes are exception classes that occur in exception + * handlers. + * + * @author Eric Lafortune + */ +public class CaughtClassMarker +implements ClassVisitor +{ + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + public void visitProgramClass(ProgramClass programClass) + { + setCaught(programClass); + } + + + // Small utility methods. + + private static void setCaught(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setCaught(); + } + } + + + public static boolean isCaught(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.isCaught(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java new file mode 100644 index 0000000000..4bf1e9fd69 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfo.java @@ -0,0 +1,177 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.Clazz; + +/** + * This class stores some optimization information that can be attached to + * a class. + * + * @author Eric Lafortune + */ +public class ClassOptimizationInfo +{ + private boolean isInstantiated = false; + private boolean isInstanceofed = false; + private boolean isDotClassed = false; + private boolean isCaught = false; + private boolean isSimpleEnum = false; + private boolean containsStaticInitializer = false; + private boolean containsPackageVisibleMembers = false; + private boolean invokesPackageVisibleMembers = false; + private Clazz targetClass; + + + public void setInstantiated() + { + isInstantiated = true; + } + + + public boolean isInstantiated() + { + return isInstantiated; + } + + + public void setInstanceofed() + { + isInstanceofed = true; + } + + + public boolean isInstanceofed() + { + return isInstanceofed; + } + + + public void setDotClassed() + { + isDotClassed = true; + } + + + public boolean isDotClassed() + { + return isDotClassed; + } + + + public void setCaught() + { + isCaught = true; + } + + + public boolean isCaught() + { + return isCaught; + } + + + public void setSimpleEnum(boolean simple) + { + isSimpleEnum = simple; + } + + + public boolean isSimpleEnum() + { + return isSimpleEnum; + } + + + public void setContainsStaticInitializer() + { + containsStaticInitializer = true; + } + + + public boolean containsStaticInitializer() + { + return containsStaticInitializer; + } + + + public void setContainsPackageVisibleMembers() + { + containsPackageVisibleMembers = true; + } + + + public boolean containsPackageVisibleMembers() + { + return containsPackageVisibleMembers; + } + + + public void setInvokesPackageVisibleMembers() + { + invokesPackageVisibleMembers = true; + } + + + public boolean invokesPackageVisibleMembers() + { + return invokesPackageVisibleMembers; + } + + + public void setTargetClass(Clazz targetClass) + { + this.targetClass = targetClass; + } + + + public Clazz getTargetClass() + { + return targetClass; + } + + + public void merge(ClassOptimizationInfo other) + { + this.isInstantiated |= other.isInstantiated; + this.isInstanceofed |= other.isInstanceofed; + this.isDotClassed |= other.isDotClassed; + this.isCaught |= other.isCaught; + this.containsStaticInitializer |= other.containsStaticInitializer; + this.containsPackageVisibleMembers |= other.containsPackageVisibleMembers; + this.invokesPackageVisibleMembers |= other.invokesPackageVisibleMembers; + } + + + public static void setClassOptimizationInfo(Clazz clazz) + { + clazz.setVisitorInfo(new ClassOptimizationInfo()); + } + + + public static ClassOptimizationInfo getClassOptimizationInfo(Clazz clazz) + { + Object visitorInfo = clazz.getVisitorInfo(); + return visitorInfo instanceof ClassOptimizationInfo ? + (ClassOptimizationInfo)visitorInfo : + null; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java new file mode 100644 index 0000000000..ea143d68be --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ClassOptimizationInfoSetter.java @@ -0,0 +1,47 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.ProgramClass; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; +import proguard.optimize.KeepMarker; + +/** + * This ClassVisitor attaches a ClassOptimizationInfo instance to every class + * that is not being kept that it visits. + * + * @author Eric Lafortune + */ +public class ClassOptimizationInfoSetter +extends SimplifiedVisitor +implements ClassVisitor +{ + // Implementations for MemberVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + if (!KeepMarker.isKept(programClass)) + { + ClassOptimizationInfo.setClassOptimizationInfo(programClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java new file mode 100644 index 0000000000..9c85568357 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassFilter.java @@ -0,0 +1,63 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 used in a .class construct. + * + * @see DotClassMarker + * @author Eric Lafortune + */ +public class DotClassFilter +implements ClassVisitor +{ + private final ClassVisitor classVisitor; + + + public DotClassFilter(ClassVisitor classVisitor) + { + this.classVisitor = classVisitor; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + if (DotClassMarker.isDotClassed(programClass)) + { + classVisitor.visitProgramClass(programClass); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + if (DotClassMarker.isDotClassed(libraryClass)) + { + classVisitor.visitLibraryClass(libraryClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java new file mode 100644 index 0000000000..d7f8fa3149 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DotClassMarker.java @@ -0,0 +1,96 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This InstructionVisitor marks all classes that are used in a .class + * construct by any of the instructions that it visits. + * + * @author Eric Lafortune + */ +public class DotClassMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + ClassVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_LDC || + constantInstruction.opcode == InstructionConstants.OP_LDC_W) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + public void visitProgramClass(ProgramClass programClass) + { + setDotClassed(programClass); + } + + + // Small utility methods. + + private static void setDotClassed(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setDotClassed(); + } + } + + + public static boolean isDotClassed(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.isDotClassed(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java new file mode 100644 index 0000000000..f59244cfbf --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/DynamicInvocationMarker.java @@ -0,0 +1,79 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * This InstructionVisitor marks whether the methods whose instructions it + * visits contain the invokedynamic instruction. + * + * @author Eric Lafortune + */ +public class DynamicInvocationMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + ClassVisitor, + MemberVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_INVOKEDYNAMIC) + { + setInvokesDynamically(method); + } + } + + + // Small utility methods. + + private static void setInvokesDynamically(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setInvokesDynamically(); + } + } + + + /** + * Returns whether the given method calls the invokedynamic instruction. + */ + public static boolean invokesDynamically(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.invokesDynamically(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java new file mode 100644 index 0000000000..727139116f --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ExceptionInstructionChecker.java @@ -0,0 +1,260 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This class can tell whether an instruction might throw exceptions. + * + * @author Eric Lafortune + */ +public class ExceptionInstructionChecker +extends SimplifiedVisitor +implements InstructionVisitor +// ConstantVisitor, +// MemberVisitor +{ + // A return value for the visitor methods. + private boolean mayThrowExceptions; + + + /** + * Returns whether the specified method may throw exceptions. + */ + public boolean mayThrowExceptions(Clazz clazz, + Method method, + CodeAttribute codeAttribute) + { + return mayThrowExceptions(clazz, + method, + codeAttribute, + 0, + codeAttribute.u4codeLength); + } + + + /** + * Returns whether the specified block of code may throw exceptions. + */ + public boolean mayThrowExceptions(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int startOffset, + int endOffset) + { + byte[] code = codeAttribute.code; + + // Go over all instructions. + int offset = startOffset; + while (offset < endOffset) + { + // Get the current instruction. + Instruction instruction = InstructionFactory.create(code, offset); + + // Check if it may be throwing exceptions. + if (mayThrowExceptions(clazz, + method, + codeAttribute, + offset, + instruction)) + { + return true; + } + + // Go to the next instruction. + offset += instruction.length(offset); + } + + return false; + } + + + /** + * Returns whether the specified instruction may throw exceptions. + */ + public boolean mayThrowExceptions(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset) + { + Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); + + return mayThrowExceptions(clazz, + method, + codeAttribute, + offset, + instruction); + } + + + /** + * Returns whether the given instruction may throw exceptions. + */ + public boolean mayThrowExceptions(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + return instruction.mayThrowExceptions(); + +// mayThrowExceptions = false; +// +// instruction.accept(clazz, method, codeAttribute, offset, this); +// +// return mayThrowExceptions; + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) + { + // 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 (simpleInstruction.opcode) + { + 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; + } + } + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + // Check for instructions that may throw exceptions. + switch (constantInstruction.opcode) + { + 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; + +// case InstructionConstants.OP_INVOKEVIRTUAL: +// case InstructionConstants.OP_INVOKESPECIAL: +// case InstructionConstants.OP_INVOKESTATIC: +// case InstructionConstants.OP_INVOKEINTERFACE: +// // Check if the invoking the method may throw an exception. +// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + } + + +// // Implementations for ConstantVisitor. +// +// public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) +// { +// Member referencedMember = refConstant.referencedMember; +// +// // Do we have a reference to the method? +// if (referencedMember == null) +// { +// // We'll have to assume invoking the unknown method may throw an +// // an exception. +// mayThrowExceptions = true; +// } +// else +// { +// // First check the referenced method itself. +// refConstant.referencedMemberAccept(this); +// +// // If the result isn't conclusive, check down the hierarchy. +// if (!mayThrowExceptions) +// { +// Clazz referencedClass = refConstant.referencedClass; +// Method referencedMethod = (Method)referencedMember; +// +// // Check all other implementations of the method in the class +// // hierarchy. +// referencedClass.methodImplementationsAccept(referencedMethod, +// false, +// false, +// true, +// true, +// this); +// } +// } +// } +// +// +// // Implementations for MemberVisitor. +// +// public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) +// { +// mayThrowExceptions = mayThrowExceptions || +// ExceptionMethodMarker.mayThrowExceptions(programMethod); +// } +// +// +// public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) +// { +// mayThrowExceptions = mayThrowExceptions || +// !NoExceptionMethodMarker.doesntThrowExceptions(libraryMethod); +// } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java new file mode 100644 index 0000000000..5be9ce7df3 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/FieldOptimizationInfo.java @@ -0,0 +1,188 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.evaluation.ConstantValueFactory; +import proguard.evaluation.value.*; + +/** + * This class stores some optimization information that can be attached to + * a field. + * + * @author Eric Lafortune + */ +public class FieldOptimizationInfo +extends SimplifiedVisitor +implements AttributeVisitor +{ + private static final ParticularValueFactory VALUE_FACTORY = new ParticularValueFactory(); + private static final ConstantValueFactory CONSTANT_VALUE_FACTORY = new ConstantValueFactory(VALUE_FACTORY); + private static final InitialValueFactory INITIAL_VALUE_FACTORY = new InitialValueFactory(VALUE_FACTORY); + + private boolean isWritten; + private boolean isRead; + private boolean canBeMadePrivate = true; + private ReferenceValue referencedClass; + private Value value; + + + public FieldOptimizationInfo(Clazz clazz, Field field) + { + int accessFlags = field.getAccessFlags(); + + isWritten = + isRead = (accessFlags & ClassConstants.ACC_VOLATILE) != 0; + + resetValue(clazz, field); + } + + + public FieldOptimizationInfo(FieldOptimizationInfo FieldOptimizationInfo) + { + this.isWritten = FieldOptimizationInfo.isWritten; + this.isRead = FieldOptimizationInfo.isRead; + this.canBeMadePrivate = FieldOptimizationInfo.canBeMadePrivate; + this.referencedClass = FieldOptimizationInfo.referencedClass; + this.value = FieldOptimizationInfo.value; + } + + + public void setWritten() + { + isWritten = true; + } + + + public boolean isWritten() + { + return isWritten; + } + + + public void setRead() + { + isRead = true; + } + + + public boolean isRead() + { + return isRead; + } + + + public void setCanNotBeMadePrivate() + { + canBeMadePrivate = false; + } + + + public boolean canBeMadePrivate() + { + return canBeMadePrivate; + } + + + public void generalizeReferencedClass(ReferenceValue referencedClass) + { + this.referencedClass = this.referencedClass != null ? + this.referencedClass.generalize(referencedClass) : + referencedClass; + } + + + public ReferenceValue getReferencedClass() + { + return referencedClass; + } + + + public void resetValue(Clazz clazz, Field field) + { + int accessFlags = field.getAccessFlags(); + + value = null; + + // See if we can initialize a static field with a constant value. + if ((accessFlags & ClassConstants.ACC_STATIC) != 0) + { + field.accept(clazz, new AllAttributeVisitor(this)); + } + + // Otherwise initialize a non-final field with the default value. + // Conservatively, even a final field needs to be initialized with the + // default value, because it may be accessed before it is set. + if (value == null && + (SideEffectInstructionChecker.OPTIMIZE_CONSERVATIVELY || + (accessFlags & ClassConstants.ACC_FINAL) == 0)) + { + value = INITIAL_VALUE_FACTORY.createValue(field.getDescriptor(clazz)); + } + } + + + public void generalizeValue(Value value) + { + this.value = this.value != null ? + this.value.generalize(value) : + value; + } + + + public Value getValue() + { + return value; + } + + + // 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. + + public static void setFieldOptimizationInfo(Clazz clazz, Field field) + { + field.setVisitorInfo(new FieldOptimizationInfo(clazz, field)); + } + + + public static FieldOptimizationInfo getFieldOptimizationInfo(Field field) + { + Object visitorInfo = field.getVisitorInfo(); + + return visitorInfo instanceof FieldOptimizationInfo ? + (FieldOptimizationInfo)visitorInfo : + null; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java new file mode 100644 index 0000000000..35d3b5d2c0 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassFilter.java @@ -0,0 +1,63 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 used in an 'instanceof' test. + * + * @see InstanceofClassMarker + * @author Eric Lafortune + */ +public class InstanceofClassFilter +implements ClassVisitor +{ + private final ClassVisitor classVisitor; + + + public InstanceofClassFilter(ClassVisitor classVisitor) + { + this.classVisitor = classVisitor; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + if (InstanceofClassMarker.isInstanceofed(programClass)) + { + classVisitor.visitProgramClass(programClass); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + if (InstanceofClassMarker.isInstanceofed(libraryClass)) + { + classVisitor.visitLibraryClass(libraryClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java new file mode 100644 index 0000000000..26cc9665af --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstanceofClassMarker.java @@ -0,0 +1,93 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.ClassConstant; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This InstructionVisitor marks all classes that are used in an 'instanceof' + * test by any of the instructions that it visits. + * + * @author Eric Lafortune + */ +public class InstanceofClassMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + ClassVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_INSTANCEOF) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + } + + + // Implementations for ConstantVisitor. + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + public void visitProgramClass(ProgramClass programClass) + { + setInstanceofed(programClass); + } + + + // Small utility methods. + + private static void setInstanceofed(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setInstanceofed(); + } + } + + + public static boolean isInstanceofed(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.isInstanceofed(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java new file mode 100644 index 0000000000..804e9d0caf --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassFilter.java @@ -0,0 +1,62 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 InstantiationClassFilter +implements ClassVisitor +{ + private final ClassVisitor classVisitor; + + + public InstantiationClassFilter(ClassVisitor classVisitor) + { + this.classVisitor = classVisitor; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + if (InstantiationClassMarker.isInstantiated(programClass)) + { + classVisitor.visitProgramClass(programClass); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + if (InstantiationClassMarker.isInstantiated(libraryClass)) + { + classVisitor.visitLibraryClass(libraryClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java new file mode 100644 index 0000000000..610be97e48 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/InstantiationClassMarker.java @@ -0,0 +1,93 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.ClassConstant; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This InstructionVisitor marks all classes that are instantiated by any of + * the instructions that it visits. + * + * @author Eric Lafortune + */ +public class InstantiationClassMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + ClassVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_NEW) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + } + + + // Implementations for ConstantVisitor. + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + public void visitProgramClass(ProgramClass programClass) + { + setInstantiated(programClass); + } + + + // Small utility methods. + + private static void setInstantiated(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setInstantiated(); + } + } + + + public static boolean isInstantiated(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.isInstantiated(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java new file mode 100644 index 0000000000..4a09e09edc --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MemberOptimizationInfoSetter.java @@ -0,0 +1,59 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.MemberVisitor; +import proguard.optimize.KeepMarker; + +/** + * This MemberVisitor attaches a FieldOptimizationInfo instance to every field + * and a MethodOptimizationInfo instance to every method that is not being kept + * that it visits. + * + * @author Eric Lafortune + */ +public class MemberOptimizationInfoSetter +extends SimplifiedVisitor +implements MemberVisitor +{ + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + if (!KeepMarker.isKept(programField)) + { + FieldOptimizationInfo.setFieldOptimizationInfo(programClass, + programField); + } + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + if (!KeepMarker.isKept(programMethod)) + { + MethodOptimizationInfo.setMethodOptimizationInfo(programClass, + programMethod); + } + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java new file mode 100644 index 0000000000..2288669df6 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodInvocationMarker.java @@ -0,0 +1,107 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.MemberVisitor; + +/** + * This InstructionVisitor counts the number of times methods are invoked from + * the instructions that are visited. + * + * @author Eric Lafortune + */ +public class MethodInvocationMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + MemberVisitor +{ + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + // Mark the referenced method, if any. + stringConstant.referencedMemberAccept(this); + } + + + public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) + { + // Mark the referenced method. + refConstant.referencedMemberAccept(this); + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz Clazz, Member member) {} + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + incrementInvocationCount(programMethod); + } + + + // Small utility methods. + + private static void incrementInvocationCount(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.incrementInvocationCount(); + } + } + + + /** + * Returns the number of times the given method was invoked by the + * instructions that were visited. + */ + public static int getInvocationCount(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info != null ? info.getInvocationCount() : + Integer.MAX_VALUE; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java new file mode 100644 index 0000000000..2e56910895 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/MethodOptimizationInfo.java @@ -0,0 +1,336 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.*; +import proguard.evaluation.value.Value; + +/** + * This class stores some optimization information that can be attached to + * a method. + * + * @author Eric Lafortune + */ +public class MethodOptimizationInfo +{ + private boolean hasNoSideEffects = false; + private boolean hasSideEffects = false; + private boolean canBeMadePrivate = true; + private boolean catchesExceptions = false; + private boolean branchesBackward = false; + private boolean invokesSuperMethods = false; + private boolean invokesDynamically = false; + private boolean accessesPrivateCode = false; + private boolean accessesPackageCode = false; + private boolean accessesProtectedCode = false; + private boolean returnsWithNonEmptyStack = false; + private int invocationCount = 0; + private int parameterSize = 0; + private long usedParameters = 0L; + private Value[] parameters; + private Value returnValue; + + + /** + * Creates a new MethodOptimizationInfo for the given method. + */ + public MethodOptimizationInfo(Clazz clazz, Method method) + { + // Set up an array of the right size for storing information about the + // passed parameters. + int parameterCount = + ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz)); + + if ((method.getAccessFlags() & ClassConstants.ACC_STATIC) == 0) + { + parameterCount++; + } + + if (parameterCount > 0) + { + parameters = new Value[parameterCount]; + } + } + + + public void setNoSideEffects() + { + hasNoSideEffects = true; + } + + + public boolean hasNoSideEffects() + { + return hasNoSideEffects; + } + + + public void setSideEffects() + { + hasSideEffects = true; + } + + + public boolean hasSideEffects() + { + return hasSideEffects; + } + + + public void setCanNotBeMadePrivate() + { + canBeMadePrivate = false; + } + + + public boolean canBeMadePrivate() + { + return canBeMadePrivate; + } + + + public void setCatchesExceptions() + { + catchesExceptions = true; + } + + + public boolean catchesExceptions() + { + return catchesExceptions; + } + + + public void setBranchesBackward() + { + branchesBackward = true; + } + + + public boolean branchesBackward() + { + return branchesBackward; + } + + + public void setInvokesSuperMethods() + { + invokesSuperMethods = true; + } + + + public boolean invokesSuperMethods() + { + return invokesSuperMethods; + } + + + public void setInvokesDynamically() + { + invokesDynamically = true; + } + + + public boolean invokesDynamically() + { + return invokesDynamically; + } + + + public void setAccessesPrivateCode() + { + accessesPrivateCode = true; + } + + + public boolean accessesPrivateCode() + { + return accessesPrivateCode; + } + + + public void setAccessesPackageCode() + { + accessesPackageCode = true; + } + + + public boolean accessesPackageCode() + { + return accessesPackageCode; + } + + + public void setAccessesProtectedCode() + { + accessesProtectedCode = true; + } + + + public boolean accessesProtectedCode() + { + return accessesProtectedCode; + } + + + public void setReturnsWithNonEmptyStack() + { + returnsWithNonEmptyStack = true; + } + + + public boolean returnsWithNonEmptyStack() + { + return returnsWithNonEmptyStack; + } + + + public void incrementInvocationCount() + { + invocationCount++; + } + + + public int getInvocationCount() + { + return invocationCount; + } + + + public void setParameterSize(int parameterSize) + { + this.parameterSize = parameterSize; + } + + + public int getParameterSize() + { + return parameterSize; + } + + + public void setParameterUsed(int parameterIndex) + { + usedParameters |= 1L << parameterIndex; + } + + + public void setUsedParameters(long usedParameters) + { + this.usedParameters = usedParameters; + } + + + public boolean isParameterUsed(int parameterIndex) + { + return parameterIndex >= 64 || (usedParameters & (1L << parameterIndex)) != 0; + } + + + public long getUsedParameters() + { + return usedParameters; + } + + + public void generalizeParameter(int parameterIndex, Value parameter) + { + parameters[parameterIndex] = parameters[parameterIndex] != null ? + parameters[parameterIndex].generalize(parameter) : + parameter; + } + + + public Value getParameter(int parameterIndex) + { + return parameters != null ? + parameters[parameterIndex] : + null; + } + + + public void generalizeReturnValue(Value returnValue) + { + this.returnValue = this.returnValue != null ? + this.returnValue.generalize(returnValue) : + returnValue; + } + + + public Value getReturnValue() + { + return returnValue; + } + + + // For setting enum return values. + public void setReturnValue(Value returnValue) + { + this.returnValue = returnValue; + } + + + public void merge(MethodOptimizationInfo other) + { + if (other != null) + { + this.hasNoSideEffects &= other.hasNoSideEffects; + this.hasSideEffects |= other.hasSideEffects; + //this.canBeMadePrivate &= other.canBeMadePrivate; + this.catchesExceptions |= other.catchesExceptions; + this.branchesBackward |= other.branchesBackward; + this.invokesSuperMethods |= other.invokesSuperMethods; + this.invokesDynamically |= other.invokesDynamically; + this.accessesPrivateCode |= other.accessesPrivateCode; + this.accessesPackageCode |= other.accessesPackageCode; + this.accessesProtectedCode |= other.accessesProtectedCode; + } + else + { + this.hasNoSideEffects = false; + this.hasSideEffects = true; + //this.canBeMadePrivate = false; + this.catchesExceptions = true; + this.branchesBackward = true; + this.invokesSuperMethods = true; + this.accessesPrivateCode = true; + this.accessesPackageCode = true; + this.accessesProtectedCode = true; + } + } + + + public static void setMethodOptimizationInfo(Clazz clazz, Method method) + { + MethodLinker.lastMember(method).setVisitorInfo(new MethodOptimizationInfo(clazz, method)); + } + + + public static MethodOptimizationInfo getMethodOptimizationInfo(Method method) + { + Object visitorInfo = MethodLinker.lastMember(method).getVisitorInfo(); + + return visitorInfo instanceof MethodOptimizationInfo ? + (MethodOptimizationInfo)visitorInfo : + null; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java new file mode 100644 index 0000000000..624b22a2ea --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NoSideEffectMethodMarker.java @@ -0,0 +1,91 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.*; +import proguard.classfile.visitor.MemberVisitor; + +/** + * This MemberVisitor marks all methods that it visits as not having any side + * effects. It will make the SideEffectMethodMarker consider them as such + * without further analysis. + * + * @see SideEffectMethodMarker + * @author Eric Lafortune + */ +public class NoSideEffectMethodMarker +extends SimplifiedVisitor +implements MemberVisitor +{ + // A visitor info flag to indicate the visitor accepter is being kept, + // but that it doesn't have any side effects. + public static final Object KEPT_BUT_NO_SIDE_EFFECTS = new Object(); + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz Clazz, Member member) + { + // Ignore any attempts to mark fields. + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + markNoSideEffects(programMethod); + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + markNoSideEffects(libraryMethod); + } + + + // Small utility methods. + + private static void markNoSideEffects(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setNoSideEffects(); + } + else + { + MethodLinker.lastMember(method).setVisitorInfo(KEPT_BUT_NO_SIDE_EFFECTS); + } + } + + + public static boolean hasNoSideEffects(Method method) + { + if (MethodLinker.lastVisitorAccepter(method).getVisitorInfo() == KEPT_BUT_NO_SIDE_EFFECTS) + { + return true; + } + + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info != null && + info.hasNoSideEffects(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java new file mode 100644 index 0000000000..12124126ca --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonEmptyStackReturnMarker.java @@ -0,0 +1,115 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.attribute.visitor.StackSizeComputer; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This InstructionVisitor marks all methods that return with a non-empty stack + * (other than the return value). + * + * @author Eric Lafortune + */ +public class NonEmptyStackReturnMarker +extends SimplifiedVisitor +implements InstructionVisitor +{ + private final StackSizeComputer stackSizeComputer; + + + /** + * Creates a new NonEmptyStackReturnMarker + * @param stackSizeComputer the stack size computer that can return the + * stack sizes at the instructions that are + * visited. + */ + public NonEmptyStackReturnMarker(StackSizeComputer stackSizeComputer) + { + this.stackSizeComputer = stackSizeComputer; + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) + { + switch (simpleInstruction.opcode) + { + case InstructionConstants.OP_LRETURN: + case InstructionConstants.OP_DRETURN: + markReturnWithNonEmptyStack(method, offset, 2); + break; + + case InstructionConstants.OP_IRETURN: + case InstructionConstants.OP_FRETURN: + case InstructionConstants.OP_ARETURN: + markReturnWithNonEmptyStack(method, offset, 1); + break; + + case InstructionConstants.OP_RETURN: + markReturnWithNonEmptyStack(method, offset, 0); + break; + } + } + + + // Small utility methods. + + /** + * Marks the given method if the stack before the given instruction offset + * has a size larger than the given size. + */ + private void markReturnWithNonEmptyStack(Method method, + int offset, + int stackSize) + { + if (!stackSizeComputer.isReachable(offset) || + stackSizeComputer.getStackSizeBefore(offset) > stackSize) + { + setReturnsWithNonEmptyStack(method); + } + } + + + private static void setReturnsWithNonEmptyStack(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setReturnsWithNonEmptyStack(); + } + } + + + public static boolean returnsWithNonEmptyStack(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.returnsWithNonEmptyStack(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java new file mode 100644 index 0000000000..99056083fe --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/NonPrivateMemberMarker.java @@ -0,0 +1,171 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * This ClassVisitor marks all class members that can not be made private in the + * classes that it visits, and in the classes to which they refer. + * + * @author Eric Lafortune + */ +public class NonPrivateMemberMarker +extends SimplifiedVisitor +implements ClassVisitor, + ConstantVisitor, + MemberVisitor +{ + private final MethodImplementationFilter filteredMethodMarker = new MethodImplementationFilter(this); + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Mark all referenced class members in different classes. + programClass.constantPoolEntriesAccept(this); + + // Explicitly mark the <clinit> method. + programClass.methodAccept(ClassConstants.METHOD_NAME_CLINIT, + ClassConstants.METHOD_TYPE_CLINIT, + this); + + // Explicitly mark the parameterless <init> method. + programClass.methodAccept(ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT, + this); + + // Mark all methods that may have implementations. + programClass.methodsAccept(filteredMethodMarker); + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + // Go over all methods. + libraryClass.methodsAccept(this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + 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); + } + + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) + { + Clazz referencedClass = refConstant.referencedClass; + + // Is it referring 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 && + !referencedClass.equals(clazz) || + !refConstant.getClassName(clazz).equals(clazz.getName())) + { + // The referenced class member can never be made private. + refConstant.referencedMemberAccept(this); + } + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + markCanNotBeMadePrivate(programField); + } + + + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) + { + markCanNotBeMadePrivate(libraryField); + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + markCanNotBeMadePrivate(programMethod); + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + markCanNotBeMadePrivate(libraryMethod); + } + + + // Small utility methods. + + private static void markCanNotBeMadePrivate(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + if (info != null) + { + info.setCanNotBeMadePrivate(); + } + } + + + /** + * Returns whether the given field can be made private. + */ + public static boolean canBeMadePrivate(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + return info != null && + info.canBeMadePrivate(); + } + + + private static void markCanNotBeMadePrivate(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setCanNotBeMadePrivate(); + } + } + + + /** + * Returns whether the given method can be made private. + */ + public static boolean canBeMadePrivate(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info != null && + info.canBeMadePrivate(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java new file mode 100644 index 0000000000..6ac7b60c94 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java @@ -0,0 +1,85 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 package visible members. + * + * @author Eric Lafortune + */ +public class PackageVisibleMemberContainingClassMarker +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor +{ + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) + { + // Check the class itself. + if ((clazz.getAccessFlags() & ClassConstants.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) + { + if ((member.getAccessFlags() & + (ClassConstants.ACC_PRIVATE | + ClassConstants.ACC_PUBLIC)) == 0) + { + setPackageVisibleMembers(clazz); + } + } + + + // Small utility methods. + + private static void setPackageVisibleMembers(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setContainsPackageVisibleMembers(); + } + } + + + public static boolean containsPackageVisibleMembers(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.containsPackageVisibleMembers(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java new file mode 100644 index 0000000000..86ba808591 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java @@ -0,0 +1,129 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * This ConstantVisitor marks all classes that refer to package visible classes + * or class members. + * + * @author Eric Lafortune + */ +public class PackageVisibleMemberInvokingClassMarker +extends SimplifiedVisitor +implements ConstantVisitor, + ClassVisitor, + MemberVisitor +{ + 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() & + ClassConstants.ACC_PUBLIC) == 0) + { + setInvokesPackageVisibleMembers(referencingClass); + } + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz clazz, Member member) + { + if ((member.getAccessFlags() & + (ClassConstants.ACC_PUBLIC | + ClassConstants.ACC_PRIVATE)) == 0) + { + setInvokesPackageVisibleMembers(referencingClass); + } + } + + + // Small utility methods. + + private static void setInvokesPackageVisibleMembers(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setInvokesPackageVisibleMembers(); + } + } + + + public static boolean invokesPackageVisibleMembers(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info == null || info.invokesPackageVisibleMembers(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java new file mode 100644 index 0000000000..85e348cc42 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ParameterUsageMarker.java @@ -0,0 +1,285 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.MemberVisitor; +import proguard.evaluation.value.Value; +import proguard.optimize.evaluation.PartialEvaluator; + +/** + * This MemberVisitor counts the parameters and marks the used parameters + * of the methods that it visits. It also marks the 'this' parameters of + * methods that have hierarchies. + * + * @author Eric Lafortune + */ +public class ParameterUsageMarker +extends SimplifiedVisitor +implements MemberVisitor, + AttributeVisitor, + InstructionVisitor +{ + private static final boolean DEBUG = false; + + + private final boolean markThisParameter; + private final boolean markAllParameters; + private final PartialEvaluator partialEvaluator = new PartialEvaluator(); + + + /** + * Creates a new ParameterUsageMarker. + */ + public ParameterUsageMarker() + { + this(false, false); + } + + + /** + * Creates a new ParameterUsageMarker that optionally marks all parameters. + * @param markThisParameter specifies whether all 'this' parameters should + * be marked as being used. + * @param markAllParameters specifies whether all other parameters should + * be marked as being used. + */ + public ParameterUsageMarker(boolean markThisParameter, + boolean markAllParameters) + { + this.markThisParameter = markThisParameter; + this.markAllParameters = markAllParameters; + } + + + // Implementations for MemberVisitor. + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + int parameterSize = + ClassUtil.internalMethodParameterSize(programMethod.getDescriptor(programClass), + programMethod.getAccessFlags()); + + if (parameterSize > 0) + { + int accessFlags = programMethod.getAccessFlags(); + + // Must we mark the 'this' parameter? + if (markThisParameter && + (accessFlags & ClassConstants.ACC_STATIC) == 0) + { + // Mark the 'this' parameter. + markParameterUsed(programMethod, 0); + } + + // Must we mark all other parameters? + if (markAllParameters) + { + // Mark all parameters, without the 'this' parameter. + markUsedParameters(programMethod, + (accessFlags & ClassConstants.ACC_STATIC) != 0 ? + -1L : -2L); + } + + // Is it a native method? + if ((accessFlags & ClassConstants.ACC_NATIVE) != 0) + { + // Mark all parameters. + markUsedParameters(programMethod, -1L); + } + + // Is it an abstract method? + else if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0) + { + // Mark the 'this' parameter. + markParameterUsed(programMethod, 0); + } + + // Is it a non-native, concrete method? + else + { + // Is the method not static, but synchronized, or can it have + // other implementations, or is it a class instance initializer? + if ((accessFlags & ClassConstants.ACC_STATIC) == 0 && + ((accessFlags & ClassConstants.ACC_SYNCHRONIZED) != 0 || + programClass.mayHaveImplementations(programMethod) || + programMethod.getName(programClass).equals(ClassConstants.METHOD_NAME_INIT))) + { + // Mark the 'this' parameter. + markParameterUsed(programMethod, 0); + } + + // Mark the parameters that are used by the code. + programMethod.attributesAccept(programClass, this); + } + + if (DEBUG) + { + System.out.print("ParameterUsageMarker: ["+programClass.getName() +"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"]: "); + for (int index = 0; index < parameterSize; index++) + { + System.out.print(isParameterUsed(programMethod, index) ? '+' : '-'); + } + System.out.println(); + } + + } + + // Set the parameter size. + setParameterSize(programMethod, parameterSize); + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + // Can the method have other implementations? + if (libraryClass.mayHaveImplementations(libraryMethod)) + { + // All implementations must keep all parameters of this method, + // including the 'this' parameter. + markUsedParameters(libraryMethod, -1L); + } + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + // Evaluate the code. + partialEvaluator.visitCodeAttribute(clazz, method, codeAttribute); + + // Mark the parameters that are used by the code. + codeAttribute.instructionsAccept(clazz, method, this); + } + + + // 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 (partialEvaluator.isTraced(offset) && + variableInstruction.isLoad()) + { + int parameterIndex = variableInstruction.variableIndex; + if (parameterIndex < codeAttribute.u2maxLocals) + { + Value producer = + partialEvaluator.getVariablesBefore(offset).getProducerValue(parameterIndex); + if (producer != null && + producer.instructionOffsetValue().contains(PartialEvaluator.AT_METHOD_ENTRY)) + { + // Mark the variable. + markParameterUsed(method, parameterIndex); + + // Account for Category 2 instructions, which take up two entries. + if (variableInstruction.isCategory2()) + { + markParameterUsed(method, parameterIndex + 1); + } + } + } + } + } + + + // Small utility methods. + + /** + * Sets the total size of the parameters. + */ + private static void setParameterSize(Method method, int parameterSize) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setParameterSize(parameterSize); + } + } + + + /** + * Returns the total size of the parameters. + */ + public static int getParameterSize(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info != null ? info.getParameterSize() : 0; + } + + + /** + * Marks the given parameter as being used. + */ + public static void markParameterUsed(Method method, int variableIndex) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setParameterUsed(variableIndex); + } + } + + + /** + * Marks the given parameters as being used. + */ + public static void markUsedParameters(Method method, long usedParameters) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setUsedParameters(info.getUsedParameters() | usedParameters); + } + } + + + /** + * Returns whether the given parameter is being used. + */ + public static boolean isParameterUsed(Method method, int variableIndex) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || + info.isParameterUsed(variableIndex); + } + + + /** + * Returns which parameters are being used. + */ + public static long getUsedParameters(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info != null ? info.getUsedParameters() : -1L; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java new file mode 100644 index 0000000000..472309d3c1 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/ReadWriteFieldMarker.java @@ -0,0 +1,163 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.MemberVisitor; + +/** + * This InstructionVisitor marks all fields that are write-only. + * + * @author Eric Lafortune + */ +public class ReadWriteFieldMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + MemberVisitor +{ + // Parameters for the visitor methods. + private boolean reading = true; + private boolean writing = true; + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + byte opcode = constantInstruction.opcode; + + // Check for instructions that involve fields. + switch (opcode) + { + case InstructionConstants.OP_LDC: + case InstructionConstants.OP_LDC_W: + // Mark the field, if any, as being read from and written to. + reading = true; + writing = true; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + + case InstructionConstants.OP_GETSTATIC: + case InstructionConstants.OP_GETFIELD: + // Mark the field as being read from. + reading = true; + writing = false; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + + case InstructionConstants.OP_PUTSTATIC: + case InstructionConstants.OP_PUTFIELD: + // Mark the field as being written to. + reading = false; + writing = true; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + } + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + // Mark the referenced field, if any. + stringConstant.referencedMemberAccept(this); + } + + + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + { + // Mark the referenced field. + fieldrefConstant.referencedMemberAccept(this); + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz Clazz, Member member) {} + + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + // Mark the field if it is being read from. + if (reading) + { + markAsRead(programField); + } + + // Mark the field if it is being written to. + if (writing) + { + markAsWritten(programField); + } + } + + + // Small utility methods. + + private static void markAsRead(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + if (info != null) + { + info.setRead(); + } + } + + + public static boolean isRead(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + return info == null || + info.isRead(); + } + + + private static void markAsWritten(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + if (info != null) + { + info.setWritten(); + } + } + + + public static boolean isWritten(Field field) + { + FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field); + return info == null || + info.isWritten(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java new file mode 100644 index 0000000000..5374c4e0c4 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectInstructionChecker.java @@ -0,0 +1,375 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +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 outside of + * its method. Return instructions and local field accesses can be included or + * not. + * + * @see ReadWriteFieldMarker + * @see StaticInitializerContainingClassMarker + * @see NoSideEffectMethodMarker + * @see SideEffectMethodMarker + * @author Eric Lafortune + */ +public class SideEffectInstructionChecker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor, + MemberVisitor +{ + static final boolean OPTIMIZE_CONSERVATIVELY = System.getProperty("optimize.conservatively") != null; + + + private final boolean includeReturnInstructions; + private final boolean includeLocalFieldAccess; + + // A return value for the visitor methods. + private boolean writingField; + private Clazz referencingClass; + private boolean hasSideEffects; + + + /** + * Creates a new SideEffectInstructionChecker + * @param includeReturnInstructions specifies whether return instructions + * count as side effects. + * @param includeLocalFieldAccess specifies whether reading or writing + * local fields counts as side effects. + */ + public SideEffectInstructionChecker(boolean includeReturnInstructions, + boolean includeLocalFieldAccess) + { + this.includeReturnInstructions = includeReturnInstructions; + this.includeLocalFieldAccess = includeLocalFieldAccess; + } + + + /** + * Returns whether the given instruction has side effects outside of its + * method. + */ + public boolean hasSideEffects(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + hasSideEffects = false; + + instruction.accept(clazz, method, codeAttribute, offset, this); + + return hasSideEffects; + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) + { + byte opcode = simpleInstruction.opcode; + + // Check for instructions that might cause side effects. + switch (opcode) + { + 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_NEWARRAY: + case InstructionConstants.OP_ARRAYLENGTH: + case InstructionConstants.OP_ANEWARRAY: + case InstructionConstants.OP_MULTIANEWARRAY: + // These instructions strictly taken may cause a side effect + // (ArithmeticException, NullPointerException, + // ArrayIndexOutOfBoundsException, NegativeArraySizeException). + hasSideEffects = OPTIMIZE_CONSERVATIVELY; + break; + + 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_ATHROW : + case InstructionConstants.OP_MONITORENTER: + case InstructionConstants.OP_MONITOREXIT: + // These instructions always cause a side effect. + hasSideEffects = true; + break; + + case InstructionConstants.OP_IRETURN: + case InstructionConstants.OP_LRETURN: + case InstructionConstants.OP_FRETURN: + case InstructionConstants.OP_DRETURN: + case InstructionConstants.OP_ARETURN: + case InstructionConstants.OP_RETURN: + // These instructions may have a side effect. + hasSideEffects = includeReturnInstructions; + break; + } + } + + + public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) + { + byte opcode = variableInstruction.opcode; + + // Check for instructions that might cause side effects. + switch (opcode) + { + case InstructionConstants.OP_RET: + // This instruction may have a side effect. + hasSideEffects = includeReturnInstructions; + break; + } + } + + + 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. + switch (opcode) + { + case InstructionConstants.OP_GETSTATIC: + // Check if accessing the field might cause any side effects. + writingField = false; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + + case InstructionConstants.OP_PUTSTATIC: + // Check if accessing the field might cause any side effects. + writingField = true; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + + case InstructionConstants.OP_GETFIELD: + if (OPTIMIZE_CONSERVATIVELY) + { + // These instructions strictly taken may cause a side effect + // (NullPointerException). + hasSideEffects = true; + } + else + { + // Check if the field is write-only or volatile. + writingField = false; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + break; + + case InstructionConstants.OP_PUTFIELD: + if (OPTIMIZE_CONSERVATIVELY) + { + // These instructions strictly taken may cause a side effect + // (NullPointerException). + hasSideEffects = true; + } + else + { + // Check if the field is write-only or volatile. + writingField = true; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + break; + + case InstructionConstants.OP_INVOKESPECIAL: + case InstructionConstants.OP_INVOKESTATIC: + // Check if the invoked method is causing any side effects. + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + break; + + case InstructionConstants.OP_INVOKEVIRTUAL: + case InstructionConstants.OP_INVOKEINTERFACE: + case InstructionConstants.OP_INVOKEDYNAMIC: + if (OPTIMIZE_CONSERVATIVELY) + { + // These instructions strictly taken may cause a side effect + // (NullPointerException). + hasSideEffects = true; + } + else + { + // Check if the invoked method is causing any side effects. + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + break; + + case InstructionConstants.OP_ANEWARRAY: + case InstructionConstants.OP_CHECKCAST: + case InstructionConstants.OP_MULTIANEWARRAY: + // This instructions strictly taken may cause a side effect + // (ClassCastException, NegativeArraySizeException). + hasSideEffects = OPTIMIZE_CONSERVATIVELY; + break; + } + } + + + public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) + { + byte opcode = branchInstruction.opcode; + + // Check for instructions that might cause side effects. + switch (opcode) + { + case InstructionConstants.OP_JSR: + case InstructionConstants.OP_JSR_W: + hasSideEffects = includeReturnInstructions; + break; + } + } + + + // 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. + fieldrefConstant.referencedMemberAccept(this); + } + + + public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) + { + // Pass the referencing class. + referencingClass = clazz; + + // We'll have to assume invoking an unknown method has side effects. + hasSideEffects = true; + + // Check the referenced method, if known. + refConstant.referencedMemberAccept(this); + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + hasSideEffects = + (includeLocalFieldAccess || !programClass.equals(referencingClass)) && + ((writingField && ReadWriteFieldMarker.isRead(programField)) || + (programField.getAccessFlags() & ClassConstants.ACC_VOLATILE) != 0 || + mayHaveSideEffects(referencingClass, programClass)); + } + + + 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) || + mayHaveSideEffects(referencingClass, programClass)); + } + + + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) + { + hasSideEffects = true; + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + hasSideEffects = + !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod); + } + + + // Small utility methods. + + /** + * Returns whether a field reference or method invocation from the + * referencing class to the referenced class might have any side + * effects. + */ + private boolean mayHaveSideEffects(Clazz referencingClass, Clazz referencedClass) + { + return + !referencedClass.equals(referencingClass) && + !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(referencedClass)); + } + + + /** + * 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 NamedMethodVisitor(ClassConstants.METHOD_NAME_CLINIT, + ClassConstants.METHOD_TYPE_CLINIT, + new SideEffectMethodFilter( + new MemberToClassVisitor( + new ClassCollector(set)))))); + + return set; + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java new file mode 100644 index 0000000000..2e38245378 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodFilter.java @@ -0,0 +1,73 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.MemberVisitor; + +/** + * This MemberVisitor delegates all its method calls to another MemberVisitor, + * but only for Method objects that are marked as having side effects. + * + * @see SideEffectMethodMarker + * + * @author Eric Lafortune + */ +public class SideEffectMethodFilter +implements MemberVisitor +{ + private final MemberVisitor memberVisitor; + + + /** + * Creates a new SideEffectMethodFilter. + * @param memberVisitor the member visitor to which the visiting will be + * delegated. + */ + public SideEffectMethodFilter(MemberVisitor memberVisitor) + { + this.memberVisitor = memberVisitor; + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) {} + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) {} + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + if (SideEffectMethodMarker.hasSideEffects(programMethod)) + { + memberVisitor.visitProgramMethod(programClass, programMethod); + } + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + if (SideEffectMethodMarker.hasSideEffects(libraryMethod)) + { + memberVisitor.visitLibraryMethod(libraryClass, libraryMethod); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java new file mode 100644 index 0000000000..091f9e22c0 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SideEffectMethodMarker.java @@ -0,0 +1,181 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * This ClassPoolVisitor marks all methods that have side effects. + * + * @see ReadWriteFieldMarker + * @see NoSideEffectMethodMarker + * @author Eric Lafortune + */ +public class SideEffectMethodMarker +extends SimplifiedVisitor +implements ClassPoolVisitor, + ClassVisitor, + MemberVisitor, + AttributeVisitor +{ + // Reusable objects for checking whether instructions have side effects. + private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(false, true); + private final SideEffectInstructionChecker initializerSideEffectInstructionChecker = new SideEffectInstructionChecker(false, false); + + // Parameters and values for visitor methods. + private int newSideEffectCount; + private boolean hasSideEffects; + + + // Implementations for ClassPoolVisitor. + + public void visitClassPool(ClassPool classPool) + { + // Go over all classes and their methods, marking if they have side + // effects, until no new cases can be found. + do + { + newSideEffectCount = 0; + + // Go over all classes and their methods once. + classPool.classesAccept(this); + } + while (newSideEffectCount > 0); + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Go over all methods. + programClass.methodsAccept(this); + } + + + // Implementations for MemberVisitor. + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + if (!hasSideEffects(programMethod) && + !NoSideEffectMethodMarker.hasNoSideEffects(programMethod)) + { + // Initialize the return value. + hasSideEffects = + (programMethod.getAccessFlags() & + (ClassConstants.ACC_NATIVE | + ClassConstants.ACC_SYNCHRONIZED)) != 0; + + // Look further if the method hasn't been marked yet. + if (!hasSideEffects) + { + // Investigate the actual code. + programMethod.attributesAccept(programClass, this); + } + + // Mark the method depending on the return value. + if (hasSideEffects) + { + markSideEffects(programMethod); + + newSideEffectCount++; + } + } + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + // Remember whether the code has any side effects. + hasSideEffects = hasSideEffects(clazz, method, codeAttribute); + } + + + // Small utility methods. + + /** + * Returns whether the given code has any side effects. + */ + private boolean hasSideEffects(Clazz clazz, + Method method, + CodeAttribute codeAttribute) + { + byte[] code = codeAttribute.code; + int length = codeAttribute.u4codeLength; + + SideEffectInstructionChecker checker = + method.getName(clazz).equals(ClassConstants.METHOD_NAME_CLINIT) ? + initializerSideEffectInstructionChecker : + sideEffectInstructionChecker; + + // Go over all instructions. + int offset = 0; + do + { + // Get the current instruction. + Instruction instruction = InstructionFactory.create(code, offset); + + // Check if it may be throwing exceptions. + if (checker.hasSideEffects(clazz, + method, + codeAttribute, + offset, + instruction)) + { + return true; + } + + // Go to the next instruction. + offset += instruction.length(offset); + } + while (offset < length); + + return false; + } + + + private static void markSideEffects(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setSideEffects(); + } + } + + + public static boolean hasSideEffects(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || + info.hasSideEffects(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java new file mode 100644 index 0000000000..9d05a9f2e7 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumFilter.java @@ -0,0 +1,96 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 its visits to one of two other given + * ClassVisitor instances, depending on whether the classes are marked + * as simple enums or not. + * + * @see SimpleEnumMarker + * + * @author Eric Lafortune + */ +public class SimpleEnumFilter +implements ClassVisitor +{ + private final ClassVisitor simpleEnumClassVisitor; + private final ClassVisitor otherClassVisitor; + + + /** + * Creates a new SimpleEnumClassFilter. + * + * @param simpleEnumClassVisitor the class visitor to which visits to + * classes that are marked to be simpleEnum + * will be delegated. + */ + public SimpleEnumFilter(ClassVisitor simpleEnumClassVisitor) + { + this(simpleEnumClassVisitor, null); + } + + + /** + * Creates a new SimpleEnumClassFilter. + * + * @param simpleEnumClassVisitor the class visitor to which visits to + * classes that are marked as simple enums + * will be delegated. + * @param otherClassVisitor the class visitor to which visits to + * classes that are not marked as simple + * enums will be delegated. + */ + public SimpleEnumFilter(ClassVisitor simpleEnumClassVisitor, + ClassVisitor otherClassVisitor) + { + this.simpleEnumClassVisitor = simpleEnumClassVisitor; + this.otherClassVisitor = otherClassVisitor; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + // Is the class marked as a simple enum? + ClassVisitor classVisitor = SimpleEnumMarker.isSimpleEnum(programClass) ? + simpleEnumClassVisitor : otherClassVisitor; + + if (classVisitor != null) + { + classVisitor.visitProgramClass(programClass); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + // A library class can't be marked as a simple enum. + if (otherClassVisitor != null) + { + otherClassVisitor.visitLibraryClass(libraryClass); + } + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java new file mode 100644 index 0000000000..6877f37aeb --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SimpleEnumMarker.java @@ -0,0 +1,75 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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 marks all program classes that it visits with a given + * flag for simple enums. + * + * @author Eric Lafortune + */ +public class SimpleEnumMarker +implements ClassVisitor +{ + private final boolean simple; + + + /** + * Creates a new SimpleEnumMarker that marks visited classes with the + * given flag. + */ + public SimpleEnumMarker(boolean simple) + { + this.simple = simple; + } + + + // Implementations for ClassVisitor. + + public void visitLibraryClass(LibraryClass libraryClass) {} + + public void visitProgramClass(ProgramClass programClass) + { + setSimpleEnum(programClass); + } + + + // Small utility methods. + + private void setSimpleEnum(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + if (info != null) + { + info.setSimpleEnum(simple); + } + } + + + public static boolean isSimpleEnum(Clazz clazz) + { + ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz); + return info != null && info.isSimpleEnum(); + } +}
\ No newline at end of file diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java new file mode 100644 index 0000000000..0000b7d765 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java @@ -0,0 +1,62 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java new file mode 100644 index 0000000000..49fb5432d1 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java @@ -0,0 +1,65 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.ClassVisitor; + +/** + * 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.METHOD_NAME_CLINIT, + ClassConstants.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/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java new file mode 100644 index 0000000000..63e6225504 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/SuperInvocationMarker.java @@ -0,0 +1,93 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.CodeAttribute; +import proguard.classfile.constant.RefConstant; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This InstructionVisitor marks all methods that invoke super methods (other + * than initializers) from the instructions that it visits. + * + * @author Eric Lafortune + */ +public class SuperInvocationMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor +{ + private boolean invokesSuperMethods; + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_INVOKESPECIAL) + { + invokesSuperMethods = false; + + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + + if (invokesSuperMethods) + { + setInvokesSuperMethods(method); + } + } + } + + + // Implementations for ConstantVisitor. + + public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) + { + invokesSuperMethods = + !clazz.equals(refConstant.referencedClass) && + !refConstant.getName(clazz).equals(ClassConstants.METHOD_NAME_INIT); + } + + + // Small utility methods. + + private static void setInvokesSuperMethods(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + if (info != null) + { + info.setInvokesSuperMethods(); + } + } + + + public static boolean invokesSuperMethods(Method method) + { + MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method); + return info == null || info.invokesSuperMethods(); + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java new file mode 100644 index 0000000000..ba31ac4875 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/VariableUsageMarker.java @@ -0,0 +1,96 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare + * + * 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.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +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. + * + * @author Eric Lafortune + */ +public class VariableUsageMarker +extends SimplifiedVisitor +implements AttributeVisitor, + InstructionVisitor +{ + private boolean[] variableUsed = new boolean[ClassConstants.TYPICAL_VARIABLES_SIZE]; + + + /** + * Returns whether the given variable has been marked as being used. + */ + public boolean isVariableUsed(int variableIndex) + { + return variableUsed[variableIndex]; + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + int maxLocals = codeAttribute.u2maxLocals; + + // 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); + } + + codeAttribute.instructionsAccept(clazz, method, this); + } + + + // 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) + { + // Mark the variable. + variableUsed[variableInstruction.variableIndex] = true; + + // Account for Category 2 instructions, which take up two entries. + if (variableInstruction.isCategory2()) + { + variableUsed[variableInstruction.variableIndex + 1] = true; + } + } +} diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html new file mode 100644 index 0000000000..d16486e863 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/src/proguard/optimize/info/package.html @@ -0,0 +1,4 @@ +<body> +This package contains classes to collect additional information about classes +and class members, which can then be used for optimization. +</body> |