evaluationsimplifier.java

来自「proguard 一个java的混淆器」· Java 代码 · 共 1,560 行 · 第 1/5 页

JAVA
1,560
字号
                else if (highestDupOffset < 0)                {                    // Remember the offset of the last dup/swap instruction.                    highestDupOffset = offset;                }            }            offset--;        }        while (offset >= 0);        if (DEBUG_ANALYSIS) System.out.println();        // Insert dup instructions where necessary, to keep the stack consistent.        boolean updated;        do        {            if (DEBUG_ANALYSIS) System.out.println("Dup marking:");            // Repeat going over all instructions, as long as dup/swap            // instructions are updated.            updated = false;            offset = highestDupOffset;            while (offset >= 0)            {                if (partialEvaluator.isTraced(offset))                {                    Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                        offset);                    // Make sure any dup/swap instructions are always consistent                    // at this offset.                    if (isDupOrSwap(instruction))                    {                        updated |= fixDupInstruction(clazz,                                                     codeAttribute,                                                     offset,                                                     instruction);                    }                }                offset--;            }        }        while (updated);        if (DEBUG_ANALYSIS) System.out.println();        // Insert pop instructions after marked pushing instructions,        // if required to keep the stack consistent.        if (DEBUG_ANALYSIS) System.out.println("Marked push fixing:");        offset = codeLength - 1;        do        {            if (//partialEvaluator.isTraced(offset) &&                isNecessary[offset] &&                !isSimplified[offset])            {                Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                    offset);                // Make sure any non-dup/swap instructions are always consistent                // at this offset.                if (!isDupOrSwap(instruction))                {                    // Make sure any pushing instructions are always                    // consistent after this offset.                    fixPushInstruction(clazz,                                       codeAttribute,                                       offset,                                       instruction);                }            }            offset--;        }        while (offset >= 0);        if (DEBUG_ANALYSIS) System.out.println();        // Mark unmarked pop instructions after dup instructions,        // if required to keep the stack consistent.        // This is mainly required to fix "synchronized(C.class)" constructs        // as compiled by jikes and by the Eclipse compiler:        //    ...        //    dup        //    ifnonnull ...        //    pop        //    ...        if (DEBUG_ANALYSIS) System.out.println("Pop marking:");        offset = codeLength - 1;        do        {            if (//partialEvaluator.isTraced(offset) &&                isNecessary[offset]   &&                !isSimplified[offset] &&                !codeAttributeEditor.isModified(offset))            {                Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                    offset);                if (isDupOrSwap(instruction))                {                    markConsumingPopInstructions(clazz,                                                 codeAttribute,                                                 offset,                                                 instruction);                }            }            offset--;        }        while (offset >= 0);        if (DEBUG_ANALYSIS) System.out.println();        // Mark branches straddling just inserted push/pop instructions.        if (DEBUG_ANALYSIS) System.out.println("Final straddling branch marking:");        lowestNecessaryOffset = codeLength;        offset = codeLength - 1;        do        {            int nextOffset = offset - 1;            // Update the lowest index of all marked instructions higher up.            if (isNecessary[offset])            {                lowestNecessaryOffset = offset;            }            // Check if this instruction is a branch origin from a branch that            // straddles some marked code.            nextOffset = markAndSimplifyStraddlingBranches(offset,                                                           partialEvaluator.branchTargets(offset),                                                           lowestNecessaryOffset,                                                           nextOffset);            // Update the lowest index of all marked instructions higher up.            if (isNecessary[offset])            {                lowestNecessaryOffset = offset;            }            // Check if this instruction is a branch target from a branch that            // straddles some marked code.            nextOffset = markAndSimplifyStraddlingBranches(partialEvaluator.branchOrigins(offset),                                                           offset,                                                           lowestNecessaryOffset,                                                           nextOffset);            if (DEBUG_ANALYSIS)            {                if (nextOffset >= offset)                {                    System.out.println();                }            }            // Update the lowest index of all marked instructions higher up.            if (isNecessary[offset])            {                lowestNecessaryOffset = offset;            }            // Update the index of the instruction to be investigated next.            offset = nextOffset;        }        while (offset >= 0);        if (DEBUG_ANALYSIS) System.out.println();        // Mark variable initializations, even if they aren't strictly necessary.        // The virtual machine's verification step is not smart enough to see        // this, and may complain otherwise.        if (DEBUG_ANALYSIS) System.out.println("Initialization marking: ");        offset = 0;        do        {            // Is it an initialization that hasn't been marked yet, and whose            // corresponding variable is used for storage?            int variableIndex = partialEvaluator.initializedVariable(offset);            if (variableIndex >= 0 &&                !isNecessary[offset] &&                isVariableReferenced(codeAttribute, offset+1, variableIndex))            {                if (DEBUG_ANALYSIS) System.out.println(offset +",");                // Figure out what kind of initialization value has to be stored.                int pushComputationalType = partialEvaluator.getVariablesAfter(offset).getValue(variableIndex).computationalType();                increaseStackSize(offset, pushComputationalType, false);            }            offset++;        }        while (offset < codeLength);        if (DEBUG_ANALYSIS) System.out.println();        if (DEBUG_RESULTS)        {            System.out.println("Simplification results:");            offset = 0;            do            {                Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                    offset);                System.out.println((isNecessary[offset] ? " + " : " - ")+instruction.toString(offset));                if (partialEvaluator.isTraced(offset))                {                    InstructionOffsetValue varProducerOffsets = partialEvaluator.varProducerOffsets(offset);                    if (varProducerOffsets.instructionOffsetCount() > 0)                    {                        System.out.println("     has overall been using information from instructions setting vars: "+varProducerOffsets);                    }                    InstructionOffsetValue stackProducerOffsets = partialEvaluator.stackProducerOffsets(offset);                    if (stackProducerOffsets.instructionOffsetCount() > 0)                    {                        System.out.println("     has overall been using information from instructions setting stack: "+stackProducerOffsets);                    }                    int initializationOffset = partialEvaluator.initializationOffset(offset);                    if (initializationOffset != PartialEvaluator.NONE)                    {                        System.out.println("     is to be initialized at ["+initializationOffset+"]");                    }                    InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset);                    if (branchTargets != null)                    {                        System.out.println("     has overall been branching to "+branchTargets);                    }                    Instruction preInsertion = codeAttributeEditor.preInsertions[offset];                    if (preInsertion != null)                    {                        System.out.println("     is preceded by: "+preInsertion);                    }                    Instruction replacement = codeAttributeEditor.replacements[offset];                    if (replacement != null)                    {                        System.out.println("     is replaced by: "+replacement);                    }                    Instruction postInsertion = codeAttributeEditor.postInsertions[offset];                    if (postInsertion != null)                    {                        System.out.println("     is followed by: "+postInsertion);                    }                    //System.out.println("     Vars:  "+vars[offset]);                    //System.out.println("     Stack: "+stacks[offset]);                }                offset += instruction.length(offset);            }            while (offset < codeLength);        }        // Delete all instructions that are not used.        offset = 0;        do        {            Instruction instruction = InstructionFactory.create(codeAttribute.code,                                                                offset);            if (!isNecessary[offset])            {                codeAttributeEditor.deleteInstruction(offset);                codeAttributeEditor.insertBeforeInstruction(offset, null);                codeAttributeEditor.replaceInstruction(offset, null);                codeAttributeEditor.insertAfterInstruction(offset, null);                // Visit the instruction, if required.                if (extraDeletedInstructionVisitor != null)                {                    instruction.accept(clazz, method, codeAttribute, offset, extraDeletedInstructionVisitor);                }            }            offset += instruction.length(offset);        }        while (offset < codeLength);        // Apply all accumulated changes to the code.        codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);    }    /**     * Marks the producers at the given offsets.     * @param consumerOffset the offset of the consumer.     * @param nextOffset     the offset of the instruction to be investigated next.     * @return the updated offset of the instruction to be investigated next.     *         It is always greater than or equal the original offset, because     *         instructions are investigated starting at the highest index.     */    private int markProducers(int consumerOffset,                              int nextOffset)    {        if (DEBUG_ANALYSIS) System.out.print(consumerOffset);        // Mark all instructions whose variable values are used.        nextOffset = markProducers(partialEvaluator.varProducerOffsets(consumerOffset), nextOffset);        // Mark all instructions whose stack values are used.        nextOffset = markProducers(partialEvaluator.stackProducerOffsets(consumerOffset), nextOffset);

⌨️ 快捷键说明

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