📄 partialevaluator.java
字号:
System.err.println(" Method = ["+methodInfo.getName(classFile)+methodInfo.getDescriptor(classFile)+"]"); System.err.println(" Instruction = "+instruction.toString(instructionOffset)); throw ex; } // Collect the offsets of the instructions whose results were used. InstructionOffsetValue variablesTraceValue = variables.getCollectedProducerValue().instructionOffsetValue(); InstructionOffsetValue stackTraceValue = stack.getCollectedProducerValue().instructionOffsetValue(); InstructionOffsetValue unusedTraceValue = unusedParameterCleaner.getTraceValue().instructionOffsetValue(); varProducerValues[instructionOffset] = varProducerValues[instructionOffset].generalize(variablesTraceValue).instructionOffsetValue(); stackProducerValues[instructionOffset] = stackProducerValues[instructionOffset].generalize(stackTraceValue).instructionOffsetValue(); unusedProducerValues[instructionOffset] = unusedProducerValues[instructionOffset].generalize(unusedTraceValue).instructionOffsetValue(); initializedVariables[instructionOffset] = variables.getInitializationIndex(); // Collect the branch targets from the branch unit. InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets(); int branchTargetCount = branchTargets.instructionOffsetCount(); // Stop tracing. variables.setCollectedProducerValue(traceValue); stack.setCollectedProducerValue(traceValue); branchUnit.setTraceBranchTargets(traceValue); if (DEBUG) { if (variablesTraceValue.instructionOffsetCount() > 0) { System.out.println(" has used information from instructions setting vars: "+variablesTraceValue); } if (stackTraceValue.instructionOffsetCount() > 0) { System.out.println(" has used information from instructions setting stack: "+stackTraceValue); } if (branchUnit.wasCalled()) { System.out.println(" is branching to "+branchTargets); } if (varProducerValues[instructionOffset].instructionOffsetCount() > 0) { System.out.println(" has up til now been using information from instructions setting vars: "+varProducerValues[instructionOffset]); } if (stackProducerValues[instructionOffset].instructionOffsetCount() > 0) { System.out.println(" has up till now been using information from instructions setting stack: "+stackProducerValues[instructionOffset]); } if (unusedProducerValues[instructionOffset].instructionOffsetCount() > 0) { System.out.println(" no longer needs information from instructions setting stack: "+unusedProducerValues[instructionOffset]); } if (branchTargetValues[instructionOffset] != null) { System.out.println(" has up till now been branching to "+branchTargetValues[instructionOffset]); } System.out.println(" Vars: "+variables); System.out.println(" Stack: "+stack); } // Maintain a generalized local variable frame and stack at this // branch instruction offset. if (vars[instructionOffset] == null) { // First time we're passing by this instruction. // There's not even a context at this index yet. vars[instructionOffset] = new TracedVariables(variables); stacks[instructionOffset] = new TracedStack(stack); } else if (evaluationCount == 0) { // First time we're passing by this instruction. // Reuse the context objects at this index. vars[instructionOffset].initialize(variables); stacks[instructionOffset].copy(stack); } else { // If there are multiple alternative branches, or if this // instruction has been evaluated an excessive number of // times, then generalize the current context. // TODO: See if we can avoid generalizing the current context. //if (branchTargetCount > 1 || // evaluationCount > MAXIMUM_EVALUATION_COUNT) //{ // variables.generalize(vars[instructionOffset]); // stack.generalize(stacks[instructionOffset]); //} boolean vars_changed = vars[instructionOffset].generalize(variables); boolean stack_changed = stacks[instructionOffset].generalize(stack); // Bail out if the current context is the same as last time. if (!vars_changed && !stack_changed && branchTargets.equals(branchTargetValues[instructionOffset])) { if (DEBUG) System.out.println("Repeated variables, stack, and branch targets"); break; } // Generalize the current context. Note that the most recent // variable values have to remain last in the generalizations, // for the sake of the ret instruction. variables.initialize(vars[instructionOffset]); stack.copy(stacks[instructionOffset]); } // Did the branch unit get called? if (branchUnit.wasCalled()) { // Accumulate the branch targets at this offset. branchTargetValues[instructionOffset] = branchTargetValues[instructionOffset] == null ? branchTargets : branchTargetValues[instructionOffset].generalize(branchTargets).instructionOffsetValue(); // Are there no branch targets at all? if (branchTargetCount == 0) { // Exit from this code block. break; } // Accumulate the branch origins at the branch target offsets. InstructionOffsetValue instructionOffsetValue = InstructionOffsetValueFactory.create(instructionOffset); for (int index = 0; index < branchTargetCount; index++) { int branchTarget = branchTargets.instructionOffset(index); branchOriginValues[branchTarget] = branchOriginValues[branchTarget] == null ? instructionOffsetValue: branchOriginValues[branchTarget].generalize(instructionOffsetValue).instructionOffsetValue(); } // Are there multiple branch targets? if (branchTargetCount > 1) { // Handle them recursively and exit from this code block. for (int index = 0; index < branchTargetCount; index++) { if (DEBUG) System.out.println("Alternative branch #"+index+" out of "+branchTargetCount+", from ["+instructionOffset+"] to ["+branchTargets.instructionOffset(index)+"]"); evaluateInstructionBlock(classFile, methodInfo, codeAttrInfo, new TracedVariables(variables), new TracedStack(stack), branchUnit, branchTargets.instructionOffset(index)); } break; } if (DEBUG) System.out.println("Definite branch from ["+instructionOffset+"] to ["+branchTargets.instructionOffset(0)+"]"); } // Just continue with the next instruction. instructionOffset = branchTargets.instructionOffset(0); } if (DEBUG) System.out.println("Ending processing of instruction block"); } // Small utility methods. /** * Initializes the data structures for the variables, stack, etc. */ private void initializeVariables(CodeAttrInfo codeAttrInfo, Variables parameters) { int codeLength = codeAttrInfo.u4codeLength; if (DEBUG) { System.out.println(" Max locals = "+codeAttrInfo.u2maxLocals); System.out.println(" Max stack = "+codeAttrInfo.u2maxStack); } // Create new arrays for storing information at each instruction offset. if (vars.length < codeLength) { varProducerValues = new InstructionOffsetValue[codeLength]; stackProducerValues = new InstructionOffsetValue[codeLength]; unusedProducerValues = new InstructionOffsetValue[codeLength]; branchOriginValues = new InstructionOffsetValue[codeLength]; branchTargetValues = new InstructionOffsetValue[codeLength]; vars = new TracedVariables[codeLength]; stacks = new TracedStack[codeLength]; evaluationCounts = new int[codeLength]; initializedVariables = new int[codeLength]; for (int index = 0; index < codeLength; index++) { initializedVariables[index] = NONE; } } else { for (int index = 0; index < codeLength; index++) { varProducerValues[index] = null; stackProducerValues[index] = null; unusedProducerValues[index] = null; branchOriginValues[index] = null; branchTargetValues[index] = null; evaluationCounts[index] = 0; initializedVariables[index] = NONE; if (vars[index] != null) { vars[index].reset(codeAttrInfo.u2maxLocals); } if (stacks[index] != null) { stacks[index].reset(codeAttrInfo.u2maxStack); } } } // Reuse the existing variables and stack objects, ensuring the right size. variables.reset(codeAttrInfo.u2maxLocals); stack.reset(codeAttrInfo.u2maxStack); // Initialize the variables with the parameters. variables.initialize(parameters); // Set the store value of each parameter variable. InstructionOffsetValue atMethodEntry = InstructionOffsetValueFactory.create(PartialEvaluator.AT_METHOD_ENTRY); for (int index = 0; index < parameters.size(); index++) { variables.setStoredTraceValue(index, atMethodEntry); } // Reset the return value. branchUnit.setTraceReturnValue(null); } /** * Generalize the local variable frames of a block of instructions. */ private void generalizeVariables(int startOffset, int endOffset, TracedVariables generalizedVariables) { for (int index = startOffset; index < endOffset; index++) { if (isTraced(index)) { // We can't use the return value, because local generalization // can be different a couple of times, with the global // generalization being the same. generalizedVariables.generalize(vars[index]); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -