📄 partialevaluator.java
字号:
} /** * Marks the instructions at the given offsets, if the current instruction * itself has been marked. * @param index the offset of the current instruction. * @param nextIndex the index of the instruction to be investigated next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal, because instructions are * investigated starting at the highest index. */ private int markDependencies(int index, int nextIndex) { if (isNecessary[index] && !codeAttrInfoEditor.isModified(index)) { if (DEBUG_ANALYSIS) System.out.print(index); // Mark all instructions whose variable values are used. nextIndex = markDependencies(varTraceValues[index], nextIndex); // Mark all instructions whose stack values are used. nextIndex = markDependencies(stackTraceValues[index], nextIndex); if (DEBUG_ANALYSIS) System.out.print(","); } return nextIndex; } /** * Marks the instructions at the given offsets. * @param traceOffsetValue the offsets of the instructions to be marked. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal, because instructions are * investigated starting at the highest index. */ private int markDependencies(InstructionOffsetValue traceOffsetValue, int nextIndex) { if (traceOffsetValue != null) { int traceOffsetCount = traceOffsetValue.instructionOffsetCount(); for (int traceOffsetIndex = 0; traceOffsetIndex < traceOffsetCount; traceOffsetIndex++) { // Has the other instruction been marked yet? int traceOffset = traceOffsetValue.instructionOffset(traceOffsetIndex); if (!isNecessary[traceOffset]) { if (DEBUG_ANALYSIS) System.out.print("["+traceOffset+"]"); // Mark it. isNecessary[traceOffset] = true; // Restart at this instruction if it has a higher offset. if (nextIndex < traceOffset) { if (DEBUG_ANALYSIS) System.out.print("!"); nextIndex = traceOffset; } } } } return nextIndex; } /** * Marks the branch instructions of straddling branches, if they straddle * some code that has been marked. * @param index the offset of the branch origin or branch target. * @param branchValue the offsets of the straddling branch targets * or branch origins. * @param isPointingToTargets <code>true</code> if the above offsets are * branch targets, <code>false</code> if they * are branch origins. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal the original index, because * instructions are investigated starting at the highest index. */ private int markStraddlingBranches(int index, InstructionOffsetValue branchValue, boolean isPointingToTargets, int lowestNecessaryIndex, int nextIndex) { if (branchValue != null) { // Loop over all branch origins. int branchCount = branchValue.instructionOffsetCount(); for (int branchIndex = 0; branchIndex < branchCount; branchIndex++) { // Is the branch straddling any necessary instructions? int branch = branchValue.instructionOffset(branchIndex); // Is the offset pointing to a branch origin or to a branch target? nextIndex = isPointingToTargets ? markStraddlingBranch(index, branch, lowestNecessaryIndex, nextIndex) : markStraddlingBranch(branch, index, lowestNecessaryIndex, nextIndex); } } return nextIndex; } /** * Marks the given branch instruction, if it straddles some code that has * been marked. * @param branchOrigin the branch origin. * @param branchTarget the branch target. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal the original index, because * instructions are investigated starting at the highest index. */ private int markStraddlingBranch(int branchOrigin, int branchTarget, int lowestNecessaryIndex, int nextIndex) { // Has the branch origin been marked yet, and is it straddling the // lowest necessary instruction? if (!isNecessary[branchOrigin] && isStraddlingBranch(branchOrigin, branchTarget, lowestNecessaryIndex)) { if (DEBUG_ANALYSIS) System.out.print("["+branchOrigin+"->"+branchTarget+"]"); // Mark the branch origin. isNecessary[branchOrigin] = true; // Restart at the branch origin if it has a higher offset. if (nextIndex < branchOrigin) { if (DEBUG_ANALYSIS) System.out.print("!"); nextIndex = branchOrigin; } } return nextIndex; } /** * Marks and simplifies the branch instructions of straddling branches, * if they straddle some code that has been marked. * @param branchOrigin the branch origin. * @param branchTargets the branch targets. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal the original index, because * instructions are investigated starting at the highest index. */ private int markAndSimplifyStraddlingBranches(int branchOrigin, InstructionOffsetValue branchTargets, int lowestNecessaryIndex, int nextIndex) { if (branchTargets != null && !isNecessary[branchOrigin]) { // Loop over all branch targets. int branchCount = branchTargets.instructionOffsetCount(); if (branchCount > 0) { for (int branchIndex = 0; branchIndex < branchCount; branchIndex++) { // Is the branch straddling any necessary instructions? int branchTarget = branchTargets.instructionOffset(branchIndex); if (!isStraddlingBranch(branchOrigin, branchTarget, lowestNecessaryIndex)) { return nextIndex; } } nextIndex = markAndSimplifyStraddlingBranch(branchOrigin, branchTargets.instructionOffset(0), lowestNecessaryIndex, nextIndex); } } return nextIndex; } /** * Marks and simplifies the branch instructions of straddling branches, * if they straddle some code that has been marked. * @param branchOrigins the branch origins. * @param branchTarget the branch target. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal the original index, because * instructions are investigated starting at the highest index. */ private int markAndSimplifyStraddlingBranches(InstructionOffsetValue branchOrigins, int branchTarget, int lowestNecessaryIndex, int nextIndex) { if (branchOrigins != null) { // Loop over all branch origins. int branchCount = branchOrigins.instructionOffsetCount(); for (int branchIndex = 0; branchIndex < branchCount; branchIndex++) { // Is the branch straddling any necessary instructions? int branchOrigin = branchOrigins.instructionOffset(branchIndex); nextIndex = markAndSimplifyStraddlingBranch(branchOrigin, branchTarget, lowestNecessaryIndex, nextIndex); } } return nextIndex; } /** * Marks and simplifies the given branch instruction, if it straddles some * code that has been marked. * @param branchOrigin the branch origin. * @param branchTarget the branch target. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. * @param nextIndex the index of the instruction to be investigated * next. * @return the updated index of the instruction to be investigated next. * It is always greater than or equal the original index, because * instructions are investigated starting at the highest index. */ private int markAndSimplifyStraddlingBranch(int branchOrigin, int branchTarget, int lowestNecessaryIndex, int nextIndex) { // Has the branch origin been marked yet, and is it straddling the // lowest necessary instruction? if (!isNecessary[branchOrigin] && isStraddlingBranch(branchOrigin, branchTarget, lowestNecessaryIndex)) { if (DEBUG_ANALYSIS) System.out.print("["+branchOrigin+"->"+branchTarget+"]"); // Mark the branch origin. isNecessary[branchOrigin] = true; // Replace the branch instruction by a simple branch instrucion. Instruction replacementInstruction = new BranchInstruction(InstructionConstants.OP_GOTO_W, branchTarget - branchOrigin).shrink(); codeAttrInfoEditor.replaceInstruction(branchOrigin, replacementInstruction); // Restart at the branch origin if it has a higher offset. if (nextIndex < branchOrigin) { if (DEBUG_ANALYSIS) System.out.print("!"); nextIndex = branchOrigin; } } return nextIndex; } /** * Returns whether the given branch straddling some code that has been marked. * @param branchOrigin the branch origin. * @param branchTarget the branch target. * @param lowestNecessaryIndex the lowest offset of all instructions marked * so far. */ private boolean isStraddlingBranch(int branchOrigin, int branchTarget,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -