/** * Returns whether the stack specified entries before the given offset are * present. */ public boolean isStackEntriesPresentBefore(int instructionOffset, int stackIndex1, int stackIndex2) { boolean present1 = isStackEntryPresentBefore(instructionOffset, stackIndex1); boolean present2 = isStackEntryPresentBefore(instructionOffset, stackIndex2); //if (present1 ^ present2) //{ // throw new UnsupportedOperationException("Can't handle partial use of dup2 instructions"); //} return present1 || present2; }
/** * Returns whether the stack specified entries before the given offset are * present. */ public boolean isStackEntriesPresentBefore(int instructionOffset, int stackIndex1, int stackIndex2) { boolean present1 = isStackEntryPresentBefore(instructionOffset, stackIndex1); boolean present2 = isStackEntryPresentBefore(instructionOffset, stackIndex2); //if (present1 ^ present2) //{ // throw new UnsupportedOperationException("Can't handle partial use of dup2 instructions"); //} return present1 || present2; }
/** * Returns whether the stack specified entries before the given offset are * present. */ public boolean isStackEntriesPresentBefore(int instructionOffset, int stackIndex1, int stackIndex2) { boolean present1 = isStackEntryPresentBefore(instructionOffset, stackIndex1); boolean present2 = isStackEntryPresentBefore(instructionOffset, stackIndex2); //if (present1 ^ present2) //{ // throw new UnsupportedOperationException("Can't handle partial use of dup2 instructions"); //} return present1 || present2; }
private int fixedSwap(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved // or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? SWAP : // ...AB -> ...BA stackEntryPresent0 ? POP : // ...AB -> ...A NOP : // ...A -> ...A stackEntryPresent1 ? POP_X1 : // ...AB -> ...B NOP; // ...B -> ...B } }
private int fixedSwap(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved // or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? SWAP : // ...AB -> ...BA stackEntryPresent0 ? POP : // ...AB -> ...A NOP : // ...A -> ...A stackEntryPresent1 ? POP_X1 : // ...AB -> ...B NOP; // ...B -> ...B } }
private int fixedSwap(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved // or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? SWAP : // ...AB -> ...BA stackEntryPresent0 ? POP : // ...AB -> ...A NOP : // ...A -> ...A stackEntryPresent1 ? POP_X1 : // ...AB -> ...B NOP; // ...B -> ...B } }
private int fixedDup(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved, // copied, or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? DUP : // ...O -> ...OO NOP : // ...O -> ...O stackEntryNecessary1 ? NOP : // ...O -> ...O stackEntryPresent0 ? POP : // ...O -> ... NOP; // ... -> ... }
private int fixedDup(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved, // copied, or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? DUP : // ...O -> ...OO NOP : // ...O -> ...O stackEntryNecessary1 ? NOP : // ...O -> ...O stackEntryPresent0 ? POP : // ...O -> ... NOP; // ... -> ... }
private int fixedDup(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); // Figure out which stack entries should be moved, // copied, or removed. return stackEntryNecessary0 ? stackEntryNecessary1 ? DUP : // ...O -> ...OO NOP : // ...O -> ...O stackEntryNecessary1 ? NOP : // ...O -> ...O stackEntryPresent0 ? POP : // ...O -> ... NOP; // ... -> ... }
private int fixedDup_x1(int instructionOffset, int topBefore, int topAfter) boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1);
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { // We check all entries to make sure the stack is also consistent // at method exit points, where some stack entries might be // discarded. int stackSize = partialEvaluator.getStackBefore(offset).size(); for (int stackIndex = 0; stackIndex < stackSize; stackIndex++) { // Is this stack entry pushed by any producer // (because it is required by other consumers)? if (!isStackEntryUnwantedBefore(offset, stackIndex) && isStackEntryPresentBefore(offset, stackIndex)) { // Mark all produced stack entries. markStackEntryProducers(offset, stackIndex, false); } } } }
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { // We check all entries to make sure the stack is also consistent // at method exit points, where some stack entries might be // discarded. int stackSize = partialEvaluator.getStackBefore(offset).size(); for (int stackIndex = 0; stackIndex < stackSize; stackIndex++) { // Is this stack entry pushed by any producer // (because it is required by other consumers)? if (!isStackEntryUnwantedBefore(offset, stackIndex) && isStackEntryPresentBefore(offset, stackIndex)) { // Mark all produced stack entries. markStackEntryProducers(offset, stackIndex, false); } } } }
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { // We check all entries to make sure the stack is also consistent // at method exit points, where some stack entries might be // discarded. int stackSize = partialEvaluator.getStackBefore(offset).size(); for (int stackIndex = 0; stackIndex < stackSize; stackIndex++) { // Is this stack entry pushed by any producer // (because it is required by other consumers)? if (!isStackEntryUnwantedBefore(offset, stackIndex) && isStackEntryPresentBefore(offset, stackIndex)) { // Mark all produced stack entries. markStackEntryProducers(offset, stackIndex, false); } } } }
isStackEntryPresentBefore(offset, stackIndex))
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (branchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the branch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, branchInstruction.branchOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing branch instruction "+branchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, branchInstruction); } }
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (branchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the branch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, branchInstruction.branchOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing branch instruction "+branchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, branchInstruction); } }
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (switchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the switch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, switchInstruction.defaultOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing switch instruction "+switchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, switchInstruction); } }
public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (branchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the branch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, branchInstruction.branchOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing branch instruction "+branchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, branchInstruction); } }
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (switchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the switch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, switchInstruction.defaultOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing switch instruction "+switchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, switchInstruction); } }
public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction) { if (instructionUsageMarker.isInstructionNecessary(offset)) { if (switchInstruction.stackPopCount(clazz) > 0 && !instructionUsageMarker.isStackEntryPresentBefore(offset, instructionUsageMarker.getStackBefore(offset).size() - 1)) { // Replace the switch instruction by a simple goto. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO, switchInstruction.defaultOffset); codeAttributeEditor.replaceInstruction(offset, replacementInstruction); if (DEBUG) System.out.println(" Replacing switch instruction "+switchInstruction.toString(offset)+" by "+replacementInstruction.toString()); } } else { visitAnyInstruction(clazz, method, codeAttribute, offset, switchInstruction); } }