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 + -
显示快捷键?