📄 evaluationsimplifier.java
字号:
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(); // Insert pop instructions where necessary, to keep the stack consistent. if (DEBUG_ANALYSIS) System.out.println("Stack consistency marking:"); offset = codeLength - 1; do { if (partialEvaluator.isTraced(offset) && !isDupOrSwap(codeAttrInfo.code[offset])) { // Make sure the stack is always consistent at this offset. fixStackConsistency(classFile, codeAttrInfo, offset); } offset--; } while (offset >= 0); if (DEBUG_ANALYSIS) System.out.println(); // Fix dup/swap instructions where necessary, to keep the stack consistent. if (DEBUG_ANALYSIS) System.out.println("Dup/swap marking and fixing:"); offset = codeLength - 1; do { if (partialEvaluator.isTraced(offset) && isDupOrSwap(codeAttrInfo.code[offset])) { // Make sure any dup/swap instructions are always consistent at this offset. fixDupInstruction(codeAttrInfo, offset); } 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 != PartialEvaluator.NONE && !isNecessary[offset] && isVariableReferenced(codeAttrInfo, variableIndex)) { if (DEBUG_ANALYSIS) System.out.println(offset +","); // Figure out what kind of initialization value has to be stored. int pushComputationalType = partialEvaluator.variableValue(offset, 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(codeAttrInfo.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); } InstructionOffsetValue unusedProducerOffsets = partialEvaluator.unusedProducerOffsets(offset); if (unusedProducerOffsets.instructionOffsetCount() > 0) { System.out.println(" no longer needs information from instructions setting stack: "+unusedProducerOffsets); } InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset); if (branchTargets != null) { System.out.println(" has overall been branching to "+branchTargets); } Instruction preInsertion = codeAttrInfoEditor.preInsertions[offset]; if (preInsertion != null) { System.out.println(" is preceded by: "+preInsertion); } Instruction replacement = codeAttrInfoEditor.replacements[offset]; if (replacement != null) { System.out.println(" is replaced by: "+replacement); } Instruction postInsertion = codeAttrInfoEditor.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(codeAttrInfo.code, offset); if (!isNecessary[offset]) { codeAttrInfoEditor.deleteInstruction(offset); codeAttrInfoEditor.insertBeforeInstruction(offset, null); codeAttrInfoEditor.replaceInstruction(offset, null); codeAttrInfoEditor.insertAfterInstruction(offset, null); // Visit the instruction, if required. if (extraDeletedInstructionVisitor != null) { instruction.accept(classFile, methodInfo, codeAttrInfo, offset, extraDeletedInstructionVisitor); } } offset += instruction.length(offset); } while (offset < codeLength); // Apply all accumulated changes to the code. codeAttrInfoEditor.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo); } /** * 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); if (DEBUG_ANALYSIS) System.out.print(","); return nextOffset; } /** * Marks the instructions at the given offsets. * @param producerOffsets the offsets of the producers to be marked. * @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(InstructionOffsetValue producerOffsets, int nextOffset) { if (producerOffsets != null) { int offsetCount = producerOffsets.instructionOffsetCount(); for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++) { // Has the other instruction been marked yet? int offset = producerOffsets.instructionOffset(offsetIndex); if (offset > PartialEvaluator.AT_METHOD_ENTRY && !isNecessary[offset]) { if (DEBUG_ANALYSIS) System.out.print("["+offset +"]"); // Mark it. isNecessary[offset] = true; // Restart at this instruction if it has a higher offset. if (nextOffset < offset) { if (DEBUG_ANALYSIS) System.out.print("!"); nextOffset = offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -