Skip to content

Commit

Permalink
Improve optimizations
Browse files Browse the repository at this point in the history
Includes the addition of 2 new field optimizations and 3 new method
optimizations
  • Loading branch information
mrjameshamilton authored and JorenHannes committed Mar 24, 2021
1 parent af272c2 commit 2ba28f1
Show file tree
Hide file tree
Showing 75 changed files with 4,050 additions and 971 deletions.
80 changes: 80 additions & 0 deletions base/src/proguard/classfile/ClassMemberPair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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.classfile;

import proguard.classfile.visitor.MemberVisitor;

import java.util.Objects;

/**
* Container class for a pair of class + member.
*
* @author James Hamilton
*/
public class ClassMemberPair
{
public final Clazz clazz;
public final Member member;


public ClassMemberPair(Clazz clazz, Member member)
{
this.clazz = clazz;
this.member = member;
}


public void accept(MemberVisitor memberVisitor)
{
this.member.accept(this.clazz, memberVisitor);
}


public String getName()
{
return this.member.getName(this.clazz);
}


@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassMemberPair that = (ClassMemberPair)o;
return Objects.equals(clazz, that.clazz) &&
Objects.equals(member, that.member);
}


@Override
public int hashCode()
{
return Objects.hash(clazz, member);
}


@Override
public String toString()
{
return clazz.getName() + "." + this.member.getName(this.clazz) + this.member.getDescriptor(this.clazz);
}
}
84 changes: 84 additions & 0 deletions base/src/proguard/classfile/visitor/InjectedClassFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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.classfile.visitor;

import proguard.classfile.*;
import proguard.util.ProcessingFlags;


/**
* This ClassVisitor delegates to one of two other visitors, depending on
* whether the visited class was injected or not.
*
* @author Johan Leys
*/
public class InjectedClassFilter
implements ClassVisitor
{
private final ClassVisitor injectedClassVisitor;
private final ClassVisitor otherClassVisitor;


public InjectedClassFilter(ClassVisitor injectedClassVisitor,
ClassVisitor otherClassVisitor)
{
this.injectedClassVisitor = injectedClassVisitor;
this.otherClassVisitor = otherClassVisitor;
}


// Implementations for ClassVisitor.

@Override
public void visitAnyClass(Clazz clazz)
{
throw new UnsupportedOperationException(this.getClass().getName() + " does not support " + clazz.getClass().getName());
}

@Override
public void visitProgramClass(ProgramClass programClass)
{
ClassVisitor delegate = delegateVisitor(programClass);
if (delegate != null)
{
delegate.visitProgramClass(programClass);
}
}


@Override
public void visitLibraryClass(LibraryClass libraryClass)
{
if (otherClassVisitor != null)
{
otherClassVisitor.visitLibraryClass(libraryClass);
}
}


// Small utility methods.

private ClassVisitor delegateVisitor(ProgramClass programClass)
{
return (programClass.processingFlags & ProcessingFlags.INJECTED) != 0 ?
injectedClassVisitor : otherClassVisitor;
}
}
86 changes: 86 additions & 0 deletions base/src/proguard/optimize/CalledMemberVisitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2021 Guardsquare NV
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.optimize;

import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.visitor.*;

/**
* This InstructionVisitor visits all members that can be executed because of an instruction.
* Explicitly (invoke instructions) or implicitly (class initialisation methods)
*/
public class CalledMemberVisitor
implements InstructionVisitor
{
private final MemberVisitor memberVisitor;
private final MemberToClassVisitor staticClassInitializer;


public CalledMemberVisitor(MemberVisitor memberVisitor)
{
this.memberVisitor = memberVisitor;
this.staticClassInitializer =
new MemberToClassVisitor(
new NamedMethodVisitor(ClassConstants.METHOD_NAME_CLINIT, null, 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)
{

switch (constantInstruction.opcode)
{
case Instruction.OP_INVOKEVIRTUAL:
case Instruction.OP_INVOKESPECIAL:
case Instruction.OP_INVOKESTATIC:
case Instruction.OP_INVOKEINTERFACE:
case Instruction.OP_INVOKEDYNAMIC:
clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
new ReferencedMemberVisitor(
new MultiMemberVisitor(memberVisitor,staticClassInitializer)));
break;

case Instruction.OP_GETSTATIC:
case Instruction.OP_PUTSTATIC:
clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
new ReferencedMemberVisitor(staticClassInitializer));
break;
}
}
}
14 changes: 7 additions & 7 deletions base/src/proguard/optimize/ChangedCodePrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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
Expand Down Expand Up @@ -54,6 +54,12 @@ public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute
}


public void visitSourceDebugExtensionAttribute(Clazz clazz, SourceDebugExtensionAttribute sourceDebugExtensionAttribute)
{
attributeVisitor.visitSourceDebugExtensionAttribute(clazz, sourceDebugExtensionAttribute);
}


public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
{
attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
Expand All @@ -72,12 +78,6 @@ public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAtt
}


public void visitSourceDebugExtensionAttribute(Clazz clazz, SourceDebugExtensionAttribute sourceDebugExtensionAttribute)
{
attributeVisitor.visitSourceDebugExtensionAttribute(clazz, sourceDebugExtensionAttribute);
}


public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
attributeVisitor.visitInnerClassesAttribute(clazz, innerClassesAttribute);
Expand Down
9 changes: 6 additions & 3 deletions base/src/proguard/optimize/DuplicateInitializerFixer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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
Expand All @@ -28,6 +28,7 @@
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.optimize.info.*;
import proguard.util.ProcessingFlags;

/**
* This MemberVisitor adds an additional parameter to the duplicate
Expand Down Expand Up @@ -90,7 +91,9 @@ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programM
if (!programMethod.equals(similarMethod))
{
// Should this initializer be preserved?
if (KeepMarker.isKept(programMethod))
if (KeepMarker.isKept(programMethod) ||
// PGD-18: preserve this initializer if the other one has been modified.
(similarMethod.getProcessingFlags() & ProcessingFlags.MODIFIED) != 0)
{
// Fix the other initializer.
// We'll just proceed if it is being kept as well;
Expand Down Expand Up @@ -149,7 +152,7 @@ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programM
int parameterCount =
ClassUtil.internalMethodParameterCount(newDescriptor,
programMethod.getAccessFlags());
programMethodOptimizationInfo.insertParameter(parameterCount - 1);
programMethodOptimizationInfo.insertParameter(parameterCount - 1, 1);

int parameterSize =
programMethodOptimizationInfo.getParameterSize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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
Expand Down Expand Up @@ -78,7 +78,6 @@ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}

public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{

// Reset the code changes.
codeAttributeEditor.reset(codeAttribute.u4codeLength);

Expand Down

0 comments on commit 2ba28f1

Please sign in to comment.