1 21 package proguard.optimize.peephole; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.CodeAttribute; 25 import proguard.classfile.editor.CodeAttributeEditor; 26 import proguard.classfile.instruction.*; 27 import proguard.classfile.instruction.visitor.InstructionVisitor; 28 import proguard.classfile.util.SimplifiedVisitor; 29 30 35 public class LoadStoreRemover 36 extends SimplifiedVisitor 37 implements InstructionVisitor 38 { 39 private BranchTargetFinder branchTargetFinder; 40 private CodeAttributeEditor codeAttributeEditor; 41 private InstructionVisitor extraInstructionVisitor; 42 43 44 52 public LoadStoreRemover(BranchTargetFinder branchTargetFinder, 53 CodeAttributeEditor codeAttributeEditor) 54 { 55 this(branchTargetFinder, codeAttributeEditor, null); 56 } 57 58 59 69 public LoadStoreRemover(BranchTargetFinder branchTargetFinder, 70 CodeAttributeEditor codeAttributeEditor, 71 InstructionVisitor extraInstructionVisitor) 72 { 73 this.branchTargetFinder = branchTargetFinder; 74 this.codeAttributeEditor = codeAttributeEditor; 75 this.extraInstructionVisitor = extraInstructionVisitor; 76 } 77 78 79 81 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 82 83 84 public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) 85 { 86 if (variableInstruction.isLoad() && 88 variableInstruction.opcode != InstructionConstants.OP_RET) 89 { 90 int variableIndex = variableInstruction.variableIndex; 91 92 int nextOffset = offset + variableInstruction.length(offset); 93 94 if (!codeAttributeEditor.isModified(offset) && 95 !codeAttributeEditor.isModified(nextOffset) && 96 !branchTargetFinder.isTarget(nextOffset)) 97 { 98 Instruction nextInstruction = InstructionFactory.create(codeAttribute.code, 100 nextOffset); 101 102 if (nextInstruction instanceof VariableInstruction) 103 { 104 variableInstruction = (VariableInstruction)nextInstruction; 105 if (!variableInstruction.isLoad() && 106 variableInstruction.opcode != InstructionConstants.OP_IINC && 107 variableInstruction.variableIndex == variableIndex) 108 { 109 codeAttributeEditor.deleteInstruction(offset); 111 codeAttributeEditor.deleteInstruction(nextOffset); 112 113 if (extraInstructionVisitor != null) 115 { 116 extraInstructionVisitor.visitVariableInstruction(clazz, method, codeAttribute, offset, variableInstruction); 117 } 118 } 119 } 120 } 121 } 122 } 123 } 124 | Popular Tags |