⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 methodinliner.java

📁 ProGuard 是一个免费的 Java类文件的压缩
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * ProGuard -- shrinking, optimization, obfuscation, and preverification *             of Java bytecode. * * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu) * * This library 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 library 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package proguard.optimize.peephole;import proguard.classfile.util.*;import proguard.classfile.attribute.visitor.*;import proguard.classfile.attribute.*;import proguard.classfile.instruction.visitor.InstructionVisitor;import proguard.classfile.instruction.*;import proguard.classfile.editor.*;import proguard.classfile.*;import proguard.classfile.visitor.*;import proguard.classfile.constant.visitor.ConstantVisitor;import proguard.classfile.constant.*;import proguard.optimize.info.*;/** * This AttributeVisitor inlines short methods in the code attributes that it * visits. * * @author Eric Lafortune */public class MethodInlinerextends      SimplifiedVisitorimplements   AttributeVisitor,             InstructionVisitor,             ExceptionInfoVisitor,             ConstantVisitor,             MemberVisitor{    private static final int MAXIMUM_INLINING_CODE_LENGTH  = 8;    private static final int MAXIMUM_CODE_EXPANSION        = 2;    private static final int MAXIMUM_EXTRA_CODE_LENGTH     = 128;    //*    private static final boolean DEBUG = false;    /*/    private static       boolean DEBUG = true;    //*/    private boolean            allowAccessModification;    private InstructionVisitor extraInlinedInvocationVisitor;    private CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();    private AccessMethodMarker    accessMethodMarker    = new AccessMethodMarker();    private CatchExceptionMarker  catchExceptionMarker  = new CatchExceptionMarker();    private ConstantAdder         constantAdder         = new ConstantAdder();    private StackSizeComputer     stackSizeComputer     = new StackSizeComputer();    private Clazz   targetClass;    private Method  targetMethod;    private boolean inlining;    private boolean emptyInvokingStack;    private int     uninitializedObjectCount;    private int     variableOffset;    private boolean inlined;    private boolean inlinedAny;    /**     * Creates a new MethodInliner.     * @param allowAccessModification indicates whether the access modifiers of     *                                classes and class members can be changed     *                                in order to inline methods.     */    public MethodInliner(boolean allowAccessModification)    {        this(allowAccessModification, null);    }    /**     * Creates a new MethodInliner.     * @param allowAccessModification indicates whether the access modifiers of     *                                classes and class members can be changed     *                                in order to inline methods.     * @param extraInlinedInvocationVisitor an optional extra visitor for all     *                                      inlined invocation instructions.     */    public MethodInliner(boolean            allowAccessModification,                         InstructionVisitor extraInlinedInvocationVisitor)    {        this.allowAccessModification       = allowAccessModification;        this.extraInlinedInvocationVisitor = extraInlinedInvocationVisitor;    }    // Implementations for AttributeVisitor.    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)    {        if (!inlining)        {//            codeAttributeComposer.DEBUG = DEBUG =//                clazz.getName().equals("abc/Def") &&//                method.getName(clazz).equals("abc");            targetClass              = clazz;            targetMethod             = method;            uninitializedObjectCount = method.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ? 1 : 0;            inlinedAny               = false;            codeAttributeComposer.reset();            constantAdder.setTargetClass((ProgramClass)clazz);            stackSizeComputer.visitCodeAttribute(clazz, method, codeAttribute);            // Append the body of the code.            copyCode(clazz, method, codeAttribute);            targetClass  = null;            targetMethod = null;            constantAdder.setTargetClass(null);            // Update the code attribute if any code has been inlined.            if (inlinedAny)            {                codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);                // Update the accessing flags.                codeAttribute.instructionsAccept(clazz, method, accessMethodMarker);                // Update the exception catching flags.                catchExceptionMarker.visitCodeAttribute(clazz, method, codeAttribute);            }        }        // Only inline the method if it is invoked once or if it is short.        // TODO: Check total code length after inlining.        else if (MethodInvocationMarker.getInvocationCount(method) == 1 ||                 codeAttribute.u4codeLength <= MAXIMUM_INLINING_CODE_LENGTH)        {            if (DEBUG)            {                System.out.println("MethodInliner: inlining ["+                                   clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] in ["+                                   targetClass.getName()+"."+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]");            }            // Append instructions to store the parameters.            storeParameters(clazz, method);            // Inline the body of the code.            copyCode(clazz, method, codeAttribute);            inlined    = true;            inlinedAny = true;        }    }    /**     * Appends instructions to pop the parameters for the given method, storing     * them in new local variables.     */    private void storeParameters(Clazz clazz, Method method)    {        String descriptor = method.getDescriptor(clazz);        boolean isStatic =            (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;        // Count the number of parameters, taking into account their categories.        int parameterCount  = ClassUtil.internalMethodParameterCount(descriptor);        int parameterSize   = ClassUtil.internalMethodParameterSize(descriptor);        int parameterOffset = isStatic ? 0 : 1;        // Store the parameter types.        String[] parameterTypes = new String[parameterSize];        InternalTypeEnumeration internalTypeEnumeration =            new InternalTypeEnumeration(descriptor);        for (int parameterIndex = 0; parameterIndex < parameterSize; parameterIndex++)        {            String parameterType = internalTypeEnumeration.nextType();            parameterTypes[parameterIndex] = parameterType;            if (ClassUtil.internalTypeSize(parameterType) == 2)            {                parameterIndex++;            }        }        codeAttributeComposer.beginCodeFragment((parameterOffset + parameterCount) * 4);        // Go over the parameter types backward, storing the stack entries        // in their corresponding variables.        for (int parameterIndex = parameterSize-1; parameterIndex >= 0; parameterIndex--)        {            String parameterType = parameterTypes[parameterIndex];            if (parameterType != null)            {                byte opcode;                switch (parameterType.charAt(0))                {                    case ClassConstants.INTERNAL_TYPE_BOOLEAN:                    case ClassConstants.INTERNAL_TYPE_BYTE:                    case ClassConstants.INTERNAL_TYPE_CHAR:                    case ClassConstants.INTERNAL_TYPE_SHORT:                    case ClassConstants.INTERNAL_TYPE_INT:                        opcode = InstructionConstants.OP_ISTORE;                        break;                    case ClassConstants.INTERNAL_TYPE_LONG:                        opcode = InstructionConstants.OP_LSTORE;                        break;                    case ClassConstants.INTERNAL_TYPE_FLOAT:                        opcode = InstructionConstants.OP_FSTORE;                        break;                    case ClassConstants.INTERNAL_TYPE_DOUBLE:                        opcode = InstructionConstants.OP_DSTORE;                        break;                    default:                        opcode = InstructionConstants.OP_ASTORE;                        break;                }                codeAttributeComposer.appendInstruction(parameterSize-parameterIndex-1,                                                        new VariableInstruction(opcode, variableOffset + parameterOffset + parameterIndex).shrink());            }        }        // Put the 'this' reference in variable 0 (plus offset).        if (!isStatic)        {            codeAttributeComposer.appendInstruction(parameterSize,                                                    new VariableInstruction(InstructionConstants.OP_ASTORE, variableOffset).shrink());        }        codeAttributeComposer.endCodeFragment();    }    /**     * Appends the code of the given code attribute.     */    private void copyCode(Clazz clazz, Method method, CodeAttribute codeAttribute)    {        // The code may expand, due to expanding constant and variable        // instructions.        codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength * MAXIMUM_CODE_EXPANSION +                                                MAXIMUM_EXTRA_CODE_LENGTH);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -